学习率是神经网络中非常难以设置的超参数之一。
对于大规模的神经网络训练我们经常采用mini-batch Gradient Descent,但是在MBGD中如何选择合适的学习率是一个非常困难的问题。Learning Rate设置太小会导致神经网络收敛缓慢,Learning Rate设置太大可能导致神经网络在最小值附近波动甚至发散。
一种方案是在Trainning过程中动态调整Learning Rate。这种调整往往通过预先定义的策略进行调整或者当目标函数落在某个阈值中的时候进行调整,这些策略或者阈值是事先定义好的,不能自适应数据集自身的特征。
此外,数据的特征是不同的,用相同的Learning Rate调整所有的参数也部分场景下也是不合适的。比如我们的数据特征是非常稀疏的,我们可能更倾向于为很少出现的feature更大的学习率;
为了解决这些问题,研究者提出了很多梯度优化算法。
1.Momentum
普通的梯度下降(MBGD、SGD等)方法的缺点是:它的梯度更新方向完全依赖于当前Batch数据计算出的梯度,因此易变,不稳定。
如上图所示,蜿蜒曲折的河流流向低谷处,但是由于局部的高低起伏,河流并不是笔直的流向低谷,而是曲曲折折的流过去。梯度下降也有同样的问题,由于局部梯度的波动,导致梯度下降过程总是以震荡的形式靠近局部最优解。
Momentum算法借用了物理中的动量概念。它模拟的是物体运动时的惯性,即更新的时候在一定程度上保留之前更新的方向,同时利用当前batch数据计算的梯度微调最终的更新方向。这样一来,可以在一定程度上增加稳定性,从而学习地更快,并且还有一定摆脱局部最优的能力。Momentum通过引入
抑制震荡,加速SGD朝着相关的梯度方向迭代(如下图所示)
梯度更新规则
加入历史信息
之后,与物理学中动量的合成法则一样,如果当前梯度与历史梯度方向一致,则增强该维度上的梯度变化;如果当前梯度与历史梯度方向不一致,则当前梯度会衰减,从而达到加快收敛,减小震荡的目的。
γ的值通常取0.9。
TensorFlow中的实现
代码语言:javascript复制tf.train.MomentumOptimizer(learning_rate=learning_rate,momentum=0.9)
2.Nesterov Accelerated Gradient
Nesterov Accelerated Gradient方法是对Momentum梯度下降算法的改进版本,其速度更快。它的基本思想是既然每一步都需要引入历史梯度信息
来更新参数θ,那为什么不先按照历史梯度往前走一小步,按照前面一小步的位置的"超前梯度"来做梯度合并呢?
梯度更新规则
如下图所示,Momentum的方法首先计算当前的梯度(图中比较短的蓝色向量),然后沿着历史累计梯度方向向前迈出一大步(上图比较长的蓝色向量)。NAG的方法首先在历史累计的梯度方向上迈出一大步(棕色向量),然后在此基础上做一个校准(红色向量),两个向量累加得到最终的NAG梯度更新向量(绿色向量)。
TensorFlow中的实现
代码语言:javascript复制tf.train.MomentumOptimizer(learning_rate=learning_rate,momentum=0.9, use_nesterov=True)