2013-12-23 56 views
4

我试图了解神经网络应用神经网络识别数字

我组成的输入数组作为

..# ### ### #.# 
.## ..# ..# #.# 
..# ### ### ### 
..# #.. ..# ..# 
..# ### ### ..#, etc 

期望ouptut我设置为位/ 10,即,位= 5输出= 0.5

代码

require 'ruby-fann' 

train = RubyFann::TrainData.new(
    inputs: [ 
    [0,0,1,0,1,1,0,0,1,0,0,1,0,0,1], 
    [1,1,1,0,0,1,1,1,1,1,0,0,1,1,1], 
    [1,1,1,0,0,1,1,1,1,0,0,1,1,1,1], 
    [1,0,1,1,0,1,1,1,1,0,0,1,0,0,1], 
    [1,1,1,1,0,0,1,1,1,0,0,1,1,1,1], 
    [1,1,1,1,0,0,1,1,1,1,0,1,1,1,1], 
    [1,1,1,0,0,1,0,1,0,1,0,0,1,0,0], 
    [1,1,1,1,0,1,1,1,1,1,0,1,1,1,1], 
    [1,1,1,1,0,1,1,1,1,0,0,1,1,1,1] 
    ], 
    desired_outputs: [[0.1],[0.2],[0.3], [0.4], [0.5], [0.6], [0.7], [0.8], [0.9]] 
) 
fann = RubyFann::Standard.new(
    num_inputs: 15, 
    hidden_neurons: [8,4,3,4,1], 
    num_outputs: 1 
) 
fann.train_on_data(train, 100000, 10, 0.1) # 100000 max_epochs, 100 errors between reports and 0.1 desired MSE (mean-squared-error) 
outputs = fann.run([0,0,1,0,1,1,0,0,1,0,0,1,0,0,1]) 
result = outputs.first 
abort result.inspect 

输出每个运行脚本

0.5367386954219215 
0.5141728468011051 
0.5249739971144654 
0.5373135467504666 
0.5182686028674102 
0.46710004502372293 
0.4723526462690119 
0.5306690734137796 
0.5151398228322749 
0.5359153267266001 
0.469100790593523 
0.4749347798092478 
0.5094355973839471 
0.5205985468860461 
0.5277528652471375 
0.4825827561254995 

我不明白为什么输出不等于0.1,这与第一个输入完全相同。

什么意思是0.46 - 0.53 diapason中的值?

UPDATE

我用0.1代替0和1用0.9

输出

0.4794515462681635 
0.5332274595769928 
0.4601992972516728 
0.427064909364266 
0.43466252163025687 
0.46931411920827737 
0.4455544021835517 
0.48051179013023565 
0.4798245565677274 
0.4479353078492235 
0.4646710791032779 
0.4887400910135108 

此外,我添加1输入为数字零,什么都没有发生显著

+0

什么'RubyFann'?这是一个标准的宝石? –

+1

是的,因为我理解它的C++快速人工神经网络库封装器 –

+0

也许你应该使用浮点数作为训练数据? –

回答

5

训练神经网是一种黑暗艺术。在这里,你最大的问题是设置一个0.1的RMS误差目标 - 这意味着你将接受比你感兴趣的差异更大的平均绝对误差。将它设置得更低应该有很大的帮助。

另外(但同样重要):

  • 你不需要这么多隐藏层。足够的神经元。从反复试验中,我认为你的[8,4,3,4,1]对于这个问题有点低(而最后的1没有任何用处)。值[30]似乎工作 - 我基本上通过尝试几个猜测得到这个。

  • 分类通常最好每个类别输出一个0/1输出,然后选择最大值。你不需要需要,虽然,我测试了你的0.1,0.2等目标,它的工作原理就是这样。解释为什么单独的输出更好:如果你的输入有一些噪声,并且网络理想地应该在3和8之间选择,那么使用单个输出的中间值可能是0.55 - 即使你四舍五入也不是很有用该值基本不正确。但是,对于用于分类的9个输出,“3”和“8”的输出都会很高,您可以选择稍高的一个,或者放心地显示正确的值是“3 “或”8“。

  • 您选择作为测试用例的问题可能会陷入局部最小值,您需要调整动量和学习率以获得更好的成功机会。

  • 改编培训数据也可能有所帮助。

下面的代码修改/ PARAMS应该给更接近于您想要的结果:

require 'ruby-fann' 

train = RubyFann::TrainData.new(
    inputs: [ 
    [0,0,1,0,1,1,0,0,1,0,0,1,0,0,1], [1,1,1,0,0,1,1,1,1,1,0,0,1,1,1], 
    [1,1,1,0,0,1,1,1,1,0,0,1,1,1,1], [1,0,1,1,0,1,1,1,1,0,0,1,0,0,1], 
    [1,1,1,1,0,0,1,1,1,0,0,1,1,1,1], [1,1,1,1,0,0,1,1,1,1,0,1,1,1,1], 
    [1,1,1,0,0,1,0,1,0,1,0,0,1,0,0], [1,1,1,1,0,1,1,1,1,1,0,1,1,1,1], 
    [1,1,1,1,0,1,1,1,1,0,0,1,1,1,1] 
    ], 
    desired_outputs: [ [1,0,0,0,0,0,0,0,0], [0,1,0,0,0,0,0,0,0], 
        [0,0,1,0,0,0,0,0,0], [0,0,0,1,0,0,0,0,0], 
        [0,0,0,0,1,0,0,0,0], [0,0,0,0,0,1,0,0,0], 
        [0,0,0,0,0,0,1,0,0], [0,0,0,0,0,0,0,1,0], 
        [0,0,0,0,0,0,0,0,1] ] 
) 

fann = RubyFann::Standard.new(
    num_inputs: 15, 
    hidden_neurons: [30], 
    num_outputs: 9 
) 

fann.learning_rate = 0.5 
fann.momentum = 0.5 

fann.train_on_data(train, 10000, 1000, 0.001) 

outputs = fann.run([0,0,1,0,1,1,0,0,1,0,0,1,0,0,1]) 
m = outputs.max 
puts "Result: #{(outputs.find_index { |x| x == m }) + 1}"