2012-12-15 50 views
11

为了学习的目的,我实现了一个简单的神经网络框架,它只支持多层感知器和简单的反向传播。对于线性分类和通常的XOR问题,它的工作原理没问题,但对于正弦函数逼近,结果并不令人满意。用神经网络逼近正弦函数

我基本上试图用一个由6-10个神经元组成的隐藏层来逼近正弦函数的一个周期。网络使用双曲线切线作为隐藏层的激活函数和输出的线性函数。结果仍然是对正弦波的相当粗略的估计,需要很长的时间来计算。

我看着encog参考,但即使有,我不能把它简单的反向传播的工作(通过切换到弹性传播它开始变得更好,但仍比提供in this similar question超光滑[R脚本的方式更糟糕)。那么我是否真的想做一些不可能的事情?用简单的反向传播(无动量,没有动态学习速率)是否无法逼近正弦? R中神经网络库使用的实际方法是什么?

编辑:我知道这肯定是可能找到一个足够好的近似,即使简单的反向传播(如果你与你的初始权重非常幸运),但其实我更想知道这是否是一个可行的办法。与我的实现相比,我链接到的R脚本看起来似乎非常快速且稳健地收敛(在40个时期,只有很少的学习样本),甚至是encog的弹性传播。我只是想知道我是否可以做些什么来改进反向传播算法以获得相同的性能,还是需要研究一些更高级的学习方法?

+0

你有没有得到它的工作?面对同样的问题。 –

+0

不要这么想,但是因为这是4年前,所以不能真正回忆所有的细节。上面提到的nnet包是用C实现的,只有700行代码,然后一些R包装在它的上面。也许看看会给你一些想法。 – Muton

回答

1

你绝对不是在为不可能的事情而努力。神经网络是universal approximators - 这意味着对于任何函数F和误差E,存在可以与误差小于E.近似˚F一些神经网络(仅需要单个隐藏层)

当然,发现(那些)网络是完全不同的问题。我可以告诉你最好是试错......这里的基本步骤:

  1. 将数据分成两个部分:训练集(〜2/3)和测试组(〜三分之一)。
  2. 在训练集中的所有项目上训练您的网络。
  3. 在测试集中的所有项目上测试(但不要训练)您的网络并记录平均误差。
  4. 重复第2步和第3步,直到您达到最小测试错误(当网络开始超越训练数据而损害其他所有内容时发生“过度配合”),或者直到您的整体错误消失明显下降(意味着网络和它将要获得的一样好)。
  5. 如果在这一点上的错误是可接受的低,你就完成了。否则,你的网络不够复杂,无法处理你正在训练的功能;添加更多隐藏的神经元,并回到开始...

有时更改您的激活函数也可以有所作为(只是不要使用线性,因为它否定了添加更多图层的能力)。但是,再次看到什么效果最好,这将是试错。

希望有帮助(对不起,我不能更有用)!

PS:我也知道这是可能的,因为我已经看到有人近似与网络正弦。我想说她利用S形激活函数不是,但我不能保证我的记忆对个性化......

+0

谢谢!这实际上是我已经在做的事情,如果我有点不清楚,我很抱歉。我知道这是*可能*,但更多地试图找出我使用的简单学习方法对于这个特定问题是否可行? – Muton

+0

@Muton - Gotcha。在这种情况下,我唯一的提示是为当前的设置添加一个动量项。应该在两个方面提供帮助:它会加快学习的速度,并让你摆脱一些当地的最低限度。尽管如此,我无法想象它会带来巨大的性能差异。 –

3

这可以通过使用现代框架像TensorFlow神经网络可以比较容易地实现。

例如,使用每层火车100元在我的电脑上几秒钟,两层的神经网络提供了一个很好的近似:

enter image description here

代码也很简单:

import tensorflow as tf 
import numpy as np 

with tf.name_scope('placeholders'): 
    x = tf.placeholder('float', [None, 1]) 
    y = tf.placeholder('float', [None, 1]) 

with tf.name_scope('neural_network'): 
    x1 = tf.contrib.layers.fully_connected(x, 100) 
    x2 = tf.contrib.layers.fully_connected(x1, 100) 
    result = tf.contrib.layers.fully_connected(x2, 1, 
               activation_fn=None) 

    loss = tf.nn.l2_loss(result - y) 

with tf.name_scope('optimizer'): 
    train_op = tf.train.AdamOptimizer().minimize(loss) 

with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 

    # Train the network 
    for i in range(10000): 
     xpts = np.random.rand(100) * 10 
     ypts = np.sin(xpts) 

     _, loss_result = sess.run([train_op, loss], 
            feed_dict={x: xpts[:, None], 
              y: ypts[:, None]}) 

     print('iteration {}, loss={}'.format(i, loss_result)) 
+2

你的代码实际上实现了3层神经网络,而不是2层。命名方案包含隐藏层和输出层,因此您的三个图层分别为“x1”,“x2”和“结果”。 – stackoverflowuser2010