梯度下降算法针对凸优化问题原则上是可以收敛到全局最优的,因为此时只有唯一的局部最优点。而实际上深度学习模型是一个复杂的非线性结构,一般属于非凸问题,这意味着存在很多局部最优点(鞍点),采用梯度下降算法可能会陷入局部最优,这应该是最头疼的问题。这点和进化算法如遗传算法很类似,都无法保证收敛到全局最优。因此,我们注定在这个问题上成为“高级炼丹师”。可以看到,梯度下降算法中一个重要的参数是学习速率,适当的学习速率很重要:学习速率过小时收敛速度慢,而过大时导致训练震荡,而且可能会发散。理想的梯度下降算法要满足两点:收敛速度要快;能全局收敛。为了这个理想,出现了很多经典梯度下降算法的变种,下面将分别介绍它们。
梯度下降算法(Gradient Descent Optimization)是神经网络模型训练最常用的优化算法。梯度下降算法背后的原理:目标函数J(θ)关于参数θ的梯度将是目标函数上升最快的方向,对于最小化优化问题,只需要将参数沿着梯度相反的方向前进一个步长(学习速率),就可以实现目标函数的下降。参数更新公式如下:
其中是参数的梯度。
根据计算目标函数J(θ)采用数据量的大小,梯度下降算法又可以分为批量梯度下降算法(Batch Gradient Descent),随机梯度下降算法(Stochastic GradientDescent)和小批量梯度下降算法(Mini-batch Gradient Descent)。
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(loss)
SGD方法的一个缺点是,其更新方向完全依赖于当前的batch,因而其更新十分不稳定,每次迭代计算的梯度含有比较大的噪音。解决这一问题的一个简单的做法便是引入momentum,momentum即动量,是BorisPolyak在1964年提出的,其基于物体运动时的惯性:将一个小球从山顶滚下,其初始速率很慢,但在加速度作用下速率很快增加,并最终由于阻力的存在达到一个稳定速率,即更新的时候在一定程度上保留之前更新的方向,同时利用 当前batch的梯度 微调最终的更新方向。这样一来,可以在一定程度上增加稳定性,从而学习地更快,并且还有一定摆脱局部最优的能力。
其更新方程如下:
可以看到,参数更新时不仅考虑当前梯度值,而且加上了一个动量项γm,但多了一个超参γ,通常γ设置为0.5,直到初始学习稳定,然后增加到0.9或更高。相比原始梯度下降算法,动量梯度下降算法有助于加速收敛。当梯度与动量方向一致时,动量项会增加,而相反时,动量项减少,因此动量梯度下降算法可以减少训练的震荡过程。
tf.train.MomentumOptimizer(learning_rate=learning_rate,momentum=0.9)
NAG
NAG(Nesterov Accelerated Gradient),,由Ilya Sutskever(2012 unpublished)在Nesterov工作的启发下提出的。对动量梯度下降算法的改进版本,其速度更快。其变化之处在于计算“超前梯度”更新动量项 γm,具体公式如下:
既然参数要沿着动量项 γm更新,不妨计算未来位置(θ -γm)的梯度,然后合并两项作为最终的更新项,其具体效果如图1所示,可以看到一定的加速效果。
momentum基础上设置 use_nesterov=True
tf.train.MomentumOptimizer(learning_rate=learning_rate,momentum=0.9, use_nesterov=True)
AdaGrad是Duchi在2011年提出的一种学习速率自适应的梯度下降算法。在训练迭代过程,其学习速率是逐渐衰减的,经常更新的参数其学习速率衰减更快,这是一种自适应算法。其更新过程如下:
每步迭代过程:
其中,全局学习速率 ϵ, 初始参数 θ,梯度平方的累计量r初始化为0), δ(通常为10^−7)是为了防止分母的为 0。
由于梯度平方的累计量r逐渐增加的,那么学习速率是衰减的。考虑下图所示的情况,目标函数在两个方向的坡度不一样,如果是原始的梯度下降算法,在接近坡底时收敛速度比较慢。而当采用AdaGrad,这种情况可以被改善。由于比较陡的方向梯度比较大,其学习速率将衰减得更快,这有利于参数沿着更接近坡底的方向移动,从而加速收敛。对于每个参数,随着其更新的总距离增多,其学习速率也随之变慢。
缺点: 任然要设置一个变量ϵ ,经验表明,在普通算法中也许效果不错,但在深度学习中,深度过深时会造成训练提前结束。
tf.train.AdagradOptimizer(learning_rate=0.001).minimize(loss)
Adadelta是对Adagrad的扩展,最初方案依然是对学习率进行自适应约束,但是进行了计算上的简化。
Adagrad会累加之前所有的梯度平方,而Adadelta只累加固定大小的项,并且也不直接存储这些项,仅仅是近似计算对应的平均值。即:
其中,η是学习率,gt 是梯度
在此处Adadelta其实还是依赖于全局学习率的,但是作者做了一定处理,经过近似牛顿迭代法之后:
其中,E代表求期望。此时,可以看出Adadelta已经不用依赖于全局学习率了。
tf.train.AdadeltaOptimizer(learning_rate=0.001).minimize(loss)
RMSprop是对Adagrad算法的改进,主要是解决。其实思路很简单,类似Momentum思想,引入一个衰减系数,让梯度平方的累计量r 每回合都衰减一定比例:
其中,衰减系数ρ
decay: 衰减率
epsilon: 设置较小的值,防止分母的为 0.
tf.train.RMSPropOptimizer(learning_rate=0.001,momentum=0.9, decay=0.9, epsilon=1e-10)
优点:
- 相比于AdaGrad,这种方法有效减少了出现梯度爆炸情况,因此避免了学习速率过快衰减的问题。
- 适合处理非平稳目标,对于RNN效果很好
缺点:
- 又引入了新的超参—衰减系数ρ
- 依然依赖于全局学习速率,
总结:RMSprop算是Adagrad的一种发展,和Adadelta的变体,效果趋于二者之间。
自适应矩估计(daptive moment estimation,Adam),是Kingma等在2015年提出的一种新的优化算法,本质上是带有动量项的RMSprop,其结合了Momentum和RMSprop算法的思想。它利用梯度的一阶矩估计 和 二阶矩估计 动态调整每个参数的学习率。
具体实现每步迭代过程:
其中,一阶动量s,二阶动量r(初始化为0),一阶动量衰减系数ρ1, 二阶动量衰减系数ρ2
超参数的建议值是ρ1=0.9,ρ2 =0.999,epsilon: 设置较小的值,防止分母的为 0。
各种优化方法在CIFAR-10图像识别上比较:
图片来源:The Marginal Value of Adaptive Gradient Methods in Machine Learning
转:https://blog.csdn.net/u010899985/article/details/81836299