神经网络发散而非收敛

6
我使用CUDA实现了一个神经网络,有两层(每层有2个神经元)。我试图通过反向传播让它学习两个简单的二次多项式函数。但是它并没有收敛,反而发散(输出变成无穷大)。
以下是我尝试过的方法:
- 我将初始权重设置为0,但由于发散,我随机化了初始权重。 - 我阅读了一些资料,得知如果学习率过高,神经网络可能会发散,因此我将学习率降低到0.000001。 - 我尝试让其加上两个函数:3 * i + 7 * j+9 和 j*j + i*i + 24 (我将i和j作为输入层),但却没有成功。 - 以前我曾将其实现为单层网络,并能更好地逼近多项式函数。 - 我在考虑在这个网络中实现动量,但不确定是否能帮助它学习。 - 我使用线性(也就是没有)激活函数。 - 开始存在振荡现象,但是一旦任何一个权重大于1,输出便开始发散。
我检查了我的代码,但似乎没有任何问题。所以我的问题是:这里出了什么问题?非常感谢您的帮助。

我相信代码没有问题。而且我认为(backprop)算法已经足够详细地描述了,对于任何熟悉神经网络的人来说都是如此。我想知道的是还有什么其他可能出错了... 我正在删除cuda标签,以防误导任何人认为这是一个CUDA问题。 - Shayan RC
4
根据我的经验,当您的参数超出范围或某些函数返回无穷大时(例如,如果您使用逻辑损失函数,可能会出现对数函数返回无穷大的情况),就会发生这种情况。我建议首先检查数值问题,例如使用梯度检查器。但是这个问题太广泛了,我猜我们不能在这个问题上帮到你。 - Thomas Jungblut
输出不会突然变成无穷大,而是在一些初始振荡之后逐渐增加。只有当任何一个权重大于一时,它才开始发散。因此,这不是由于任何一个函数返回无穷大引起的。我已经添加了更多信息,希望能有所帮助。 - Shayan RC
神经网络发散而非收敛。 - badp
2个回答

4

神经网络代码发散的最常见原因是编码者忘记在权重变化表达式中加入负号。

另一个原因可能是计算梯度时使用的误差表达式存在问题。

如果这些都不成立,那么我们需要查看代码并作出回答。


4
  1. 如果你要解决的问题是分类类型的,尝试使用3层网络(根据科尔莫戈洛夫理论,3层足以)。从输入A和B到隐藏节点C的连接(C = A * wa + B * wb)表示AB空间中的一条线。该线将正确和错误的半空间分开。从隐藏层到输出的连接将隐藏层值相互关联,给出所需的输出。

  2. 根据你的数据,误差函数可能会呈现出类似梳子的形状,因此实现动量应该有所帮助。保持学习速率为1对我来说是最优的。

  3. 你的训练过程偶尔会陷入局部最小值,因此网络训练将由几个连续的会话组成。如果会话超过最大迭代次数或振幅过高,或者错误显然很高-则会话失败,请开始另一个会话。

  4. 在每个会话开始时,用随机(-0.5-+0.5)的值重新初始化权重。

  5. 制作错误下降图表确实有助于您更好地理解。你会有那种“啊哈!”的感觉。


3
你有Kolmogorov关于神经网络层数的规则的参考文献吗? - Luis
1
@Luis 我的印象是,随着深度学习的出现,三层架构已经过时了。 - chris
1
@ChrisAnderson 三层“东西”不是一个“东西”。它是对你想做什么、为什么以及使用哪些方法进行数学反思和分析。当然,你可以增加更多的层(或者很多节点),但这并不能保证你正在正确地解决问题。关于层数的问题仍然很有趣,特别是对于原始问题:我使用CUDA实现了一个具有2层的神经网络(每层2个神经元)。我正在尝试使用反向传播使其学习2个简单的二次多项式函数。 - Luis
哦,抱歉。我想我曾经看到有人 一般性地 推荐这样的东西,这让我感到沮丧。你说的很有道理(我没有注意到实际的问题文本)。 - chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接