使用正弦函数训练神经网络

Train neural network with sine function

我想用 sine() 函数训练神经网络。

目前我使用此代码和 (cerebrum gem):

require 'cerebrum'

input = Array.new
300.times do |i|
  inputH = Hash.new
  inputH[:input]=[i]
  sinus = Math::sin(i)
  inputH[:output] = [sinus]
  input.push(inputH)

end

network = Cerebrum.new

network.train(input, {
  error_threshold: 0.00005,
  iterations:      40000,
  log:             true,
  log_period:      1000,
  learning_rate:   0.3
})


res = Array.new
300.times do |i|
  result = network.run([i])
  res.push(result[0])
end

puts "#{res}"

但它不起作用,如果我 运行 经过训练的网络我得到一些奇怪的输出值(而不是得到正弦曲线的一部分)。

所以,我做错了什么?

Cerebrum 是一个非常基础且缓慢的神经网络实现。 Ruby中有更好的选择,比如ruby-fann gem.

很可能你的问题是网络太简单了。您没有指定任何隐藏层 - 看起来代码为您的情况分配了一个默认的隐藏层,其中包含 3 个神经元。

试试这样的:

network = Cerebrum.new({
  learning_rate:  0.01,
  momentum:       0.9,
  hidden_layers:  [100]
})

并期望它需要永远训练,而且仍然不是很好。

此外,您对 300 个输出的选择范围太广 - 对于网络来说,它看起来很像噪声,并且不能很好地在点之间进行插值。神经网络不会以某种方式找出 "oh, that must be a sine wave" 并与之匹配。相反,它在点之间进行插值 - 当它同时在多个维度上这样做时,聪明的一点就会发生,也许会找到您无法通过手动检查轻易发现的结构。为了给它一个合理的学习机会,我建议你给它更密集的点,例如你目前有 sinus = Math::sin(i) 的地方使用:

sinus = Math::sin(i.to_f/10)

这仍然是正弦波的近 5 次迭代。这应该足以证明网络可以学习任意函数。