【问题标题】:Train neural network with sine function用正弦函数训练神经网络
【发布时间】:2016-06-11 05:19:28
【问题描述】:

我想用 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}"

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

那么,我做错了什么?

【问题讨论】:

  • 顺便说一句,我想到你希望Math::sin 使用度数 - 它没有,它以更大的单位弧度工作。如果您只想查看预测的单个正弦波,可以使用sinus = Math::sin(i.to_f/50) 或附近

标签: ruby neural-network artificial-intelligence


【解决方案1】:

Cerebrum 是一个非常基本且缓慢的 NN 实现。 Ruby 中有更好的选择,例如ruby-fann gem。

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

尝试类似:

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

并期望它需要很长时间才能训练,而且仍然不是很好。

此外,您对 300 个输出的选择范围太广 - 对于网络而言,它看起来更像是噪声,并且无法很好地在点之间进行插值。神经网络无法以某种方式找出“哦,那一定是正弦波”并与之匹配。取而代之的是,它在点之间进行插值——当它同时在多个维度上进行插值时,就会发生巧妙的一点,也许会找到手动检查无法轻易发现的结构。为了给它一个合理的学习机会,我建议你给它更密集的点,例如您目前拥有sinus = Math::sin(i) 的地方改为使用:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 2018-11-26
    • 2012-12-03
    • 2012-04-02
    • 2018-08-19
    • 2010-11-20
    • 2019-09-15
    相关资源
    最近更新 更多