【深度学习之优化器】SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam

1 优化器简介

损失函数:深度学习模型通过引入损失函数,用来计算目标预测的错误程度。根据损失函数计算得到的误差结果,需要对模型参数(即权重和偏差)进行很小的更改,以期减少预测错误。
优化器:使损失函数最小化的方式更改可训练参数,损失函数指导优化器朝正确的方向移动。


优化器的发展历程:SGD -> SGDM -> NAG —>AdaGrad -> AdaDelta -> Adam -> Nadam–>…
从AdaGrad之后提出的为 自适应学习率的优化算法。其思想:经常更新的参数,需要学习速度慢一些,偶尔更新的参数,需要学习率大一些。

2 常用优化器的计算


2.1 SGD

BGD (Batch gradient descent) 批量梯度下降法】:每次的梯度的更新 使用所有的样本。每一次的梯度更新都使用所有样本,更新100次遍历所有数据100次

  • 优点:每次迭代都计算了全部的样本,获取到的是全局最优解
  • 缺点
    1)要对实际数据同时计算梯度,就会非常的耗时;
    2)同事实际使用中数据量都很大,无法进行一次完成所有数据的迭代。

SGD(Stochastic gradientdescent)随机梯度下降法】:每次的梯度的更新 使用一个样本。

  • 优点:速度快
  • 缺点
    1)噪声大,波动大;
    2)非常容易陷入局部最优解;
    3)结果具有随机性,因为可能只使用到部分的样本,就已经迭代到局部最优解了

MBGD(Mini-batch gradient descent)小批量梯度下降】:每次的梯度的更新 使用batch个样本。

  • 优点
    1)相较SGD收敛更稳定;
    2)另一方面可以充分地利用深度学习库中高度优化的矩阵操作来进行更有效的梯度计算。
  • 缺点
    1)SGD的学习受 学习率影响,如果lr偏大,lossfunction 会在极小值处不停地震荡;lr偏小,收敛速度就会变慢。
    这种情况一般解决方法,训练开始使用较大lr,随着迭代过程逐步降低lr,这样我们需要多尝试 lr降低策略,直到找到最优的)
    2)对于非凸函数,容易陷入局部最优解。因为在鞍点周围的所有维度的梯度都约等于0,就很容易困在这里在这里插入图片描述

但在实际的论文或工程中,所说的使用优化器SGD,其实指代的MBGD。这样强调的重点是参数更新的计算方式,而不是batch数量。所以在本博客接下来的表述中,SGD就指代MBGD。

SGD的表达式为:θ t = θ t − 1 − l r ∗ ▽ t J ( θ t ) \theta^{t}=\theta^{t-1}-lr*\bigtriangledown _{t}J(\theta^{t})θt=θt1lrtJ(θt)


2.2 SGD+Momentum

为了优化SGD的问题,提出了SGDM(使用动量的随机梯度下降)。
动量方法是为了加速学习(加速梯度下降),特别的是处理高曲率、小但一致的梯度,或带噪声的梯度。动量累积了之前梯度指数级衰减的移动平均,并继续沿该方向移动。
这里约等于是对动量进行了加权平均。

具体的数学表达式如下: v t = γ v t − 1 + l r ∗ ▽ J ( θ t ) v^{t} = \gamma v^{t-1} + lr*\bigtriangledown J(\theta^{t})vt=γvt1+lrJ(θt) θ t = θ t − 1 − v t \theta^{t}=\theta^{t-1}-v^{t}θt=θt1vt
其中,g t g^tgt为本次计算的梯度,l r lrlr 为学习率,θ \thetaθ为当前的参数。
γ \gammaγ为动量因子,通常被设置为0.9~0.99之间。

SGDM】好处:

  • 减小震荡,加速收敛:在前后两次梯度方向改变时,momentum能够降低参数更新速度,从而减少震荡;在两次梯度方向相近时,momentum可以加速参数更新, 从而加速收敛
  • 离开鞍点,离开局部最优:如果运行到了鞍点,不会立马停下来,即使当前的方向为水平,因为会借用上一时刻的动量,从而离开鞍点,离开局部最优值。

这里图示简单示意SGDM是如何减小震荡的。横轴为权重参数,纵轴为该操作的输出,我们想由起始点开始优化迭代,直至目标输出target。

  • 使用SGD的收敛曲线 (图一),进行了7次的梯度更新后,到达target。使用SGDM的收敛曲线 (图二),进行4次的梯度更新后,到达target。
    对与某一次的迭代,若上次和本次的梯度方向相反(夹角大于90),则会减弱本次的梯度,使其减小震荡,加速收敛 (图三);若上次和本次的梯度方向相近(夹角小于90度),动量项产生一个加速的作用,从而加速收敛(图略)。最后给出个动图模拟两者的收敛
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    请添加图片描述

2.3 NAG

牛顿加速梯度动量优化方法(NAG, Nesterov accelerated gradient):沿着上一步的速度方向先走一小步,再看当前的梯度然后再走一步。简化的理解是:

  • SGD:在点B时,直接沿着点B的梯度进行更新即可
  • SGDM:在点B时,先沿着动量项的方向更新到B’,然后在按照点B的梯度方向更新。
  • NAG:在点B时,先沿着动量项的方向更新到 B’,然后计算B’ 位置的梯度,再沿着 B’ 的梯度方向进行更新。具体公式为θ ′ = θ t − 1 − γ v t − 1 \theta^{'}=\theta^{t-1}-\gamma v_{t-1}θ=θt1γvt1 v t = γ v t − 1 + l r ∗ ▽ J ( θ ′ ) v_{t}=\gamma v_{t-1}+lr*\bigtriangledown J(\theta^{'})vt=γvt1+lrJ(θ) θ t = θ t − 1 − v t \theta^{t}=\theta^{t-1}-v_tθt=θt1vt在这里插入图片描述

2.4 AdaGrad

二阶动量:可以度量历史更新频率。使⽤⼀个小批量随机梯度 g t g_tgt按元素平⽅的累加变量 的所有历史累计值n t n_tnt。 可以解释为以往所有梯度值的平方和,越大表示经常跟新,越小表示不经常更新。
n 0 = g 0 2 n_0=g^{2}_0n0=g02
n 1 = g 0 2 + g 1 2 n_1=g^{2}_0+g^{2}_1n1=g02+g12
n 2 = g 0 2 + g 1 2 + g 2 2 n_2=g^{2}_0+g^{2}_1+g^{2}_2n2=g02+g12+g22

AdaGrad 的操作为:根据梯度的情况自适应的调整学习率,从而避免统⼀的学习率难以适应所有维度的问题。在第t次时,有公式:n t = n t − 1 + g t 2 n_{t}=n_{t-1}+g^{2}_{t}nt=nt1+gt2 Δ θ t = − l r n t + ε ∗ g t \Delta \theta_{t}=-\frac{lr}{\sqrt{n_{t}+\varepsilon }}*g_{t}Δθt=nt+εlrgt
特点:

  • n t n_tnt单调递增,l r ′ lr^{'}lr单调递减。
  • 前期n t n_tnt较小的时候,学习率较大,能够放大梯度。
    后期n t n_tnt 较大的时候,学习率较小,能够缩小梯度
    中后期,分母上梯度平方的累加会越来越大,使gradient→0,使得训练提前结束。

2.5 RMSProp算法 / Adadelta算法

两者都是为了解决 AdaGrad 学习率下降过快的问题,提出了 n t n_tnt的计算使用加权的方式,只关注过去一段时间内的变化。

  • 对于RMSProp,更新的梯度为 n t = γ n t − 1 + ( 1 − γ ) g t 2 n_{t}=\gamma n_{t-1}+(1-\gamma)g^{2}_{t}nt=γnt1+(1γ)gt2 Δ θ t = − l r n t + ε ∗ g t \Delta \theta_{t}=-\frac{lr}{\sqrt{n_{t}+\varepsilon }}*g_{t}Δθt=nt+εlrgt
  • 对于Adadelta,没有学习率这个超参数。它会维护一个新的变量 Δ x t \Delta x_{t}Δxt,初始为0,用其来带替学习率的设置。
    n t = γ n t − 1 + ( 1 − γ ) g t 2 n_{t}=\gamma n_{t-1}+(1-\gamma)g^{2}_{t}nt=γnt1+(1γ)gt2 Δ θ t = − Δ x i − 1 + ε n t + ε ∗ g t \Delta \theta_{t}=-\frac{\sqrt{\Delta x_{i-1}+\varepsilon }}{\sqrt{n_{t}+\varepsilon }}*g_{t}Δθt=nt+εΔxi1+εgt Δ x i = ρ Δ x i − 1 + ( 1 − ρ ) g t 2 \Delta x_{i}=\rho \Delta x_{i-1}+(1-\rho )g^{2}_{t}Δxi=ρΔxi1+(1ρ)gt2

2.6 Adam

Adam(Adaptive Moment Estimation)自适应矩估计。adam–> SGDM + RMSProp,也就是结合了动量加权、自适应学习率的系数加权(梯度的平方)。公式为v t = β 1 v t − 1 + ( 1 − β 1 ) g t v_t=\beta_{1}v_{t-1} + (1-\beta_1)g_tvt=β1vt1+(1β1)gtn t = β 2 n t − 1 + ( 1 − β 2 ) g t 2 n_t=\beta_2n_{t-1} + (1-\beta_2)g^2_tnt=β2nt1+(1β2)gt2作者发现一阶和二阶值初始训练时很小,接近为0,所以作者重新计算了个偏差进行校正,降低偏差对训练初期的影响。训练前期时,1 / ( 1 − β t ) 1/(1-\beta^t)1/(1βt)起到校正作用,训练后期,该项约定于1,不起作用。v ^ t = v t 1 − β 1 t \hat{v}_t=\frac{v_t}{1-\beta^t_1}v^t=1β1tvt n ^ t = n t 1 − β 2 t \hat{n}_t=\frac{n_t}{1-\beta^t_2}n^t=1β2tnt 最终的梯度更新为 θ t + 1 = θ t − l r n ^ t + ε v ^ t \theta_{t+1}=\theta_t-\frac{lr}{\sqrt{\hat{n}_t+\varepsilon}}\hat{v}_tθt+1=θtn^t+εlrv^t其中 β 1 t \beta^t_1β1tβ 2 t \beta^t_2β2tβ \betaβ的t次方。超参通常选择 β 1 = 0.9 \beta_1=0.9β1=0.9β 2 = 0.999 \beta_2=0.999β2=0.999ε = 1 0 8 \varepsilon=10^8ε=108

adam中1 / ( 1 − β t ) 1/(1-\beta^t)1/(1βt)的参数的推导:
n 1 = ( 1 − β 2 ) g 1 2 n_1=(1-\beta_2)g^2_1n1=(1β2)g12
n 2 = β 2 v 1 + ( 1 − β ) g 2 2 n_2=\beta_2 v_1+(1-\beta)g^2_2n2=β2v1+(1β)g22
= β 2 ( 1 − β 2 ) g 1 2 + ( 1 − β 2 ) g 2 2 =\beta_2(1-\beta_2)g^2_1+(1-\beta_2)g^2_2=β2(1β2)g12+(1β2)g22
= ( 1 − β 2 ) ( β 2 g 1 2 + g 2 2 ) =(1-\beta_2)(\beta_2g^2_1+g^2_2)=(1β2)(β2g12+g22)
= ( 1 − β 2 ) ( β 2 2 − 1 g 1 2 + β 2 2 − 2 g 2 2 ) =(1-\beta_2)(\beta^{2-1}_2g^2_1+\beta^{2-2}_2g^2_2)=(1β2)(β221g12+β222g22)
= ( 1 − β 2 ) ∑ i = 1 2 β 2 2 − i g 2 2 =(1-\beta_2)\sum^2_{i=1}\beta^{2-i}_2g^2_2=(1β2)i=12β22ig22
n t = ( 1 − β 2 ) ∑ i = 1 t β 2 t − 1 g i 2 n_t=(1-\beta_2)\sum^t_{i=1}\beta^{t-1}_2 g^2_int=(1β2)i=1tβ2t1gi2
E ( n t ) = ( 1 − β 2 ) E ( ∑ i = 1 t β 2 t − i g i 2 ) + ξ E(n_t)=(1-\beta_2) E(\sum^{t}_{i=1}\beta^{t-i}_2 g^2_i)+\xiE(nt)=(1β2)E(i=1tβ2tigi2)+ξ
= ( 1 − β 2 ) ( 1 + β 2 1 + β 2 2 + . . . + β 2 t − 1 ) E ( g i 2 ) + ξ =(1-\beta_2)(1+\beta^1_2+\beta^2_2+...+\beta^{t-1}_2)E(g^2_i)+\xi=(1β2)(1+β21+β22+...+β2t1)E(gi2)+ξ
= ( 1 − β 2 ) ( 1 − β 2 t 1 − β 2 ) E ( g i 2 ) + ξ =(1-\beta_2)(\frac{1-\beta^t_2}{1-\beta_2})E(g^2_i)+\xi=(1β2)(1β21β2t)E(gi2)+ξ
= ( 1 − β 2 t ) E ( g i 2 ) + ξ =(1-\beta^t_2)E(g^2_i)+\xi=(1β2t)E(gi2)+ξ
我们实际需要的是梯度的二阶矩估计E ( g i 2 ) E(g^2_i)E(gi2),但当前是对v t v_tvt求期望E ( v t ) E(v_t)E(vt),因此要得到 E ( g i 2 ) E(g^2_i)E(gi2),就需要除以前面的系数。
公式推导是OK的,但这里的个人理解还是有点不明确。只需要把握住:重新计算了个偏差进行校正,可以降低偏差对训练初期的影响。


版权声明:本文为magic_ll原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。