我正在与Neural Networks一起玩,试图了解基于您需要解决的问题来设计其体系结构的最佳实践。
我生成了一个非常简单的数据集,该数据集由单个凸区域组成,如下所示:
当我使用具有L = 1或L = 2个隐藏层(加上输出层)的体系结构时,一切工作正常,但是一旦我添加了第三个隐藏层(L = 3),我的性能就会下降到比偶然情况稍好。
我知道您添加到网络中的复杂性越高(要学习的权重和参数的数量),您越倾向于过度拟合数据,但是我认为这不是我的问题的本质,原因有两个:
Can anybody help me understand why adding an extra hidden layer gives me this drop in performances on such a simple task?
这是我的性能随使用的层数而变化的图像:
由于评论已添加部分:
L(s) = 1 / 1 + exp(-s)
最佳答案
至少在其表面上,这似乎是所谓的“消失梯度”问题的一种情况。
激活功能
您的神经元根据逻辑S形函数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)
作为三个可能非常小的值的乘积,如果网络中的权重不在逻辑函数的导数的“中间”范围之外,则此类网络中的一阶导数会非常迅速地变小。此外,由于层中的错误会“ split ”并分配给层中的每个单元,因此添加更多层会加剧这种迅速消失的导数的恶化。反过来,这进一步降低了该层以下的层中的梯度。
在具有两个以上隐藏层的网络中,这可能成为训练网络的一个严重问题,因为一阶梯度信息将使您相信权重无法有效地变化。
但是,有一些解决方案可以帮助您!我能想到的就是改变学习方法,以使用比一阶梯度下降更为复杂的方法,通常会结合一些二阶导数信息。
动量
使用一些二阶信息近似的最简单解决方案是在网络参数更新中包括动量项。而不是使用更新参数:
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的加速渐变”,您实际上甚至可以得到比这更好的效果:
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
的"new"设置,就可以对其进行计算。 Read more in a neural-networks context here (PDF)。粗麻布免费
教科书中将二阶梯度信息合并到神经网络训练算法中的方法是使用牛顿法来计算目标函数相对于参数的一阶和二阶导数。但是,称为Hessian matrix的二阶导数通常非常大且计算成本过高。
在过去的几年中,一些聪明的研究没有计算整个黑森州的值(value),而是提出了一种仅计算特定搜索方向上的黑森州的值(value)的方法。然后,您可以使用此过程来确定比一阶梯度更好的参数更新。
您可以通过阅读research paper (PDF)或查看sample implementation来了解有关此内容的更多信息。
其他
还有许多其他优化方法可用于此任务,包括conjugate gradient (PDF -- definitely worth a read),Levenberg-Marquardt (PDF),L-BFGS,但根据我在研究文献中所看到的,动量法和无Hessian法似乎是最常见的方法。
关于artificial-intelligence - 神经网络架构设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20009078/