梯度下降及其优化算法综述

优化神经网络的模型参数时,梯度下降(Gradient Descent)是最常采用的方法之一,本文旨在让读者对梯度下降及其优化版本的算法有直观的认识。首先介绍梯度下降的三种变体(BGD,SGD,MBGD),总结三者在训练的过程中所面临的挑战,进而介绍常用的改进算法,包括这些算法在解决以上挑战时的动机以及导形式。

梯度下降(GD)

梯度下降算法(Gradient Descent Optimization)是神经网络模型训练最常用的优化算法。对于深度学习模型,基本都是采用梯度下降算法来进行优化训练的。梯度下降算法背后的原理:目标函数J(θ)关于参数θ的梯度将是目标函数上升最快的方向。对于最小化优化问题,只需要将参数沿着梯度相反的方向前进一个步长,就可以实现目标函数的下降。这个步长又称为学习速率η。参数更新公式如下:


根据计算梯度项采用数据量的不同,梯度下降算法又可以分为批量梯度下降算法(Batch Gradient Descent),随机梯度下降算法(Stochastic GradientDescent)和小批量梯度下降算法(Mini-batch Gradient Descent),相关源码可以参考

 批量梯度下降(BGD)随机梯度下降(SGD)小批量梯度下降(MBGD)
单次样本量所有样本单个样本"batch_size"个样本
公式
优点

    1.所有样本,可利用矩阵,实现并行

     2.迭代方向更好的代表样本总量

                      更新速度快

                     可并行化

           速度相对没有慢很多

缺点训练耗时大

1.准确性下降,强凸也无法线性收敛

2.不利于并行实现

batcha_size选择不能盲目过大

1.会导致内存容量不够,

2.样本下降方向基本不变,无用功

梯度下降存在以下问题

1.不能保证全局收敛(全局最优),梯度下降算法针对凸优化问题原则上是可以收敛到全局最优的,因为此时只有唯一的局部最优点。而实际上深度学习模型是一个复杂的非线性结构,一般属于非凸问题,这意味着存在很多局部最优点(鞍点),采用梯度下降算法可能会陷入局部最优。

2.适当的学习速率选择困难,学习速率过小时收敛速度慢,而过大时导致训练震荡,而且可能会发散,目前可采用的方法是在训练过程中调整学习率大小。

3. learning rate 对于每个参数都相同,这种做法是不合理的:如果训练数据是稀疏的,并且不同特征的出现频率差异较大,那么比较合理的做法是对于出现频率低的特征设置较大的学习速率,对于出现频率较大的特征数据设置较小的学习速率。


梯度下降优化算法

下面,我们将列举一些梯度下降的优化算法,这些算法被广泛用来处理前面提到的挑战。我们不会讨论在实际中不适合在高维数据集中计算的算法,例如诸如牛顿法的二阶方法。

动量(Momentum)

SGD方法的一个缺点是其更新方向完全依赖于当前batch计算出的梯度,因而很难通过陡谷,即在一个维度上的表面弯曲程度远大于其他维度的区域(局部最优点附近),SGD依然缓慢更新收敛,Momentum算法借用了物理中的动量概念,它模拟的是物体运动时的惯性,即更新的时候在一定程度上保留之前更新的方向,同时利用当前batch的梯度微调最终的更新方向。这样一来,可以在一定程度上增加稳定性,从而学习地更快,并且还有一定摆脱局部最优的能力,更新公式如下:

从本质上说,动量法,就像我们从山上推下一个球,球在滚下来的过程中累积动量,变得越来越快(直到达到终极速度,如果有空气阻力的存在,则γ<1γ<1)。同样的事情也发生在参数的更新过程中:对于在梯度点处具有相同的方向的维度,其动量项增大,对于在梯度点处改变方向的维度,其动量项减小。因此,我们可以得到更快的收敛速度,同时可以减少摇摆。

Nesterov Momentum

在梯度下降时,我们希望可以预知那些地方的坡面会上升,这样在遇到上升坡面之前,降低更新速率,这方法就是Nesterov Momentum,能够给动量项这样的预知能力,其在凸优化中有较强的理论保证收敛。并且,在实践中Nesterov Momentum也比单纯的 Momentum 的效果好,更新公式如下:

其核心思想是:注意到 momentum 方法,如果只看 γ * v 项,那么当前的 θ经过 momentum 的作用会变成 θ-γ * v。因此可以把 θ-γ * v这个位置看做是当前优化的一个”展望”位置。所以,可以在 θ-γ * v求导, 而不是原始的θ。

Adagrad

上述方法中,对于每一个参数θi 的训练都使用了相同的学习率α。Adagrad算法能够在训练中自动的对learning rate进行调整,对于出现频率较低参数采用较大的α更新;相反,对于出现频率较高的参数采用较小的α更新。因此,Adagrad非常适合处理稀疏数据。我们设gt,i 为第t轮第i个参数的梯度,即gt,i=▽ΘJ(Θi) 。因此,SGD中参数更新的过程可写为:


​  

其中,Gt∈ℝd×d是一个对角矩阵,对角线上的元素i,i是直到t时刻为止,所有关于θi的梯度的平方和(Duchi等人[7]将该矩阵作为包含所有先前梯度的外积的完整矩阵的替代,因为即使是对于中等数量的参数d,矩阵的均方根的计算都是不切实际的。),ϵ是平滑项,用于防止除数为0(通常大约设置为1e−8)。比较有意思的是,如果没有平方根的操作,算法的效果会变得很差。

Adagrad算法的一个主要优点是无需手动调整学习率。在大多数的应用场景中,通常采用常数0.01。Adagrad的一个主要缺点是它在分母中累加梯度的平方:由于没增加一个正项,在整个训练过程中,累加的和会持续增长。这会导致学习率变小以至于最终变得无限小,在学习率无限小时,Adagrad算法将无法取得额外的信息。接下来的算法旨在解决这个不足。

Adadelta

Adadelta[21]是Adagrad的一种扩展算法,以处理Adagrad学习速率单调递减的问题。不是计算所有的梯度平方,Adadelta将计算计算历史梯度的窗口大小限制为一个固定值ww。

在Adadelta中,无需存储先前的ww个平方梯度,而是将梯度的平方递归地表示成所有历史梯度平方的均值。在tt时刻的均值E[g2]tE[g2]t只取决于先前的均值和当前的梯度(分量γγ类似于动量项):

 

E[g2]t=γE[g2]t−1+(1−γ)g2tE[g2]t=γE[g2]t−1+(1−γ)gt2

 

我们将γγ设置成与动量项相似的值,即0.90.9左右。为了简单起见,我们利用参数更新向量ΔθtΔθt重新表示SGD的更新过程:

 

Δθt=−η⋅gt,iΔθt=−η⋅gt,i

 

 

θt+1=θt+Δθtθt+1=θt+Δθt

 

我们先前得到的Adagrad参数更新向量变为:

 

Δθt=−ηGt+ϵ‾‾‾‾‾‾√⊙gtΔθt=−ηGt+ϵ⊙gt

 

现在,我们简单将对角矩阵GtGt替换成历史梯度的均值E[g2]tE[g2]t:

 

Δθt=−ηE[g2]t+ϵ‾‾‾‾‾‾‾‾‾‾√gtΔθt=−ηE[g2]t+ϵgt

 

由于分母仅仅是梯度的均方根(root mean squared,RMS)误差,我们可以简写为:

 

Δθt=−ηRMS[g]tgtΔθt=−ηRMS[g]tgt

 

作者指出上述更新公式中的每个部分(与SGD,动量法或者Adagrad)并不一致,即更新规则中必须与参数具有相同的假设单位。为了实现这个要求,作者首次定义了另一个指数衰减均值,这次不是梯度平方,而是参数的平方的更新:

 

E[Δθ2]t=γE[Δθ2]t−1+(1−γ)Δθ2tE[Δθ2]t=γE[Δθ2]t−1+(1−γ)Δθt2

 

因此,参数更新的均方根误差为:

 

RMS[Δθ]t=E[Δθ2]t+ϵ‾‾‾‾‾‾‾‾‾‾‾√RMS[Δθ]t=E[Δθ2]t+ϵ

 

由于RMS[Δθ]tRMS[Δθ]t是未知的,我们利用参数的均方根误差来近似更新。利用RMS[Δθ]t−1RMS[Δθ]t−1替换先前的更新规则中的学习率ηη,最终得到Adadelta的更新规则:

 

Δθt=−RMS[Δθ]t−1RMS[g]tgtΔθt=−RMS[Δθ]t−1RMS[g]tgt

 

 

θt+1=θt+Δθtθt+1=θt+Δθt

 

使用Adadelta算法,我们甚至都无需设置默认的学习率,因为更新规则中已经移除了学习率。

RMSprop

RMSprop是一个未被发表的自适应学习率的算法,该算法由Geoff Hinton在其Coursera课堂的课程6e中提出。

RMSprop和Adadelta在相同的时间里被独立的提出,都起源于对Adagrad的极速递减的学习率问题的求解。实际上,RMSprop是先前我们得到的Adadelta的第一个更新向量的特例:

 

E[g2]t=0.9E[g2]t−1+0.1g2tE[g2]t=0.9E[g2]t−1+0.1gt2

 

 

θt+1=θt−ηE[g2]t+ϵ‾‾‾‾‾‾‾‾‾‾√gtθt+1=θt−ηE[g2]t+ϵgt

 

同样,RMSprop将学习率分解成一个平方梯度的指数衰减的平均。Hinton建议将γγ设置为0.90.9,对于学习率ηη,一个好的固定值为0.0010.001。

​    

Adam

自适应矩估计(Adaptive Moment Estimation,Adam)[9]是另一种自适应学习率的算法,Adam对每一个参数都计算自适应的学习率。除了像Adadelta和RMSprop一样存储一个指数衰减的历史平方梯度的平均vtvt,Adam同时还保存一个历史梯度的指数衰减均值mtmt,类似于动量:

 

mt=β1mt−1+(1−β1)gtmt=β1mt−1+(1−β1)gt

 

 

vt=β2vt−1+(1−β2)g2tvt=β2vt−1+(1−β2)gt2

 

mtmt和vtvt分别是对梯度的一阶矩(均值)和二阶矩(非确定的方差)的估计,正如该算法的名称。当mtmt和vtvt初始化为0向量时,Adam的作者发现它们都偏向于0,尤其是在初始化的步骤和当衰减率很小的时候(例如β1β1和β2β2趋向于1)。

通过计算偏差校正的一阶矩和二阶矩估计来抵消偏差:

 

m̂ t=mt1−βt1m^t=mt1−β1t

 

 

v̂ t=vt1−βt2v^t=vt1−β2t

 

正如我们在Adadelta和RMSprop中看到的那样,他们利用上述的公式更新参数,由此生成了Adam的更新规则:

 

θt+1=θt−ηv̂ t‾‾√+ϵm̂ tθt+1=θt−ηv^t+ϵm^t

 

作者建议β1β1取默认值为0.90.9,β2β2为0.9990.999,ϵϵ为10−810−8。他们从经验上表明Adam在实际中表现很好,同时,与其他的自适应学习算法相比,其更有优势。

4.8 选择使用哪种优化算法?

那么,我们应该选择使用哪种优化算法呢?如果输入数据是稀疏的,选择任一自适应学习率算法可能会得到最好的结果。选用这类算法的另一个好处是无需调整学习率,选用默认值就可能达到最好的结果。

总的来说,RMSprop是Adagrad的扩展形式,用于处理在Adagrad中急速递减的学习率。RMSprop与Adadelta相同,所不同的是Adadelta在更新规则中使用参数的均方根进行更新。最后,Adam是将偏差校正和动量加入到RMSprop中。在这样的情况下,RMSprop、Adadelta和Adam是很相似的算法并且在相似的环境中性能都不错。Kingma等人[9]指出在优化后期由于梯度变得越来越稀疏,偏差校正能够帮助Adam微弱地胜过RMSprop。综合看来,Adam可能是最佳的选择。

有趣的是,最近许多论文中采用不带动量的SGD和一种简单的学习率的退火策略。已表明,通常SGD能够找到最小值点,但是比其他优化的SGD花费更多的时间,与其他算法相比,SGD更加依赖鲁棒的初始化和退火策略,同时,SGD可能会陷入鞍点,而不是局部极小值点。因此,如果你关心的是快速收敛和训练一个深层的或者复杂的神经网络,你应该选择一个自适应学习率的方法。


优化SGD的其他策略

最后,我们介绍可以与前面提及到的任一算法配合使用的其他的一些策略,以进一步提高SGD的性能。

批量归一化

为了便于学习,我们通常用0均值和单位方差初始化我们的参数的初始值来归一化。 随着不断训练,参数得到不同的程度的更新,我们失去了这种归一化,随着网络变得越来越深,这种现象会降低训练速度,且放大参数变化。

批量归一化[8]在每次小批量数据反向传播之后重新对参数进行0均值单位方差标准化。通过将模型架构的一部分归一化,我们能够使用更高的学习率,更少关注初始化参数。批量归一化还充当正则化的作用,减少(有时甚至消除)Dropout的必要性。

Early stopping

如Geoff Hinton所说:“Early Stopping是美丽好免费午餐”(NIPS 2015 Tutorial slides)。你因此必须在训练的过程中时常在验证集上监测误差,在验证集上如果损失函数不再显著地降低,那么应该提前结束训练。

梯度噪音

Neelakantan等人[12]在每个梯度更新中增加满足高斯分布N(0,σ2t)N(0,σt2)的噪音:

高斯分布的方差需要根据如下的策略退火:

他们指出增加了噪音,使得网络对不好的初始化更加鲁棒,同时对深层的和复杂的网络的训练特别有益。他们猜测增加的噪音使得模型更优机会逃离当前的局部最优点,以发现新的局部最优点,这在更深层的模型中更加常见。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值