神经网络算法与Python(四):梯度下降法

参考

一、Python神经网络编程
二、****博客与简书

梯度下降法

如何训练神经网络(即找到合适的权重)一直是神经网络的核心问题,从第一节可知,我们通常是通过误差来指导我们如何一步步改进神经网络。但是一个复杂的神经网络包含很多层,每一层包含很多参与中间运算的神经元,每一个神经元都可能会产生误差。

然后,我们只有神经网络最终输出的误差,即输出层每个神经元的误差。在上一节—误差与学习中,我们指出了可以采用误差反向扩散的方式,从输出层的误差按照传递链的权重将各个输出神经元的误差前馈到上一层神经元。以此类推,在一次训练中,我们可以获得神经网络中每一个神经元的误差。(在这个过程中矩阵可以帮我们减轻计算量)

得到了每个神经元的误差以后,我们关心的则变成了这些误差应该如何辅助我们更新神经网络各个传递链的权重。显然从第一节的分类器与预测器中,我们会采用一个很简单的思想即我们会观察误差随权重变化的方向,如下图所示:
神经网络算法与Python(四):梯度下降法
假设,上图中y代表的是误差值,x代表的某个神经元的某条输入链的权重。梯度下降法的思想源自于人们在山谷中寻找下山的路,当坡度变陡峭的时候,我们会大步往前迈(也就是增大改变权重的幅度),相反当坡度变得平缓时,意味着我们接近一块平地了,我们要减小步长避免错过。

这一方法指导了我们该如何根据误差的变化调整权重的变化,但是这种方法存在两个问题:
① 熟悉数学的人可能很容易发现,导数也就是斜率为零的点不一定是函数的最小值只能是函数的极小值。因此我们找到的误差最小点对应的权重实际上不一定就是真正的最优解。
② 假如我们单纯地通过斜率来调整步长的话,那么倘若函数出现十分特殊的情况,即间断点。可以想象成在某一点,误差值突然下降变为整个函数的最小值时,由于该点附近的斜率极大,因此我们的步长也会极大这样就可能会错过这个窄缝。

针对上面两个问题,我们可以通过改变起始值的方式解决(即起始权重),如下图所示不同的起始值对结果有很大影响。
神经网络算法与Python(四):梯度下降法
因此,我们在训练过程中可以尽可能多次改变起始权重并且横向比较找到的最小误差,从而确定真正的最小误差。

此外,在使用误差的时候,我们不得不注意误差的正负,因为在前馈误差的过程中,各个神经元的误差是有传递链求和得到的,倘若不注意正负符号直接求和的话那么正负误差会相消从而导致出现无误差的情况。因此,我们可以采取两种解决方案:
① 对误差求绝对值
② 求误差的平反
在这里我们倾向于第二种解决方案,因为平方可以使得误差函数更加平滑避免间跃的情况。