【发布时间】:2014-07-13 22:10:23
【问题描述】:
我有一个用标准 C++11 编写的神经网络,我相信它正确地遵循了反向传播算法(基于 this)。但是,如果我在算法的每个步骤中输出错误,它似乎会随着时间的推移而波动而不会衰减。我已经尝试完全消除动量并选择一个非常小的学习率(0.02),但它仍然以每个网络大致相同的幅度振荡(每个网络在一定范围内具有不同的幅度)。
此外,所有输入都会产生相同的输出(我在here before 上发现了一个问题,尽管使用了不同的语言。作者还提到他从来没有让它工作过。)
代码可以在here找到。
总结一下我是如何实现网络的:
-
Neurons 保存它们前面的神经元的当前权重、之前对这些权重的更改以及所有输入的总和。 -
Neurons 可以访问它们的值(所有输入的总和),或者可以输出通过给定激活函数传递所述值的结果。 -
NeuronLayers 充当Neuron容器并设置到下一层的实际连接。 -
NeuronLayers 可以将实际输出发送到下一层(而不是从上一层拉取)。 -
FFNeuralNetworks 充当NeuronLayers 的容器并管理前向传播、错误计算和反向传播。他们还可以简单地处理输入。 -
FFNeuralNetwork的输入层将其加权值(值 * 权重)发送到下一层。之后每一层的每个神经元都会输出激活函数的加权结果,除非是偏置,或者该层是输出层(偏置输出加权值,输出层简单地将和通过激活函数)。
是我在实现中犯了一个根本性的错误(对理论的误解),还是我还没有发现一些简单的错误?如果它是一个错误,它可能在哪里?
为什么即使在非常低的学习率下,误差也会以它的幅度(大约 +-(0.2 +- 学习率))波动?为什么无论输入如何,所有输出都相同?
我已经讲了很多,以至于我可能会跳过一些东西,但我想我可能对理论有一个明显的误解。
【问题讨论】:
-
如果我正确理解您的代码,您可以使用预先确定的输入数据来训练您的神经网络。相同的数据和相同的计算应该产生相同的结果。但是每次运行它都会得到不同的结果。看起来有些随机性。可能是一些未初始化的数据?
-
@Christophe 它使用预定的输入数据和预期输出进行训练,输入(和匹配的输出)是从中随机选择的。初始权重是随机的,但除了这些示例之外,没有其他任何东西是随机的。你是对的,每次都有不同的结果,这就是我试图弄清楚的——反向传播应该让值收敛到给定点,但它们没有。然而,反向传播的过程根本不是随机的,因此我很困惑。
-
是的,我刚刚注意到。当我用 srand() 注释掉所有种子时,我得到一个恒定的输出。但是我想知道您使用时间的多次播种是否不会通过重置随机数来改变随机性的质量。特别是时间(0)通常以秒为单位。
-
@Christophe 此外,如果有有任何未初始化的数据,几乎肯定会涉及到分段错误,除了可能与每个神经元中保存的值有关。但是,
Neuron的默认构造函数会处理这个问题。我还会看到一些未初始化变量的编译器警告,但我没有看到。 -
我可以尝试移除较低层中的种子,而是使用全局(或至少每个网络)种子。让我看看是否有帮助。
标签: c++ c++11 neural-network backpropagation