2018-12-28 11:37:04 qq_33414271 阅读数 264

一、发展背景及基本框架

梯度下降是目前神经网络中使用最为广泛的优化算法之一。为了弥补朴素梯度下降的种种缺陷,研究者们发明了一系列变种算法,从最初的 SGD (随机梯度下降) 逐步演进到 NAdam。然而,许多学术界最为前沿的文章中,都并没有一味使用 Adam/NAdam 等公认“好用”的自适应算法,很多甚至还选择了最为初级的 SGD 或者 SGD with Momentum 等。

深度学习优化算法的发展历程:
SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam

最基本的框架——梯度下降法(GD)

梯度下降法(GD:gradient descent )或最速下降法(SD:steepest descent )是求解无约束优化问题最常用的方法,实现简单。

梯度下降是指,在给定待优化的模型参数 θRd\theta \in \mathbb{R}^d和目标函数 J(θ)J(\theta) 后,算法通过沿梯度 θJ(θ)\nabla_\theta J(\theta) 的相反方向更新 θ\theta 来最小化J(θ)J(\theta) 。学习率 η\eta 决定了每一时刻的更新步长。对于每一个时刻 tt ,我们可以用下述步骤描述梯度下降的流程:

(1) 计算目标函数关于参数的梯度
gt=θJ(θ)g_t = \nabla_\theta J(\theta)
(2) 根据历史梯度计算一阶和二阶动量
mt=ϕ(g1,g2, ,gt)m_t = \phi(g_1, g_2, \cdots, g_t)
vt=ψ(g1,g2, ,gt)v_t = \psi(g_1, g_2, \cdots, g_t)
(3) 更新模型参数
θt+1=θt1vt+ϵmt\theta_{t+1} = \theta_t - \frac{1}{\sqrt{v_t + \epsilon}} m_t
其中, ϵ\epsilon 为平滑项,防止分母为零,通常取 1e-8。

二、GD算法体系

先上图做直观对比:
在这里插入图片描述
“长谷 (Long Valley)”点——没有基于梯度信息缩放的算法在这里很难打破对称性——SGD在哪里都找不到, Nesterov Accelerated Gradient(NAG) / Momentum 在优化方向上建立速度之前会出现振荡。(此时自适应算法会更好)

在这里插入图片描述
由于大的初始梯度,基于速度的技术(SGD-M ,NAG)被发射出来并在周围反弹。其中 Adagrad、Adadelta、RMSprop 从最开始就找到了正确的方向并快速收敛;SGD 找到了正确方向但收敛速度很慢;SGD-M 和 NAG 最初都偏离了航道,但也能最终纠正到正确方向,SGD-M 偏离的惯性比 NAG 更大。

在这里插入图片描述
鞍点(Saddle Point)附近的行为:
NAG /Momentum探索周围,几乎走了不同的路径。
Adadelta/Adagrad/RMSProp像加速SGD一样运行。

2.1-朴素 SGD (Stochastic Gradient Descent)

最为简单,没有动量的概念
在这里插入图片描述
这时,更新步骤就是最简单的θi+1=θtηgt\theta_{i+1}= \theta_t - \eta g_t

SGD 的缺点在于收敛速度慢,可能在长谷处震荡。并且,如何合理的选择学习率是 SGD 的一大难点。

2.2-SGD with Momentum

为了抑制SGD的震荡,SGDM认为梯度下降过程可以加入惯性。下坡的时候,如果发现是陡坡,那就利用惯性跑的快一些。SGDM全称是SGD with momentum,在SGD基础上引入了一阶动量:
mt=γmt1+ηgtm_t = \gamma m_{t-1} + \eta g_t

SGD-M 在原步长之上,增加了与上一时刻步长相关的 γmt1\gamma m_{t-1}γ\gamma 通常取 0.9 左右。这意味着参数更新方向不仅由当前的梯度决定,也与此前累积的下降方向有关。
这使得参数中那些梯度方向变化不大的维度可以加速更新,并减少梯度方向变化较大的维度上的更新幅度。由此产生了加速收敛和减小震荡的效果。
在这里插入图片描述
从形式上看,动量算法(红色)引入了变量v 充当速度角色——它代表参数在参数空间移动的方向和速率。速度被设为负梯度的指数衰减平均。

2.3-Nesterov Accelerated Gradient

更进一步的,人们希望下降的过程更加智能:算法能够在目标函数有增高趋势之前,减缓更新速率。

NAG 即是为此而设计的,其在 SGD-M 的基础上进一步改进了步骤 1 中的梯度计算公式:
gt=θJ(θγmt1)g_t = \nabla_\theta J(\theta - \gamma m_{t-1})
在这里插入图片描述
SGD-M 的步长计算了当前梯度(短蓝向量)和动量项 (长蓝向量)。然而,既然已经利用了动量项来更新 ,那不妨先计算出下一时刻 θ\theta 的近似位置 (棕向量),并根据该未来位置计算梯度(红向量),然后使用和 SGD-M 中相同的方式计算步长(绿向量)。这种计算梯度的方式可以使算法更好的「预测未来」,提前调整更新速率。

2.4-Adagrad(自适应更新学习率)

Ada为Adaptive,自适应算法。

SGD、SGD-M 和 NAG 均是以相同的学习率去更新 θ\theta 的各个分量。而深度学习模型中往往涉及大量的参数,不同参数的更新频率往往有所区别。

对于更新不频繁的参数(典型例子:更新 word embedding 中的低频词),我们希望单次步长更大,多学习一些知识;对于更新频繁的参数,我们则希望步长较小,使得学习到的参数更稳定,不至于被单个样本影响太多。

Adagrad算法即可达到此效果。其引入了二阶动量:

Adaptive Subgradient Methods for Online Learning and Stochastic Optimization

vt=diag(i=1tgi,12,i=1tgi,22, ,i=1tgi,d2)v_t = \text{diag}(\sum_{i=1}^t g_{i,1}^2, \sum_{i=1}^t g_{i,2}^2, \cdots, \sum_{i=1}^t g_{i,d}^2)

其中, vtRd×dv_t \in \mathbb{R}^{d\times d} 是对角矩阵,其元素 vt,iiv_{t, ii} 为参数第 i 维从初始时刻到时刻 t 的梯度平方和。

此时,可以这样理解:学习率等效为 η/vt+ϵ\eta / \sqrt{v_t + \epsilon} 。对于此前频繁更新过的参数,其二阶动量的对应分量较大,学习率就较小。这一方法在稀疏数据的场景下表现很好。

2.5-RMSprop

在 Adagrad 中, vtv_t是单调递增的,使得学习率逐渐递减至 0,可能导致训练过程提前结束。为了改进这一缺点,可以考虑在计算二阶动量时不累积全部历史梯度,而只关注最近某一时间窗口内的下降梯度。根据此思想有了 RMSprop

gtgtg_t \odot g_tgt2g_t^2 ,有
vt=γvt1+(1γ)diag(gt2)v_t = \gamma v_{t-1} + (1-\gamma) \cdot \text{diag}(g_t^2)

其二阶动量采用指数移动平均公式计算,这样即可避免二阶动量持续累积的问题。和 SGD-M 中的参数类似,\gamma 通常取 0.9 左右。

CSC321 Neural Networks for Machine Learning - Lecture 6a

2.6-Adam

Adam可以认为是 RMSprop 和 Momentum 的结合。和 RMSprop 对二阶动量使用指数移动平均类似,Adam 中对一阶动量也是用指数移动平均计算。

Adam: A Method for Stochastic Optimization

mt=η[β1mt1+(1β1)gt]m_t = \eta[ \beta_1 m_{t-1} + (1 - \beta_1)g_t ]
vt=β2vt1+(1β2)diag(gt2)v_t = \beta_2 v_{t-1} + (1-\beta_2) \cdot \text{diag}(g_t^2)
其中,初值
m0=0m_0 = 0
v0=0v_0 = 0
注意到,在迭代初始阶段,mtm_tvtv_t 有一个向初值的偏移(过多的偏向了 0)。因此,可以对一阶和二阶动量做偏置校正 (bias correction),
m^t=mt1β1t\hat{m}_t = \frac{m_t}{1-\beta_1^t}
v^t=vt1β2t\hat{v}_t = \frac{v_t}{1-\beta_2^t}
再进行更新,
θt+1=θt1v^t+ϵm^t\theta_{t+1} = \theta_t - \frac{1}{\sqrt{\hat{v}_t} + \epsilon } \hat{m}_t
可以保证迭代较为平稳。

三、小结

在这里插入图片描述
虽然这些算法在使用的时候或许只是一句代码,但了解其发展历程和基本特点是很有必要的。

参考:
[1]从 SGD 到 Adam —— 深度学习优化算法概览(一) - 骆梁宸的文章 - 知乎
https://zhuanlan.zhihu.com/p/32626442
[2]一个框架看懂优化算法之异同 SGD/AdaGrad/Adam - Juliuszh的文章 - 知乎
https://zhuanlan.zhihu.com/p/32230623
[3]https://blog.csdn.net/u012223913/article/details/78432412
[4]Visualizing Optimization Algos

2019-05-17 12:07:02 weixin_37142859 阅读数 103

深度学习优化算法

参考资料

1梯度下降算法的三个变种

根据计算一次梯度更新所使用的数据量大小,梯度下降算法共分为三种:

  • Batch gradient descent;(整个数据集)
  • Stochastic gradient descent;(一个数据样本)
  • Mini-batch gradient descent;(几个样本)

Batch gradient descent

Batch gradient descent的梯度更新公式为:
θ=θηθJ(θ)\theta=\theta-\eta \cdot \nabla_{\theta} J(\theta)

(打公式我有一个独特的窍门,嘻嘻)
式中θ\theta要更新的参数,η\eta为学习率,θJ(θ)\nabla_{\theta} J(\theta)是在整个数据集上损失的梯度。
优点:

  • 能保证模型最后收敛于全局最小点(若损失为凸)或局部最小点(损失函数非凸)

缺点:

  • 每更新一次参数需要计算出整个数据集每一个样本的推断结果并计算损失,计算量大,内存占用大
  • 权重更新缓慢
  • 无法在线学习

Stochastic gradient descent(SGD)

Stochastic gradient descent每次计算损失的梯度时,仅使用一个样本,公式如下:
θ=θηθJ(θ;x(i);y(i))\theta=\theta-\eta \cdot \nabla_{\theta} J\left(\theta ; x^{(i)} ; y^{(i)}\right)
优点

  • 考虑一种计算情况,假设数据集中每个样本都一样,Batch gradient decent用所有的数据样本来计算损失,存在严重的计算冗余,其实只要计算一个样本即可。尽管这种极端的情况不会出现,但在同一个数据集中,数据必然存在相似性,SGD相比于Batch gradient decent能减少很多计算冗余。
  • 研究表明,当学习率较小时,SGD和BGD有相同的收敛点
  • 在线学习

缺点

  • SGD由于其频繁的权重更新,会导致损失在下降过程中出现较大的波动。但是波动可能使损失函数跳出局部最小值,进入一个小的收敛点。

Mini-batch gradient descent

Mini-batch gradient descent则是使用数据集中的几个样本计算损失的梯度。计算公式如下:
θ=θηθJ(θ;x(i:i+n);y(i:i+n))\theta=\theta-\eta \cdot \nabla_{\theta} J\left(\theta ; x^{(i : i+n)} ; y^{(i : i+n)}\right)
优点

  • 减小了权重更新的方差,使得损失收敛于一个更稳定的点
  • mini-batch的使用使得我们最大化利用GPU的并行计算能力

2 梯度下降算法的痛点

  • 学习率大小选择困难。太小导致训练缓慢,太大则容易导致难以收敛,在(局部)最小点附近波动
  • 算法中所有的参数都使用相同的学习率进行更新,但实际上对于不同的参数,可能有不同的更新需求
  • 在高维的损失优化中,很难收敛到每一维数据梯度都接近于0的点,相反,很容易收敛于鞍点或局部最小点

3 各种梯度下降算法

Momentum

权重更新公式:
vt=γvt1+ηθJ(θ)θ=θvt\begin{aligned} v_{t} &=\gamma v_{t-1}+\eta \nabla_{\theta} J(\theta) \\ \theta &=\theta-v_{t} \end{aligned}
记进行第tt次权重更新时,梯度大小为gtg_t(为了方便表达),则上式变为:
vt=γvt1+ηgt=ηgt+γ(ηgt1+γvt2)=ηgt+γηgt1+γ2vt2...=ηgt+γηgt1+γ2ηgt2+...+γt1ηg1\begin{aligned}v_t &= \gamma v_{t-1} + \eta g_t \\&=\eta g_t + \gamma(\eta g_{t-1}+\gamma v_{t-2})\\&=\eta g_t + \gamma \eta g_{t-1} + \gamma^2v_{t-2}\\ &...\\&=\eta g_t+\gamma \eta g_{t-1}+\gamma ^2 \eta g_{t-2} + ...+\gamma ^ {t-1}\eta g_1\end{aligned}
从式中可以知道,权重更新不仅和本次计算出来损失函数的梯度有关,还和之前计算出来每一次的梯度大小有点,距离越近,贡献越大,距离越远,贡献越小(γ<1\gamma<1)。当γ=0\gamma=0时则退化成普通的SGD。
那么,把以往的权重更新考虑进去有什么用呢???

  • 若在某个维度多次权重更新方向一致,则会加速该权重的更新
  • 若在某个维度权重更新方向一直发生变化,即梯度出现正负交替,多个梯度求和的结果则会减小该方向权重的变化。

但是,Momentum法存在一个缺陷。当某一维度的梯度经过多次同样的方向的权重更新后,达到了最小值。尽管在最小值处的的梯度gt=0g_t=0,但是!由于累计梯度的原因,vt1v_{t-1}并不为0,因此权重会铁憨憨地继续更新,但却是往损失变大的方向更新。
因此,需要给权重的更新提供一点感知下一位置的能力。请看下一个方法!

Nesterov accelerated gradient

权重更新公式
vt=γvt1+ηθJ(θγvt1)θ=θvt\begin{array}{l}{v_{t}=\gamma v_{t-1}+\eta \nabla_{\theta} J\left(\theta-\gamma v_{t-1}\right)} \\ {\theta=\theta-v_{t}}\end{array}
对比Momentum法,二者在权重更新时,都由两项组成:

  • 累计动量项:γvt1\gamma v_{t-1}
  • 损失梯度项:
    ηθJ(θγvt1)\eta \nabla_{\theta} J\left(\theta-\gamma v_{t-1}\right)(Nesterov);
    ηθJ(θ)\eta \nabla_{\theta} J(\theta)(Momentum)

二者的区别在于损失梯度项。对于Momentum,是当前位置的梯度损失;对于Nesterov是下一近似位置的梯度损失,正是该项,赋予了该优化方法感知下一刻的能力。
考虑以下这个场景:某一维度的权重经过多次的更新后,累计动量项已相对较大,且接近了最小点,权重再次更新后会导致损失反而变大。看看二者的表现:

  • Momentum:计算当前位置损失的梯度(仍与之前的梯度相同),结合累计动量项,更新权重,最终导致损失反而变大
  • Nesterov:计算下一位置的近似梯度(过了最小点之后,此时的梯度与之前相反),结合累计动量项,更新权重。由于损失梯度项变为相反值,一定程度上减少了权重更新的幅度,缓和甚至避免了损失的回升!

考虑一个二维权重的更新,水平方向和垂直方向,假设垂直方向的权重已接近最优值,也即权重再增大会导致损失不减反增。
Momentum的损失梯度项(红色)垂直方向的分量接近0,但累计动量项仍有很大的垂直分量,两个分量合成后(黄色),垂直方向的权重仍进行了很大的权重更新。
Nesterov的损失梯度项是下一位置的近似梯度,由于下一位置梯度和当前相反,因此垂直分量向下。两个分量合成后,垂直方向的分量抵消了一部分,最终垂直方向的权重更新不大。

Adagrad

权重更新公式:
θt+1,i=θt,iηGt,ii+ϵgt,i\theta_{t+1, i}=\theta_{t, i}-\frac{\eta}{\sqrt{G_{t, i i}+\epsilon}} \cdot g_{t, i}
式中:

  • θt+1,i\theta_{t+1,i}t+1t+1时刻ii方向的权重;
  • Gt,iiG_{t,ii}是对角阵GtG_t对角上第ii个元素,该元素大小为θi\theta_i以往每一次梯度的平方和;
  • ϵ=108\epsilon=10^{-8},避免除0

Adagrad方法旨在对不同参数,在不同时刻使用不同的学习率。
对于频繁发生更新(梯度不为0)的权重,其学习率会被调整得较小;而对于更新不频繁的权重,其学习率则会被调整得较大。
但随着训练的进行,梯度的平方和越来越大,导致最终学习率被调整得很小,导致训练收敛困难。

Adadelta

Adadelta旨在处理Adagrad学习速率单调递减的情况。不是使用所有梯度的平方和,而是使用梯度平方的调和均值(与常规均值不一样),定义如下:
E[g2]t=γE[g2]t1+(1γ)gt2E\left[g^{2}\right]_{t}=\gamma E\left[g^{2}\right]_{t-1}+(1-\gamma) g_{t}^{2}
相应地,权重变化值变成
Δθt=ηE[g2]t+ϵgt \Delta \theta_{t}=-\frac{\eta}{\sqrt{E\left[g^{2}\right]_{t}+\epsilon}} g_{t}
将分母用均方根(RME,先平方、取平均、再求平方根)表示(此处并不是严格的平方根,因为所取的平均是经过调和的):
Δθt=ηRMS[g]tgt \Delta \theta_{t}=-\frac{\eta}{R M S[g]_{t}} g_{t}
与以往不同,此处是对参数的平方进行更新:
E[Δθ2]t=γE[Δθ2]t1+(1γ)Δθt2 E\left[\Delta \theta^{2}\right]_{t}=\gamma E\left[\Delta \theta^{2}\right]_{t-1}+(1-\gamma) \Delta \theta_{t}^{2}
同样可以的到参数更新的均方根:
RMS[Δθ]t=E[Δθ2]t+ϵ R M S[\Delta \theta]_{t}=\sqrt{E\left[\Delta \theta^{2}\right]_{t}+\epsilon}
参数更新的均方根反应了以往参数更新的幅度大小,可用来代替学习率,于是,权重更新规则变为:
Δθt=RMS[Δθ]t1RMS[g]tgtθt+1=θt+Δθt \begin{array}{c}{\Delta \theta_{t}=-\frac{R M S[\Delta \theta]_{t-1}}{R M S[g]_{t}} g_{t}} \\ {\theta_{t+1}=\theta_{t}+\Delta \theta_{t}}\end{array}
无需设置学习率

RMSprop

RMSprop同样是为了解决Adagrad学习率单调递减的情况。和Adadelta初始想法一致,采用权重梯度平方和的均值来调整学习率。更新规则如下:
E[g2]t=0.9E[g2]t1+0.1gt2θt+1=θtηE[g2]t+ϵgt \begin{array}{c}{E\left[g^{2}\right]_{t}=0.9 E\left[g^{2}\right]_{t-1}+0.1 g_{t}^{2}} \\ {\theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{E\left[g^{2}\right]_{t}+\epsilon}} g_{t}}\end{array}

Adam

Adam同样是一个调整学习率的优化方法。除了记录梯度的历史平方和,还记录了梯度的指数平均值:
mt=β1mt1+(1β1)gtvt=β2vt1+(1β2)gt2 \begin{aligned} m_{t} &=\beta_{1} m_{t-1}+\left(1-\beta_{1}\right) g_{t} \\ v_{t} &=\beta_{2} v_{t-1}+\left(1-\beta_{2}\right) g_{t}^{2} \end{aligned}
将式子展开:
mt=β1mt1+(1β1)gt=(1β1)gt+β1((1β1)gt1+β1mt2)=(1β1)gt+(1β1)β1gt1+β12mt2...=(1β1)(gt+β1gt1+β12gt2+...+β1t1g1) \begin{aligned} m_t &=\beta_1m_{t-1}+(1-\beta_1)g_t\\ &=(1-\beta_1)g_t + \beta_1((1-\beta_1)g_{t-1} + \beta_1m_{t-2})\\ &=(1-\beta_1)g_t+(1-\beta_1) \beta_1 g_{t-1}+\beta_1^2m_{t-2}\\ &...\\ &=(1-\beta_1)(g_t+\beta_1g_{t-1}+\beta_1^2g_{t-2}+...+\beta_1^{t-1}g_1) \end{aligned}
vtv_t同理,都是在指数平均的基础上,再乘以一个缩减的系数。
通过计算偏差校正的一阶矩和二阶矩估计来抵消偏差:
m^t=mt1β1tv^t=vt1β2t \begin{aligned} \hat{m}_{t} &=\frac{m_{t}}{1-\beta_{1}^{t}} \\ \hat{v}_{t} &=\frac{v_{t}}{1-\beta_{2}^{t}} \end{aligned}
于是权重的更新公式为:
θt+1=θtηv^t+ϵm^t \theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat{v}_{t}}+\epsilon} \hat{m}_{t}
一般设置β1=0.9β2=0.999ϵ=108\beta_1=0.9、\beta_2=0.999、\epsilon=10^{-8}

4 如何挑选优化器

对于调整学习率的方法,如Adagrad、Adadelta、RMSprop、Adam等,实验表明Adam的效果好于其他方法。有趣的是,不带动量SGD搭配衰减的学习率经常能找到更小值,但会耗费更多的时间,并且也容易陷于鞍点。

2018-09-15 20:27:43 m0_37935211 阅读数 1295

本文依旧是吴恩达《深度学习工程师》课程的笔记整理与拓展。

一、优化算法的目的与挑战

    优化算法主要是用来加快神经网络的训练速度,使得目标函数快速收敛。

    优化问题面临的挑战有病态解、鞍点、梯度爆炸与梯度消失……具体可见参考文献【1】241页到249页。

    其中深度学习不太可能陷入局部最优,因为loss函数通常涉及多个维度(w1,w2...)

二、常见的优化算法

1、基本算法

  • 小批量梯度下降即各种变体

  1. 批量梯度下降(Batch gradient descent)

  2. 随机梯度下降(Stochastic gradient descent)

  3. 小批量梯度下降(Mini-batch gradient descent)

     三者关系:

             mini-batch size = m,Batch gradient descent

             mni-batch size = 1,Stochastic gradient descent

    三者各自的特点:

           Batch gradient descent:优化目标函数一次迭代的时间太长

          Stochastic gradient descent:丧失了向量化加速的优势

          Stochastic gradient descent:可以向量化,而且每次迭代不用遍历整个数据集

    如何选择mini-batch size:

          如果是小的训练集(m<=2000),可以直接使用Batch gradient descent;对于大的训练集,常见的size有64,128,256,512.另外注意考虑CPU/GPU memory。

    涉及概念Epoch:

           1 epoch即一代就是遍历整个数据集一次。

  • Momentum梯度下降法(Gradient descent with momentum)

      相对于通常的梯度下降法,该优化算法采用了dw的指数加权平均数替换原来的dw,使得w更快地指向最优解。

       指数加权平均  Exponentially weighted averages

       这里补充一下指数加权平均的概念。课堂上是以伦敦连续很多天的温度为例子,\theta _{t}是指第t天的温度

                                               V_{t} = \beta V _{t-1}+(1-\beta )\theta _{t}

       这里的指数加权平均Vt大约是\frac{1}{1-\beta }  天的平均温度

                                     

2、自适应学习率算法

  • RMSprop

       和Momentum算法一样,可以消除梯度下降中的摆动并使用更大的学习率。

      

  • Adam

      结合了Momentum和RMSprop两种算法,是很常用的优化算法。

三、如何选择合适的优化算法

         一是考虑自己对算法的熟悉程度, 便于调试超参数;二是Adam从总体来说是最好的选择。详见参考文献【2】、【3】

四、优化策略

        许多优化技术并非真正的算法,而是一般化的模板,可以特定地产生算法,或是并入到很多不同的算法中。

  • 正则化输入 Normalizing inputs

        正则化输入可以使得代价函数更圆,从而加快训练速度。

        实现方法分为两步:零均值化,归一化方差。即减去均值除以标准差。

  • 批标准化   Batch Normalization

​​​​​​​       批标准化使得每一层的隐藏单元有着标准的均值和方差(不一定分别为0和1),从而加快训练速度。

           \gamma \varepsilon这两个参数是需要学习的参数。更多内容参看论文。

  • 预训练

               待学习

  • 学习率衰减 Learning rate decay

                                               \alpha =\frac{1}{1+decayrate*epochnum}\alpha _{0}​​​​​​​

      两个超参数:decayrate、\alpha _{0}

 

【1】《深度学习》https://github.com/exacity/deeplearningbook-chinese

【2】《深度学习总结(五)——各优化算法》https://blog.csdn.net/manong_wxd/article/details/78735439

【3】《深度学习常用优化算法》https://blog.csdn.net/pandamax/article/details/72852960

2018-05-02 06:32:19 qq_39422642 阅读数 1853

4 深度学习中的优化算法

深度学习是目前非常火的一个研究领域,主要以研究神经网络为主,因为其复杂性,所以有很多问题需要处理,同时也衍生出了很多不同的优化算法,专门改善神经网络的训练,使得它能够在工业界使用。

因此,本章收录了关于神经网络训练的一些问题,以及相应的较为成熟的解决方案,供读者使用。

4.1 动量momentum

虽然小批量梯度下降法相比于梯度下降法有了一定的效率提升,但如果小批量中的样本也特别大的时候,一个批次的训练也会非常慢,所以人们就想,能不能在小批次样本上加快迭代的速度?

在物理学中,因为惯性,物体当前时刻的速度会受到前一时刻的速度影响,基于此,发现了momentum优化算法。简单的说,就是当前迭代点的下降方向不仅仅取决于当前的梯度,还受到前面所有迭代点的影响,就像小球在碗里滑动一样,它的滑动速度会越来越快,这样迭代就能快速地到达谷底了。

物理示意图如下,迭代的实际方向是以前所有的动量和当前梯度的组合:

假设学习率为ε,动量参数为α.初始参数为w,初始速度为v,每个批次有m个样本{x(1),x(2),,x(m)},它们对应的学习目标为y(i),梯度的计算可以表示为:
g=w(1mimL(f(x(i);w),y(i)))
根据前面说到的想法,先计算速度,它更新公式可以表示为:
v=αvεg
然后迭代函数的参数w,迭代公式表示为:
w=w+v
直到迭代停止时,迭代完成,此时的参数w就是使用该算法计算得到的最优参数。值得指出的是,使用该算法计算的步长取决于梯度序列的排列和大小,如果连续有几个梯度都是位于同一方向的,说明最低点很有可能就在那个方向,所以它的步长是最大的,这样能非常快速地找到最低点,减少了计算资源的消耗。 动量算法还能改进吗? Nesterov提出了一个针对动量算法的改进措施。普通的动量算法是把历史的梯度和当前的梯度进行合并,来计算下降的方向的。而Nesterov提出,为什么不能让迭代点先按照历史梯度再走一步,然后再合并呢?因此,他提出了一个优化的方案,主要在于梯度的计算上:
v=αvεw(1mimL(f(x(i);w+αv),y(i)))
这便是NAG算法。 如果要做一个比喻的话,momentum相当于一个路痴,它不知道下一步应该去哪里?而NAG则知道我们下一步的大概方向在哪里,然后提前计算梯度,用于当前位置指导下一步的行动。

4.2 AdaGrad

学习率对于神经网络模型的训练起着重要的作用,对于一般梯度下降法,学习率是人工给定的,如何给定并没有一个硬性的规则,什么样的学习率算好,什么样的算差完全取决于实际的问题分析。

有没有什么算法能为不同模型的参数设置不同的学习率,以适应实际问题的需要呢?答案就是AdaGrad算法,它对学习率进行了约束,每次训练可以使用不同的学习率。

假设全局的学习率为ε,初始参数为w,累积的平方梯度为

r=r+gg
,然后得到参数更新的公式:
w=wεδ+rg
其中,δ是为了保持分母不为0,一般会设置为107左右。由公式就可以看到,AdaGrad的学习率会在迭代过程中,随着历史梯度的变化而变化。这而带来了另外一个后果,就是在迭代的中后期,历史梯度在分母上的累积会越来越大,所以学习率会越来越小,使得网络的学习能力越来越弱,这又该如何解决呢?

4.3 RMSProp

前面说到了AdaGrad在训练的中后期,神经网络的学习能会越来越弱,主要是因为历史梯度的累积太大了,有没有什么办法可以解决呢?
既然主要是因为梯度累积太大的问题,那如果只计算固定大小的几项,梯度是不是就不会太大了呢?这就是Adadelta算法,而且,在Adadelta算法中,并不直接存错这些项,而是近似地计算它们的平均值。

Hinton提出的RMSProp是Adadelta的一个特例,我们通过它了解一下具体是怎么计算的。RMSProp旨在使用指数衰减平均来丢弃非常遥远的历史梯度,相当于指数加权平均来计算梯度。假设衰减速率为ρ,那么累积平方梯度可以表示为:

r=ρr+(1ρ)gg
由此得到整体的参数更新公式为:
w=wεδ+rg
这种算法目前在工业界的应用广泛,是一种非常有效且实用的深度神经网络算法。

4.4 Adam

前面介绍了动量算法和RMSProp,都有各自的特点,如果把它们的特点都结合起来呢?于是就形成了一种新的算法,Adam,它的思想是利用梯度的一阶矩估计和二阶矩估计来动态调整参数对应的学习率。

假设初始的一阶,二阶炬变量分别为s=0,r=0,矩估计的指数衰减速率分别为ρ1,ρ2,且它们都在区间[0,1)内。计算梯度的一阶炬估计为:

s=ρ1s+(1ρ1)g
梯度的二阶矩估计为:
r=ρ2r+(1ρ2)gg
然后再对它们进行修正,分别为
s^=s1ρ1t,r^=r1ρ2t
相当于取了它们的无偏估计,由此得到最终的参数更新公式
w=wεs^r^+δ
其中,ε表示步长,δ保证分母不为0,用于稳定数值。

AdaGrad善于处理稀疏梯度,而RMSProp善于处理非平稳的目标,而Adam同时具备了两者的优点,所以Adam能为不同的参数计算不同的学习率,它对超参数的选择也更加鲁棒。

4.5 几种算法的比较

说了这么多的算法,在实际的应用中应该怎么选择呢?
一般情况下,选择Adam是比较好的选择,因为它身上拥有很多优势,它的Python代码如下:

s = rho1*s + (1-rho1)*g
st = s/(1-rho1**t)

r = rho2*r + (1 - rho2)*(g**2)
rt = r/(1-rho2**t)

w += - learning_rate*st/(np.sqrt(rt) + delta)

一般的参数设置为rho1=0.9,rho2=0.999,delta=1e-8,其中t表示迭代的次数。

在一般的AdaGrad算法中,对累积的平方梯度开根号扮演着重要角色,如果没有这个开根号,算法的表现会糟糕很多。

r = r + g**2
w += -learning_rate*g/(np.sqrt(r) + delta)

它的平滑参数delta在1e41e8之间最合适。

如果选择RMSProp,因为它选择移动的平均梯度来代替固定的梯度,所以自然要引入一个衰减率。

r = decay_rate*r + (1-decay_rate)*g**2
w += -learning_rate*g/(np.sqrt(r + delta))

这里的超参数衰减率decay_rate*r一般会设置为[0.9,0.99,0.999],具体视情况而定。

为了更直观的看几种算法在数据集上的表现,对每种算法进行可视化,如图所示:
这里写图片描述
按照收敛的速度来看,还是与Adadelta相似的算法,收敛速度更快。

如果开始迭代的点是鞍点呢?同样绘制一张相关的图:
这里写图片描述可以发现,梯度下降法在鞍点上徘徊了很长一段时间,才找到正确的迭代方向,而RMSProp则很快就找到了下降的方向了,进一步说明该算法的实用性。

参考
Unit Tests for Stochastic Optimization
cs231n
deeplearning

2019-04-09 14:08:08 weixin_41665360 阅读数 358

1、梯度下降

梯度下降有许多变体,它们在用于计算目标函数梯度的数据量上存在差别。


1.1、Batch 梯度下降

BatchBatch 梯度下降计算整个训练集的成本函数相对参数 θθ 的梯度
θt+1=θtηθJ(θt)(1)\theta^{t+1}=\theta^t-\eta \cdot \nabla_{\theta} J(\theta^t)\tag1
由于每执行一次参数更新,需要计算整个数据集的梯度,所以 BatchBatch 梯度下降速度非常慢,而且在数据集很大的情况下会占用很多内存。当添加新样本时,该方法不适合在线更新模型
但是,BatchBatch 梯度下降能够保证收敛到凸误差曲面的全局最小值,和非凸曲面的局部极小值


1.2、随机梯度下降(SGD)

随机梯度下降为每个训练样本(xix_i)和标签(yiy_i)执行参数更新。
θt+1=θtηθJ(θt;xi;yi)(2)\theta^{t+1}=\theta^t-\eta \cdot \nabla_{\theta} J\left(\theta^t ; x_i ; y_i\right)\tag2
BatchBatch 梯度下降对大数据集执行冗余计算,因为它在每个参数更新前重新计算相似样本梯度。SGDSGD 一次只执行一个样本上的更新来消除这种冗余。因此它通常更快,而且可以用于在线学习SGDSGD 以很大的方差执行频繁的更新,导致目标函数剧烈波动,如图 11
在这里插入图片描述
BatchBatch 梯度下降能够将参数更新到极小值。SGDSGD 的波动性一方面使它能够跳转到新的、可能更好的局部极小值,另一方面,这使收敛到精确的最小值变得复杂,因为 SGDSGD 会在最小值附近振荡。但是,当缓慢减小学习率时,SGDSGD 表现出与 BatchBatch 梯度下降相同的收敛性,几乎确定收敛到非凸优化的局部最小值和凸优化的全局最小值。


1.3、Mini-batch 梯度下降

MinibatchMini-batch 梯度下降对两种方法进行折中,实现了最佳效果,并为每一个 minibatchmini-batchnn 个样本执行一次更新。
θt+1=θtηθJ(θt;x(i:i+n);y(i:i+n))(3)\theta^{t+1}=\theta^t-\eta \cdot \nabla_{\theta} J\left(\theta^t ; x_{(i : i+n)} ; y_{(i : i+n)}\right)\tag3
这种方法可以:

  1. 减小参数更新的方差,使收敛过程更稳定
  2. 利用常见的深度学习库的高度优化的矩阵计算方法,高效计算 minibatchmini-batch 梯度

训练神经网络时,通常采用 minibatchmini-batch 梯度下降算法,但是使用 SGDSGD 这一术语。然而,普通的 minibatchmini-batch 梯度下降不能保证好的收敛性,而且有以下问题需要解决:

  1. 选择合适的学习率很困难。学习率太小会导致收敛速度过慢,学习率太大会阻碍收敛,导致损失函数在最小值附近波动,甚至发散
  2. 学习率 schedulesschedules 尝试调整训练时的学习率,比如退火,即根据预定义的 schedulesschedules 或者当迭代之间的目标变化低于某一阈值时,减小学习率。但是,schedulesschedules 或者阈值必须预定义,因此无法适应数据集特征
  3. 所有参数更新使用相同学习率。如果数据是稀疏的,而且特征频率差异较大,那么我们不想同等程度更新所有参数,而是对较少出现的特征执行更大的更新
  4. 最小化高度非凸误差函数的另一个关键挑战是避免陷入许多次优局部极小DauphinDauphin 等人认为,造成这一困难的原因不是局部极小值,而是鞍点,即在一个维度上坡度增加,另一维度上坡度减小。SGDSGD 在这些鞍点处很难逃脱,因为在所有维度上的梯度都接近于 00

2、梯度下降优化算法

2.1、Momentum

SGDSGD 很难摆脱沟壑,即曲面的曲线在一个维度比另一维度更平稳,这通常是在局部最优附近。在这些场景下,SGDSGD 在峡谷的斜坡上振荡,沿着底部向局部最优方向前进的过程中徘徊不前,如图 2a2a 所示。
在这里插入图片描述
MomentumMomentum 有助于加速相关方向的梯度下降,并抑制振荡,如图 2b2b 所示。它通过将之前的更新向量的 γ\gamma 倍加到当前更新向量来实现这一点。
vt=γvt1+ηθJ(θt)θt+1=θtvt(4) \begin{aligned} v^{t} &=\gamma v^{t-1}+\eta \nabla_{\theta} J(\theta^t) \\ \theta^{t+1} &=\theta^t-v^t \end{aligned}\tag4
动量项 γ\gamma 通常设为 0.90.9
对于梯度指向相同方向的维度 momentummomentum 项增加,对于梯度方向改变的维度,减少更新。这样就能实现更快地收敛,并减少震荡。


2.2、Nesterov 加速梯度

NAGNAG 是一种给出预见性动量项的方法。由于已知使用动量项 γvt1\gamma v^{t-1} 来更新参数,因此计算 θtγvt1\theta^t-\gamma v^{t-1} 给出了参数下一个位置的近似。这样做的好处是算法可以提前知道梯度方向发生改变,并相应地减小更新步长,从而加速收敛
vt=γvt1+ηθJ(θtγvt1)θt+1=θtvt(5) \begin{aligned} v^{t} &=\gamma v^{t-1}+\eta \nabla_{\theta} J\left(\theta^t-\gamma v^{t-1}\right) \\ \theta^{t+1} &=\theta^t-v^{t} \end{aligned}\tag5
γ\gamma 设为 0.90.9MomentumMomentum 首先计算当前梯度(图 33 小蓝色向量)然后在更新的累积梯度方向上前进一大步(大蓝色向量),NAGNAG 首先在之前累积的梯度方向进行大的跳跃(棕色向量),测量梯度然后进行校正(绿色向量)。这一预见性更新防止了参数更新过快并提升了响应能力,极大提升了 RNNRNN 在许多任务上的性能
在这里插入图片描述
既然能够根据误差函数调整更新并相应加快 SGDSGD 速度,我们也希望根据每个参数的重要性来决定更新参数的程度。

KerasKeras 中调用相关优化器方法

keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)
"""
: lr: 学习率 >= 0的浮点数
: momentum: >= 0的浮点数,在相关方向加速 SGD 并抑制震荡
: decay:  >= 0的浮点数,学习率随着更新过程衰减
: nesterov: 布尔值,是否应用 Nesterov 动量,一般用于 RNN
"""

2.3、Adagrad

AdagradAdagrad 是一种基于梯度的优化算法,它使学习率适应于参数,对低频参数执行更大的更新,对高频参数执行更小的更新。因此,它非常适合处理稀疏数据AdagradAdagrad 极大地提升了 SGDSGD 的鲁棒性。

过去,执行一次更新,每个参数使用相同的学习率 η\etaAdagradAdagrad 在每次更新时,不同的参数的学习率不同。单个参数 θi\theta_i 的更新如下:
git=θtJ(θit)(6)g_i^t=\nabla_{\theta^t} J\left(\theta_i^t\right)\tag6
θit+1=θitηGiit+ϵgit(7)\theta_i^{t+1}=\theta_i^{t}-\frac{\eta}{\sqrt{G_{i i}^t+\epsilon}} \cdot g_i^t\tag7
所有参数更新的矩阵形式为:
θ(t+1)=θ(t)η(Gt)1θtJ(θt)(8)\theta^{(t+1)}=\theta^{(t)}-\eta\left(G^{t}\right)^{-1}\odot\nabla_{\theta^t} J\left(\theta^t\right)\tag8
其中:
Gt=[τ=1tg1τ+ϵ000τ=1tg2τ+ϵ000τ=1tgdτ+ϵ]G^t=\left[\begin{matrix}\sqrt{\sum\limits_{\tau=1}^tg_1^{\tau}+\epsilon}&0&\cdots&0\\0&\sqrt{\sum\limits_{\tau=1}^tg_2^{\tau}+\epsilon}&\cdots&0\\\vdots&\vdots&\ddots&\vdots\\0&0&\cdots&\sqrt{\sum\limits_{\tau=1}^tg_d^{\tau}+\epsilon}\end{matrix}\right]
GtG^t 是一个对角矩阵,每一个对角线元素为该位置对应参数的前 tt 次更新中梯度的平方和ϵ\epsilon 为平滑参数,避免分母为 00(通常为 1e81e-8)。有趣的是,如果没有平方根运算,该算法效果更差

AdagradAdagrad 主要的优点是它不需要手动调整学习率,通常使用默认值 0.010.01

AdagradAdagrad 主要的缺点是,它在分母中积累了平方梯度:由于增加的每一项都是正的,训练过程中累计和不断增加。这相应地导致学习率减小,最终趋于无穷小,此时算法难以继续学习

KerasKeras 调用优化器方法:

keras.optimizers.Adagrad(lr=0.01, epsilon=1e-06)
"""
lr:大于0的浮点数,学习率
epsilon:大于0的小浮点数,防止除0错误
"""

2.4、Adadelta

AdadeltaAdadeltaAdagradAdagrad 的延伸。取代累加之前所有梯度平方,AdadeltaAdadelta 累加之前固定范围 ww 内的梯度。

梯度和被递归地定义为所有过去平方梯度衰减的平均值,而不是无效地存储 ww 个先前的平方梯度。在时间步 tt 时运行平均 E[g2]tE[g^2]_t,仅依赖于过去的均值和当前的梯度。:
E[g2]t=γE[g2]t1+(1γ)gt2(10)E\left[g^{2}\right]_{t}=\gamma E\left[g^{2}\right]_{t-1}+(1-\gamma) g_{t}^{2}\tag{10}
γ\gamma 设为与动量项类似的值,约为 0.90.9。为清晰起见,根据参数更新向量 Δθt\Delta\theta_t 重写 SGDSGD 更新。
Δθt=ηgt,iθt+1=θt+Δθt(11) \begin{aligned} \Delta \theta_{t} &=-\eta \cdot g_{t, i} \\ \theta_{t+1} &=\theta_{t}+\Delta \theta_{t} \end{aligned}\tag{11}
AdagradAdagrad 的参数更新向量表示为:
Δθt=ηGt+ϵgt(12)\Delta \theta_{t}=-\frac{\eta}{\sqrt{G_{t}+\epsilon}} \odot g_{t}\tag{12}
现在只需要将对角矩阵 GtG_t 替换为过去平方梯度衰减的平均值
Δθt=ηE[g2]t+ϵgt(13)\Delta \theta_{t}=-\frac{\eta}{\sqrt{E\left[g^{2}\right]_{t}+\epsilon}} g_{t}\tag{13}
由于分母只是梯度的均方根(RMSRMS)误差准则,可以用短期准则来代替它
Δθt=ηRMS[g]tgt(14)\Delta \theta_{t}=-\frac{\eta}{R M S[g]_{t}} g_{t}\tag{14}
作者指出,此更新中的单位(以及 SGDSGDMomentumMomentumAdagradAdagrad 中的单位)不匹配,即更新应该具有与参数相同的假设单位。为了实现这一点,他们首先定义了另一个指数衰减平均值,这次不是平方梯度,而是平方参数更新:
E[Δθ2]t=γE[Δθ2]t1+(1γ)Δθt2(15)E\left[\Delta \theta^{2}\right]_{t}=\gamma E\left[\Delta \theta^{2}\right]_{t-1}+(1-\gamma) \Delta \theta_{t}^{2}\tag{15}
因此,参数更新的均方误差为:
RMS[Δθ]t=E[Δθ2]t+ϵ(16)RMS[\Delta \theta]_{t}=\sqrt{E\left[\Delta \theta^{2}\right]_{t}+\epsilon}\tag{16}
由于 RMS[Δθ]tRMS[\Delta \theta]_{t} 未知,用直到前一步参数更新的 RMSRMS 逼近它。用 RMS[Δθ]t1RMS[\Delta \theta]_{t-1} 替换上一个更新规则中的学习率,最终得到 AdadeltaAdadelta 更新规则:
Δθt=RMS[Δθ]t1RMS[g]tgtθt+1=θt+Δθt(17) \begin{aligned} \Delta \theta_{t} &=-\frac{R M S[\Delta \theta]_{t-1}}{R M S[g]_{t}} g_{t} \\ \theta_{t+1} &=\theta_{t}+\Delta \theta_{t} \end{aligned}\tag{17}
使用 AdadeltaAdadelta,甚至不需要设置默认学习率,因为它已经被从更新规则中删除了。

KerasKeras 调用优化器方法:

keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-06)
"""
lr:大于0的浮点数,学习率
rho:大于0的浮点数
epsilon:大于0的小浮点数,防止除0错误
"""

2.5、RMSprop

RMSpropRMSprop 是一种自适应学习率方法。它与 AdadeltaAdadelta 均用于解决 AdagradAdagrad 学习率急剧下降的问题。事实上,RMSpropRMSpropAdadeltaAdadelta 的第一个更新向量相同。
E[g2]t=0.9E[g2]t1+0.1gt2θt+1=θtηE[g2]t+ϵgt(18) \begin{aligned} E\left[g^{2}\right]_{t} &=0.9 E\left[g^{2}\right]_{t-1}+0.1 g_{t}^{2} \\ \theta_{t+1} &=\theta_{t}-\frac{\eta}{\sqrt{E\left[g^{2}\right]_{t}+\epsilon}} g_{t} \end{aligned}\tag{18}
此外,RMSpropRMSprop 将学习率除以指数衰减的平方梯度的均值γ\gamma 最好设置为 0.90.9,学习率 η\eta 通常为 0.0010.001

KerasKeras 调用优化器方法:

keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-06)
"""
lr:大于0的浮点数,学习率
rho:大于0的浮点数
epsilon:大于0的小浮点数,防止除0错误
"""

2.6、Adam

Adaptive Moment Estimation(Adam)Adaptive~Moment~Estimation(Adam) 是另一种计算每个参数自适应学习率的方法。除了存储指数衰减的平方梯度均值 vtv_t,它还保留了类似于 momentummomentum 的,指数衰减的梯度均值 mtm_t
mt=β1mt1+(1β1)gtvt=β2vt1+(1β2)gt2(19) \begin{aligned} m_{t} &=\beta_{1} m_{t-1}+\left(1-\beta_{1}\right) g_{t} \\ v_{t} &=\beta_{2} v_{t-1}+\left(1-\beta_{2}\right) g_{t}^{2} \end{aligned}\tag{19}
mtm_tvtv_t 分别为梯度的一阶矩(均值)和二阶矩估计,这是该方法名字的由来。当 mtm_tvtv_t 被初始化为零向量时,在初始时间步,它们都偏向于 00,特别当衰变率很小时更是如此(即,β1\beta_1β2\beta_2 接近于 11)。

通过计算一阶矩和二阶矩估计偏差修正来抵消偏差。
m^t=mt1β1tv^t=vt1β2t(20)\begin{aligned} \hat{m}_{t} &=\frac{m_{t}}{1-\beta_{1}^{t}} \\ \hat{v}_{t} &=\frac{v_{t}}{1-\beta_{2}^{t}} \end{aligned}\tag{20}
AdamAdam 更新规则如下:
θt+1=θtηv^t+ϵm^t(21)\theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat{v}_{t}}+\epsilon} \hat{m}_{t}\tag{21}
β1\beta_1 默认为 0.90.9β2\beta_2 默认为 0.9990.999ϵ\epsilon 默认为 10810^{-8}。实验表明,相比于其他自适应算法,AdamAdam 效果更好。

KerasKeras 调用优化器方法:

keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
"""
lr:大于0的浮点数,学习率
beta_1/beta_2:浮点数, 0<beta<1,通常很接近1
epsilon:大于0的小浮点数,防止除0错误
"""

2.7、AdaMax

AdamAdam 中的 vtv_t 因子反向缩放之前梯度的 2\ell_2 范数和当前梯度 gt2|g_t|^2
vt=β2vt1+(1β2)gt2(22)v_{t}=\beta_{2} v_{t-1}+\left(1-\beta_{2}\right)\left|g_{t}\right|^{2}\tag{22}
这里将其改为 p\ell_p 范数,同时 β2\beta_2 变为 β2p\beta_2^p
vt=β2pvt1+(1β2p)gtp(23)v_{t}=\beta_{2}^{p} v_{t-1}+\left(1-\beta_{2}^{p}\right)\left|g_{t}\right|^{p}\tag{23}
pp 值范数通常在数值上不稳定,因此实践中 1\ell_12\ell_2 范数比较常见。然而,\ell_{\infty} 通常表现更稳定。因此作者提出了 AdaMaxAdaMax,并证明了具有 \ell_{\infty}vtv_t 收敛到更稳定的值。为避免与 adamadam 混淆,这里使用 utu_t 表示受无穷范数约束的 vtv_t
ut=β2vt1+(1β2)gt=max(β2vt1,gt)(24) \begin{aligned} u_{t} &=\beta_{2}^{\infty} v_{t-1}+\left(1-\beta_{2}^{\infty}\right)\left|g_{t}\right|^{\infty} \\ &=\max \left(\beta_{2} \cdot v_{t-1},\left|g_{t}\right|\right) \end{aligned}\tag{24}
通过将 v^t+ϵ\sqrt{\hat{v}_{t}}+\epsilon 替换为 utu_t 来获取 AdamAdam 更新规则:
θt+1=θtηutm^t(25) \theta_{t+1}=\theta_{t}-\frac{\eta}{u_{t}} \hat{m}_{t}\tag{25}
由于 utu_t 依赖于 maxmax 运算,所以不像 AdamAdam 中的 mtm_tvtv_t 容易偏向于 00,因此不需要计算 utu_t 的校正。默认值:η=0.002,β1=0.9,\eta=0.002, \beta_{1}=0.9, β2=0.999\beta_{2}=0.999

KerasKeras 调用优化器方法:

keras.optimizers.Adamax(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
"""
lr:大于0的浮点数,学习率
beta_1/beta_2:浮点数, 0<beta<1,通常很接近1
epsilon:大于0的小浮点数,防止除0错误
"""

2.8、Nadam

AdamAdam 可以看作 RMSpropRMSpropmomentummomentum 的结合RMSpropRMSprop 贡献指数衰减的之前梯度平方的均值 vtv_tmomentummomentum 计算指数衰减的之前梯度的均值 mtm_tNesterovNesterov 加速梯度优于普通的 momentummomentum

Nadam(Nesterovaccelerated Adaptive Moment Estimation)Nadam(Nesterov-accelerated~Adaptive~Moment~Estimation)AdamAdamNAGNAG 结合起来。为了将 NAGNAG 结合到 AdamAdam 需要修改动量项 mtm_t

当前动量更新规则为:
gt=θtJ(θt)mt=γmt1+ηgtθt+1=θtmt(26) \begin{aligned} g_{t} &=\nabla_{\theta_{t}} J\left(\theta_{t}\right) \\ m_{t} &=\gamma m_{t-1}+\eta g_{t} \\ \theta_{t+1} &=\theta_{t}-m_{t} \end{aligned}\tag{26}
将第二式带入第三式:
θt+1=θt(γmt1+ηgt)(27)\theta_{t+1}=\theta_{t}-\left(\gamma m_{t-1}+\eta g_{t}\right)\tag{27}
NAGNAG 在计算梯度之前,使用动量步长更新参数,从而实现更精确的参数更新。
gt=θtJ(θtγmt1)mt=γmt1+ηgtθt+1=θtmt(28)\begin{aligned} g_{t} &=\nabla_{\theta_{t}} J\left(\theta_{t}-\gamma m_{t-1}\right) \\ m_{t} &=\gamma m_{t-1}+\eta g_{t} \\ \theta_{t+1} &=\theta_{t}-m_{t} \end{aligned}\tag{28}
DozatDozat 提出修改 NAGNAG:不再使用两次动量—一次用于更新梯度,另一次用于更新参数。直接使用前瞻性动量向量更新当前参数。
gt=θtJ(θt)mt=γmt1+ηgtθt+1=θt(γmt+ηgt)(29)\begin{aligned} g_{t} &=\nabla_{\theta_{t}} J\left(\theta_{t}\right) \\ m_{t} &=\gamma m_{t-1}+\eta g_{t} \\ \theta_{t+1} &=\theta_{t}-\left(\gamma m_{t}+\eta g_{t}\right) \end{aligned}\tag{29}
注意与 2727 的区别。为了给 AdamAdam 增加 NesterovNesterov 动量,使用当前动量向量代替之前的动量向量。AdamAdam 更新规则如下:
mt=β1mt1+(1β1)gtm^t=mt1β1tθt+1=θtηv^t+ϵm^t(30)\begin{aligned} m_{t} &=\beta_{1} m_{t-1}+\left(1-\beta_{1}\right) g_{t} \\ \hat{m}_{t} &=\frac{m_{t}}{1-\beta_{1}^{t}} \\ \theta_{t+1} &=\theta_{t}-\frac{\eta}{\sqrt{\hat{v}_{t}}+\epsilon} \hat{m}_{t} \end{aligned}\tag{30}
将前两式代入第三式得:
θt+1=θtηv^t+ϵ(β1mt11β1t+(1β1)gt1β1t)(31)\theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat{v}_{t}}+\epsilon}\left(\frac{\beta_{1} m_{t-1}}{1-\beta_{1}^{t}}+\frac{\left(1-\beta_{1}\right) g_{t}}{1-\beta_{1}^{t}}\right)\tag{31}
由于 β1mt11β1t\frac{\beta_{1} m_{t-1}}{1-\beta_{1}^{t}} 是上一步动量向量的偏移修正项,可以将它用 m^t1\hat{m}_{t-1} 替代:
θt+1=θtηv^t+ϵ(β1m^t1+(1β1)gt1β1t)(32)\theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat{v}_{t}}+\epsilon}\left(\beta_{1} \hat{m}_{t-1}+\frac{\left(1-\beta_{1}\right) g_{t}}{1-\beta_{1}^{t}}\right)\tag{32}
看起来和等式 2727 类似,我们将仿照等式 2929 的做法添加 NesterovNesterov 动量。将上一步动量向量的偏移估计 m^t1\hat{m}_{t-1} 用当前动量向量的偏移估计替代:
θt+1=θtηv^t+ϵ(β1m^t+(1β1)gt1β1t)(33)\theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat{v}_{t}}+\epsilon}\left(\beta_{1} \hat{m}_{t}+\frac{\left(1-\beta_{1}\right) g_{t}}{1-\beta_{1}^{t}}\right)\tag{33}

KerasKeras 调用优化器方法:

keras.optimizers.Nadam(lr=0.002, beta_1=0.9, beta_2=0.999, 
						epsilon=1e-08, schedule_decay=0.004)
"""
lr:大于0的浮点数,学习率
beta_1/beta_2:浮点数, 0<beta<1,通常很接近1
epsilon:大于0的小浮点数,防止除0错误
"""


2.9、各优化方法收敛速度的比较

从网上找到两张图,可以清晰对各种优化方法进行比较
在这里插入图片描述
在这里插入图片描述

2.10、如何选择优化方法

  1. 如果数据是稀疏的,就选择自适应学习率方法。还可以省去调节学习率的麻烦
  2. RMSpropRMSpropAdagradAdagrad 的扩展,解决学习率急剧消失的问题
  3. AdadeltaAdadeltaRMSpropRMSprop 相同,只不过在更新规则的分子上使用了参数更新均方根
  4. AdamAdamRMSpropRMSprop 的基础上使用了偏移校正和动量
  5. RMSpropRMSpropAdadeltaAdadeltaAdamAdam 是相似的算法,在类似的情况的下做的很好。优化快要结束时,梯度变得越来越稀疏,偏移校正使 AdamAdam 略微超过 RMSpropRMSprop目前来说,AdamAdam 可能是整体优化的最佳选择
  6. 训练较深较复杂的网络时,推荐使用学习率自适应的优化方法。

3、参考

An overview of gradient descent optimization
algorithms

不支持复制粘贴公式,很无奈。

博文 来自: qq_29133371
没有更多推荐了,返回首页