我正在使用神经网络试图根据您需要解决的问题来理解设计架构的最佳实践。
我生成了一个非常简单的数据集,由单个凸区域组成,如下所示:
当我使用L = 1或L = 2隐藏层(加上输出层)的架构时,一切正常,但只要我添加第三个隐藏层(L = 3),我的性能就会下降到略微好于机会。
我知道您添加到网络中的复杂性越多(要学习的权重和参数的数量),您越倾向于过度拟合数据,但我认为这不是我问题的本质,原因有两个:
任何人都可以帮助我理解为什么添加额外的隐藏层会给出 我在这么简单的任务中表现如何下降?
以下是我的表现形象与所用图层数量的函数关系:
根据评论添加部分:
L(s) = 1 / 1 + exp(-s)
答案 0 :(得分:11)
至少在表面上,这似乎是所谓的“消失梯度”问题。
激活功能
你的神经元根据logistic sigmoid函数激活,f(x)= 1 /(1 + e ^ -x):
此激活功能经常使用,因为它具有几个不错的属性。其中一个很好的特性是f(x)的导数可以使用函数本身的值进行计算表达,如f'(x)= f(x)(1 - f(x))。此函数对于x接近零具有非零值,但很快变为零,因为| x |变大:
渐变下降
在具有逻辑激活的前馈神经网络中,误差通常使用一阶导数作为学习信号向后传播通过网络。网络中权重的通常更新与可归因于权重的误差成正比,当前权重值乘以逻辑函数的导数。
delta_w(w) ~= w * f'(err(w)) * err(w)
作为三个可能非常小的值的乘积,如果网络中的权重落在逻辑函数的导数的“中间”区域之外,则这种网络中的一阶导数可以非常快速地变小。此外,这种快速消失的衍生物通过添加更多层而变得更加恶化,因为层中的错误被“分裂”并分区到层中的每个单元。反过来,这进一步减少了低于该层的层的梯度。
在具有超过两个隐藏层的网络中,这可能成为训练网络的一个严重问题,因为一阶梯度信息会让您相信权重无法有效地改变。
但是,有一些解决方案可以提供帮助!我能想到的涉及改变你的学习方法,使用比一阶梯度下降更复杂的东西,通常包含一些二阶导数信息。
<强>动量强>
使用某些二阶信息近似的最简单解决方案是在网络参数更新中包含动量项。而不是使用:
更新参数w_new = w_old - learning_rate * delta_w(w_old)
包含一个动量词:
w_dir_new = mu * w_dir_old - learning_rate * delta_w(w_old)
w_new = w_old + w_dir_new
直观地说,您希望使用来自过去衍生物的信息来帮助确定您是否要完全遵循新的衍生物(您可以通过设置mu = 0来实现),或者继续沿前一个方向前进更新,由新的渐变信息调整(通过设置mu> 0)。
使用“Nesterov's Accelerated Gradient”实际上可以比这更好:
w_dir_new = mu * w_dir_old - learning_rate * delta_w(w_old + mu * w_dir_old)
w_new = w_old + w_dir_new
我认为这里的想法是,不是计算“旧”参数值w
的衍生物,而是计算w
的“新”设置,如果你继续按照标准动量术语移动到那里。 Read more in a neural-networks context here (PDF)
<强>海森免费强>
将二阶梯度信息合并到神经网络训练算法中的教科书方法是使用牛顿法计算目标函数关于参数的第一个和二阶导数。然而,二阶导数,称为Hessian matrix,通常非常大,计算起来非常昂贵。
在过去的几年中,一些聪明的研究表明了一种在特定搜索方向上只计算Hessian值的方法,而不是计算整个Hessian。然后,您可以使用此过程来识别比第一阶梯度更好的参数更新。
您可以通过阅读research paper (PDF)或查看sample implementation来了解详情。
<强>其他强>
还有许多其他优化方法可用于此任务 - conjugate gradient (PDF -- definitely worth a read),Levenberg-Marquardt (PDF),L-BFGS - 但是从我在研究文献中看到的,动量和Hessian - 免费方法似乎是最常见的方法。
答案 1 :(得分:2)
因为随着您向神经网络添加复杂性,收敛所需的训练迭代次数会增加,所以在向神经网络添加图层时保持训练长度不变肯定会导致您最终观察到这样的下降。要弄清楚这是否是对此特定观察的解释,请尝试增加您正在使用的训练迭代次数,并查看它是否有所改善。使用更智能的停止标准也是一个不错的选择,但简单地增加截止值可以更快地给出答案。