2016-06-13 60 views
0

经过my previous attempt,我设法训练一个神经网络来表达正弦函数。我用ai4r红宝石:神经网络正弦函数

require 'ai4r' 
srand 1 
net = Ai4r::NeuralNetwork::Backpropagation.new([1, 60, 1]) 
net.learning_rate = 0.01 
#net.propagation_function = lambda { |x| 1.0/(1.0 + Math::exp(-x)) } 

def normalise(x, xmin, xmax, ymin, ymax) 
    xrange = xmax - xmin 
    yrange = ymax - ymin 
    return ymin + (x - xmin) * (yrange.to_f/xrange) 
end 

training_data = Array.new 
test = Array.new 
i2 = 0.0 
320.times do |i| 
    i2 += 0.1 
    hash = Hash.new 
    output = Math.sin(i2.to_f) 
    input = i2.to_f 
    hash.store(:input,[normalise(input,0.0,32.0,0.0,1.0)]) 
    hash.store(:expected_result,[normalise(output,-1.0,1.0,0.0,1.0)]) 
    training_data.push(hash) 
    test.push([normalise(output,-1.0,1.0,0.0,1.0)]) 
end 
puts "#{test}" 
puts "#{training_data}" 

time = Time.now 
999999.times do |i| 
    error = 0.0 
    training_data.each do |d| 
    error+=net.train(d[:input], d[:expected_result]) 
    end 
    if error < 0.26 
    break 
    end 
    print "Times: #{i}, error: #{error} \r" 
end 
time2 = Time.now 
puts "#{time2}-#{time} = #{time2-time} Sekunden gebraucht." 

serialized = Marshal.dump(net) 
File.open("net.saved", "w+") { |file| file.write(serialized) } 

一切工作正常。该网络训练了4703.664857秒。

sin function - neural network output

当我正常化0和1之间ai4r输入/输出到多个所述的网络将被更快地训练使用S形函数,所以很明显,它不输出负值。但为什么我必须规范化输入值?这种神经网络仅接受输入值< 1吗?

在正弦例子中,是有可能输入的任何数量的如:

Input: -10.0 -> Output: 0.5440211108893699 
Input: 87654.322 -> Output: -0.6782453567239783 
Input: -9878.923 -> Output: -0.9829544956991526 

或我必须限定的范围内。

回答

1

在您的结构中,您有一个输入后有60个隐藏节点。这意味着每个隐藏节点对于总共60个学习值只有1个学习权重。从隐藏层到单个输出节点的连接同样具有60个权重或学习值。这总共提供了120个可学习的维度。

图像隐藏层中的每个节点能够学习的内容:存在单个缩放因子,然后是非线性。让我们假设你的权重最终看起来像:

[1e-10, 1e-9, 1e-8, ..., .1]

每个条目是在隐藏层节点的权重。现在,如果你在1号传递到你的网络的隐藏层将输出的东西这样的效果:

[0, 0, 0, 0, ..., .1, .25, .5, .75, 1](粗略地讲,没有实际计算)

同样的,如果你给它的东西大,如:1E10然后第一层将给:

[0, .25, .5, .75, 1, 1, 1, ..., 1]

隐藏层的权重将要学会以这种方式分离,以便能够通过将它们缩放到更小范围来处理大范围的输入。您拥有的隐藏节点越多(在第一层),每个节点必须分开的距离越小。在我的例子中,它们间隔十倍。如果你有1000个,他们将被分开的因素可能是2.

通过规范化输入范围在[0,1]之间,你限制了这些隐藏节点在启动之前需要分离多远为最后一层提供有意义的信息。这样可以加快培训速度(假设您的停止条件是基于损失的变化)。

那么直接回答你的问题:不,你不需要正常化,但它肯定有助于降低输入空间的可变性和规模加快训练速度。

+0

“同样,如果你给它一些大的东西,比如:1e10,那么第一层就会给出:”为什么顺序(现在是从大到小的数字)会改变? –

+1

哎呀,它不会。我做了一些不好的数学:)它应该给出大量的1(或非常接近1的东西)的数组,这对于神经网络来说也是很难区分的。我编辑了我的帖子。 – Andnp