经典最优化方法:梯度下降及其改进

本文内容

本文对深度学习中一些比较经典的最优化方法(梯度下降、基于动量的梯度下降、AdaGrad、RMSprop和Adam)进行了总结。本人也是一边学习一边总结,所以文中仅包含一些浅显基础的知识,已有一定基础的同学可酌情浏览。

梯度下降法

基本原理

梯度下降法是求解无约束最优化问题的一种常用方法,它是一种迭代算法,通过不断迭代使得目标函数最小化。以求解 f ( x ) f(x) f(x) R n R^n Rn上的最小值为例。假设 f ( x ) f(x) f(x) R n R^n Rn上的具有一阶连续导数,求:
m i n x ∈ R n f ( x ) \underset{x\in R^n}{min}f(x) xRnminf(x)
首先选择一个初值 x ( 0 ) x^{(0)} x(0),然后开始迭代,在每次迭代中以负梯度方向更新 x x x,从而使得函数值不断减小,直至收敛。其 k + 1 k+1 k+1 次迭代的公式如下:
x ( k + 1 ) = x ( k ) − η ∇ f ( x ( k ) ) x^{(k+1)}=x^{(k)}-\eta\nabla f(x^{(k)}) x(k+1)=x(k)ηf(x(k))
其中 η \eta η是学习率, ∇ f ( x ( k ) ) \nabla f(x^{(k)}) f(x(k)) f ( x ) f(x) f(x) x ( k ) x^{(k)} x(k)梯度。

梯度下降法存在的问题

梯度下降法简单,容易实现,但是它不保证最终求得的解为全局最优解(仅当目标函数为凸函数时梯度下降法的解是全局最优解)。另外梯度下降法的收敛速度也不能保证。

1.梯度下降法不能保证得到全局最优解
前面提到梯度下降法在每次迭代中以负梯度方向更新参数,这意味着当梯度等于0时,参数停止更新。但是我们都知道,当梯度为0时,参数可能停在函数的全局最优点,也可能在局部最优点甚至是驻点(连局部最优都不是!)。

2.很多时候梯度下降法是低效的
确切地说,当函数的形状是非均向的(anisotropic),搜索路径会非常低效,原因是负梯度的方向没有指向最小值的方向。下面以《深度学习入门基于Python的理论与实现》中的例子说明,考虑下面这个函数的最小值
f ( x , y ) = 1 20 x 2 + y 2 f(x,y)=\frac1{20}x^2+y^2 f(x,y)=201x2+y2
这个函数的图象如下图所示:
在这里插入图片描述
而它在各个的梯度方向如下图所示
在这里插入图片描述
稍有一点数学知识都可以知道, f ( x , y ) f(x,y) f(x,y)的最小值在 ( 0 , 0 ) (0,0) (0,0)点处,但是上图中并非所有的点都指向 ( 0 , 0 ) (0,0) (0,0)点,在这种情况下使用梯度下降法,很容易使参数更新的路径呈“之”字形移动,效率极为低下。
在这里插入图片描述

基于动量的梯度下降法

前面说到,梯度下降法对于形状非均向的的函数,梯度下降法的参数更新的路径常常呈“之”字形移动,效率低下。为了减缓这个问题,人们提出了基于动量的梯度下降法。基于动量的梯度下降法的思想十分简单:使参数更新的方向不仅受当前梯度影响,还受之前梯度影响。

指数加权平均

在介绍具体公式之前首先了解一下指数加权平均的思想。设 v t v_t vt v t − 1 … v 0 v_t-1 \dots v_0 vt1v0有如下关系
v t = β v t − 1 + ( 1 − β ) S t v t − 1 = β v t − 2 + ( 1 − β ) S t − 1 ⋮ v 1 = β v 0 + ( 1 − β ) S 1 v 0 = 0 v_t=\beta v_{t-1}+(1-\beta)S_t\\ v_{t-1}=\beta v_{t-2}+(1-\beta)S_{t-1}\\ \vdots\\ v_{1}=\beta v_{0}+(1-\beta)S_{1}\\ v_{0}=0 vt=βvt1+(1β)Stvt1=βvt2+(1β)St1v1=βv0+(1β)S1v0=0
其中 β \beta β大于0小于1,可以发现 v t v_t vt既受 v t − 1 v_{t-1} vt1的影响,又受 S t S_{t} St的影响,而 v t − 1 v_{t-1} vt1既受 v t − 2 v_{t-2} vt2的影响,又受 S t − 1 S_{t-1} St1的影响,将上式合并化简,可以得到
v t = β β … β t − 1 个 ( 1 − β ) S 1 + ⋯ + β ( 1 − β ) S t − 1 + ( 1 − β ) S t v_t=\underset{t-1个}{\beta\beta\dots\beta}(1-\beta)S_1+\dots+\beta(1-\beta)S_{t-1}+(1-\beta)S_t vt=t1βββ(1β)S1++β(1β)St1+(1β)St
我们发现 v t v_t vt S t 、 S t − 1 … S 1 S_t、S_{t-1} \dots S_1 StSt1S1的影响,且越靠前的 S S S v t v_t vt的影响越小。

基于动量的梯度下降

下面基于指数加权平均的思想对梯度下降进行改进,其 k + 1 k+1 k+1 次迭代的公式如下
v t = β v t − 1 + ( 1 − β ) ∇ f ( x ( k ) ) v_t=\beta v_{t-1}+(1-\beta)\nabla f(x^{(k)}) vt=βvt1+(1β)f(x(k))
x ( k + 1 ) = x ( k ) − α v t x^{(k+1)}=x^{(k)}-\alpha v_t x(k+1)=x(k)αvt
由于指数加权平均,参数每次更新的方向不仅受当前梯度影响,还受之前梯度影响,这使得参数更新的路径更加平缓,减小了更新路径的“之”化程度。

AdaGrad 与 RMSprop

梯度下降法还存在另外一个问题,那就是学习率的选取。学习率过大可能会导致算法无法收敛,学习率过小会导致学习花费过长时间。对于这个问题,人们提出一种被称为学习率衰减的方法,即随着学习的进行,学习率越来越小。

AdaGrad

AdaGrad就是基于学习率衰减的方法提出的,它会为参数的每一个元素是当地调整学习率,其 k + 1 k+1 k+1 次迭代的公式如下
h = h + ∇ f ( x k ) ⊙ ∇ f ( x ( k ) ) x ( k + 1 ) = x ( k ) − η 1 h ∇ f ( x ( k ) ) h=h+\nabla f(x^k)\odot\nabla f(x^{(k)})\\ x^{(k+1)}=x^{(k)}-\eta\frac1{\sqrt h}\nabla f(x^{(k)}) h=h+f(xk)f(x(k))x(k+1)=x(k)ηh 1f(x(k))
x x x表示要更新的参数, η \eta η表示学习率, ∇ f ( x ( k ) ) \nabla f(x^{(k)}) f(x(k))表示损失函数关于 x x x的梯度。 h h h是所有梯度值的平方和,在更新参数时,通过乘 1 h \frac1{\sqrt h} h 1动态地调整每次更新的尺度。
可以发现AdaGrad的学习率是越来越小的,这样,我们可以在一开始设置一个较大的学习率,加速算法收敛,而算法在学习的过程中会自动将学习率减小,保证算法能够收敛。
但是AdaGrad带来了新的问题,由于学习率是越来越小的,如果一直学习,学习率会趋于0,导致参数不再更新,如果此时算法还未收敛,我们的训练任务就失败了。

RMSprop

RMSprop对AdaGrad存在的问题进行了改善。它引入了之前提到的指数加权平均,它逐渐地遗忘过去的梯度,而将新梯度的信息更多地反映出来,其 k + 1 k+1 k+1 次迭代的公式如下
h = β h + ( 1 − β ) ∇ f ( x ( k ) ) ⊙ ∇ f ( x ( k ) ) x ( k + 1 ) = x ( k ) − η 1 h ∇ f ( x ( k ) ) h=\beta h+(1-\beta)\nabla f(x^{(k)})\odot\nabla f(x^{(k)})\\ x^{(k+1)}=x^{(k)}-\eta\frac1{\sqrt h}\nabla f(x^{(k)})\\ h=βh+(1β)f(x(k))f(x(k))x(k+1)=x(k)ηh 1f(x(k))
x x x表示要更新的参数, η \eta η表示学习率, ∇ f ( x ( k ) ) \nabla f(x^{(k)}) f(x(k))表示损失函数关于 x x x的梯度。 h h h是所有梯度值的加权平方和。同样,在更新参数时,通过乘 1 h \frac1{\sqrt h} h 1动态地调整每次更新的尺度。
h h h是所有梯度值的加权平方和,且越靠前的梯度影响越小,从而可以缓解学习率下降过快的问题。

Adam

前面介绍了两种改进梯度下降的思路,一种是基于动量的改进,一种是基于学习率衰减的改进。将这两种方法结合起来,就得到了Adam。其 k + 1 k+1 k+1 次迭代的公式如下
m t = β 1 m t − 1 + ( 1 − β 1 ) ∇ f ( x ( k ) )            ① n t = β 2 n t − 1 + ( 1 − β 2 ) ∇ f ( x ( k ) ) ⊙ ∇ f ( x ( k ) )            ② m ^ t = m t 1 − β 1 t            ③ n ^ t = n t 1 − β 2 t            ④ x ( k + 1 ) = x ( k ) − η 1 n ^ t m ^ t            ⑤ m_t=\beta_1m_{t-1}+(1-\beta_1)\nabla f(x^{(k)})\;\;\;\;\;①\\ n_t=\beta_2n_{t-1}+(1-\beta_2)\nabla f(x^{(k)})\odot\nabla f(x^{(k)})\;\;\;\;\;②\\ {\widehat m}_t=\frac{m_t}{1-\beta_1^t}\;\;\;\;\;③\\ {\widehat n}_t=\frac{n_t}{1-\beta_2^t}\;\;\;\;\;④\\ x^{(k+1)}=x^{(k)}-\eta\frac1{\sqrt{{\widehat n}_t}}{\widehat m}_t\;\;\;\;\;⑤ mt=β1mt1+(1β1)f(x(k))nt=β2nt1+(1β2)f(x(k))f(x(k))m t=1β1tmtn t=1β2tntx(k+1)=x(k)ηn t 1m t
x x x表示要更新的参数, η \eta η表示学习率, ∇ f ( x ( k ) ) \nabla f(x^{(k)}) f(x(k))表示损失函数, β 1 \beta_1 β1 β 2 \beta_2 β2为超参数,通常取0.9和0.999。
Adam原理比较复杂,严谨可靠的论述请参照原文(参考文献[6]),以下仅为个人理解。前面说过Adam结合了动量的思想和学习率衰减的思想进行改进,从公式上很容易看出这两种思想的影子,公式①和③很显然反映了动量的思想,使参数更新的方向不仅受当前梯度影响,还受之前梯度影响。而公式②和④反映学习率衰减的思想,使学习率越来愈小。最后公式⑤对上述公式进行汇总,即完成了Adam的参数更新公式。

总结

本文介绍的几种算法各有各的特点,但是基本的原理都是梯度下降(废话)。相对这几种算法,Adam是目前深度学习中主流且常用的算法,但这并不代表Adam是所有问题的最优解。对于不同的问题应当选择不同的算法,有的问题不能使用基于动量的梯度下降(例如训练WGAN),此时选用RMSProp反而有较好的效果。

参考文献

[1]《统计学习方法》李航
[2]《深度学习入门基于Python的理论与实现》[日]斋藤康毅
[3] 一文搞懂深度学习中的梯度下降
[4] Adaptive Subgradient Methods for Online Learning and Stochastic Optimization
[5] rmsprop: Divide the gradient by a running average of its recent magnitude
[6] Adam - A Method for Stochastic Optimization

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值