参考《动手学深度学习》 https://zh.d2l.ai/chapter_optimization/index.html

一维梯度下降

我们先以简单的一维梯度下降为例,解释梯度下降算法可能降低目标函数值的原因。假设连续可导的函数 f:R→R 的输入和输出都是标量。给定绝对值足够小的数 ϵ ,根据泰勒展开公式,我们得到以下的近似:

f(x+ϵ)≈f(x)+ϵf′(x).

这里 f′(x) 是函数 f 在 x 处的梯度。一维函数的梯度是一个标量,也称导数。

接下来,找到一个常数 η>0 ,使得 |ηf′(x)| 足够小,那么可以将 ϵ 替换为 −ηf′(x) 并得到

f(x−ηf′(x))≈f(x)−ηf′(x)2.

如果导数 f′(x)≠0 ,那么 ηf′(x)2>0 ,所以

f(x−ηf′(x))≲f(x).

这意味着,如果通过

x←x−ηf′(x)

来迭代 x ,函数 f(x) 的值可能会降低。因此在梯度下降中,我们先选取一个初始值 x 和常数 η>0 ,然后不断通过上式来迭代 x ,直到达到停止条件,例如 f′(x)2 的值已足够小或迭代次数已达到某个值。

多维梯度下降

在了解了一维梯度下降之后,我们再考虑一种更广义的情况:目标函数的输入为向量,输出为标量。假设目标函数 f:Rd→R 的输入是一个 d 维向量 x=[x1,x2,…,xd]⊤ 。目标函数 f(x) 有关 x 的梯度是一个由 d 个偏导数组成的向量:

∇xf(x)=[∂f(x)∂x1,∂f(x)∂x2,…,∂f(x)∂xd]⊤.

为表示简洁,我们用 ∇f(x) 代替 ∇xf(x) 。梯度中每个偏导数元素 ∂f(x)/∂xi 代表着 f 在 x 有关输入 xi 的变化率。为了测量 f 沿着单位向量 u (即 ∥u∥=1 )方向上的变化率,在多元微积分中,我们定义 f 在 x 上沿着 u 方向的方向导数为

Duf(x)=limh→0f(x+hu)−f(x)h.

依据方向导数性质 [1,14.6节定理三],以上方向导数可以改写为

Duf(x)=∇f(x)⋅u.

方向导数 Duf(x) 给出了 f 在 x 上沿着所有可能方向的变化率。为了最小化 f ,我们希望找到 f 能被降低最快的方向。因此,我们可以通过单位向量 u 来最小化方向导数 Duf(x) 。

由于 Duf(x)=∥∇f(x)∥⋅∥u∥⋅cos(θ)=∥∇f(x)∥⋅cos(θ) , 其中 θ 为梯度 ∇f(x) 和单位向量 u 之间的夹角,当 θ=π 时, cos(θ) 取得最小值 −1 。因此,当 u 在梯度方向 ∇f(x) 的相反方向时,方向导数 Duf(x) 被最小化。因此,我们可能通过梯度下降算法来不断降低目标函数 f 的值:

x←x−η∇f(x).

同样,其中 η (取正数)称作学习率。

随机梯度下降

在深度学习里,目标函数通常是训练数据集中有关各个样本的损失函数的平均。设 fi(x) 是有关索引为 i 的训练数据样本的损失函数, n 是训练数据样本数, x 是模型的参数向量,那么目标函数定义为

f(x)=1n∑i=1nfi(x).

目标函数在 x 处的梯度计算为

∇f(x)=1n∑i=1n∇fi(x).

如果使用梯度下降,每次自变量迭代的计算开销为 O(n) ,它随着 n 线性增长。因此,当训练数据样本数很大时,梯度下降每次迭代的计算开销很高。

随机梯度下降(stochastic gradient descent,SGD)减少了每次迭代的计算开销。在随机梯度下降的每次迭代中,我们随机均匀采样的一个样本索引 i∈{1,…,n} ,并计算梯度 ∇fi(x) 来迭代 x :

x←x−η∇fi(x).

这里 η 同样是学习率。可以看到,每次迭代的计算开销从梯度下降的 O(n) 降到了常数 O(1) 。值得强调的是,随机梯度 ∇fi(x) 是对梯度 ∇f(x) 的无偏估计:

Ei∇fi(x)=1n∑i=1n∇fi(x)=∇f(x).

这意味着,平均来说,随机梯度是对梯度的一个良好的估计。

小批量随机梯度下降

在每一次迭代中,梯度下降使用整个训练数据集来计算梯度,因此它有时也被称为批量梯度下降(batch gradient descent)。而随机梯度下降在每次迭代中只随机采样一个样本来计算梯度。正如我们在前几章中所看到的,我们还可以在每轮迭代中随机均匀采样多个样本来组成一个小批量,然后使用这个小批量来计算梯度。下面就来描述小批量随机梯度下降。

设目标函数 f(x):Rd→R 。在迭代开始前的时间步设为0。该时间步的自变量记为 x0∈Rd ,通常由随机初始化得到。在接下来的每一个时间步 t>0 中,小批量随机梯度下降随机均匀采样一个由训练数据样本索引组成的小批量 Bt 。我们可以通过重复采样(sampling with replacement)或者不重复采样(sampling without replacement)得到一个小批量中的各个样本。前者允许同一个小批量中出现重复的样本,后者则不允许如此,且更常见。对于这两者间的任一种方式,都可以使用

gt←∇fBt(xt−1)=1|B|∑i∈Bt∇fi(xt−1)

来计算时间步 t 的小批量 Bt 上目标函数位于 xt−1 处的梯度 gt 。这里 |B| 代表批量大小,即小批量中样本的个数,是一个超参数。同随机梯度一样,重复采样所得的小批量随机梯度 gt 也是对梯度 ∇f(xt−1) 的无偏估计。给定学习率 ηt (取正数),小批量随机梯度下降对自变量的迭代如下:

xt←xt−1−ηtgt.

基于随机采样得到的梯度的方差在迭代过程中无法减小,因此在实际中,(小批量)随机梯度下降的学习率可以在迭代过程中自我衰减,例如 ηt=ηtα (通常 α=−1 或者 −0.5 )、 ηt=ηαt (如 α=0.95 )或者每迭代若干次后将学习率衰减一次。如此一来,学习率和(小批量)随机梯度乘积的方差会减小。而梯度下降在迭代过程中一直使用目标函数的真实梯度,无须自我衰减学习率。

小批量随机梯度下降中每次迭代的计算开销为 O(|B|) 。当批量大小为1时,该算法即随机梯度下降;当批量大小等于训练数据样本数时,该算法即梯度下降。当批量较小时,每次迭代中使用的样本少,这会导致并行处理和内存使用效率变低。这使得在计算同样数目样本的情况下比使用更大批量时所花时间更多。当批量较大时,每个小批量梯度里可能含有更多的冗余信息。为了得到较好的解,批量较大时比批量较小时需要计算的样本数目可能更多,例如增大迭代周期数。

动量法

动量法的提出是为了解决梯度下降的上述问题。由于小批量随机梯度下降比梯度下降更为广义。设时间步 t 的自变量为 xt ,学习率为 ηt 。 在时间步 0 ,动量法创建速度变量 v0 ,并将其元素初始化成0。在时间步 t>0 ,动量法对每次迭代的步骤做如下修改:

vtxt←γvt−1+ηtgt,←xt−1−vt,

其中,动量超参数 γ 满足 0≤γ<1 。当 γ=0 时,动量法等价于小批量随机梯度下降。

指数加权移动平均
为了从数学上理解动量法,让我们先解释一下指数加权移动平均(exponentially weighted moving average)。给定超参数 0≤γ<1 ,当前时间步 t 的变量 yt 是上一时间步 t−1 的变量 yt−1 和当前时间步另一变量 xt 的线性组合:

yt=γyt−1+(1−γ)xt.

我们可以对 yt 展开:

yt=(1−γ)xt+γyt−1=(1−γ)xt+(1−γ)⋅γxt−1+γ2yt−2=(1−γ)xt+(1−γ)⋅γxt−1+(1−γ)⋅γ2xt−2+γ3yt−3…

令 n=1/(1−γ) ,那么 (1−1/n)n=γ1/(1−γ) 。因为

limn→∞(1−1n)n=exp(−1)≈0.3679,

所以当 γ→1 时, γ1/(1−γ)=exp(−1) ,如 0.9520≈exp(−1) 。如果把 exp(−1) 当作一个比较小的数,我们可以在近似中忽略所有含 γ1/(1−γ) 和比 γ1/(1−γ) 更高阶的系数的项。例如,当 γ=0.95 时,

yt≈0.05∑i=0190.95ixt−i.

因此,在实际中,我们常常将 yt 看作是对最近 1/(1−γ) 个时间步的 xt 值的加权平均。例如,当 γ=0.95 时, yt 可以被看作对最近20个时间步的 xt 值的加权平均;当 γ=0.9 时, yt 可以看作是对最近10个时间步的 xt 值的加权平均。而且,离当前时间步 t 越近的 xt 值获得的权重越大(越接近1)。

由指数加权移动平均理解动量法
现在,我们对动量法的速度变量做变形:

vt←γvt−1+(1−γ)(ηt1−γgt).

由指数加权移动平均的形式可得,速度变量 vt 实际上对序列 {ηt−igt−i/(1−γ):i=0,…,1/(1−γ)−1} 做了指数加权移动平均。换句话说,相比于小批量随机梯度下降,动量法在每个时间步的自变量更新量近似于将前者对应的最近 1/(1−γ) 个时间步的更新量做了指数加权移动平均后再除以 1−γ 。所以,在动量法中,自变量在各个方向上的移动幅度不仅取决于当前梯度,还取决于过去的各个梯度在各个方向上是否一致。在本节之前示例的优化问题中,所有梯度在水平方向上为正(向右),而在竖直方向上时正(向上)时负(向下)。这样,我们就可以使用较大的学习率,从而使自变量向最优解更快移动。

AdaGrad算法

在之前介绍过的优化算法中,目标函数自变量的每一个元素在相同时间步都使用同一个学习率来自我迭代。举个例子,假设目标函数为 f ,自变量为一个二维向量 [x1,x2]⊤ ,该向量中每一个元素在迭代时都使用相同的学习率。例如,在学习率为 η 的梯度下降中,元素 x1 和 x2 都使用相同的学习率 η 来自我迭代:

x1←x1−η∂f∂x1,x2←x2−η∂f∂x2.

在“动量法”里我们看到,当 x1 和 x2 的梯度值有较大差别时,需要选择足够小的学习率使得自变量在梯度值较大的维度上不发散。但这样会导致自变量在梯度值较小的维度上迭代过慢。动量法依赖指数加权移动平均使得自变量的更新方向更加一致,从而降低发散的可能。本节我们介绍AdaGrad算法,它根据自变量在每个维度的梯度值的大小来调整各个维度上的学习率,从而避免统一的学习率难以适应所有维度的问题 。

算法
AdaGrad算法会使用一个小批量随机梯度 gt 按元素平方的累加变量 st 。在时间步0,AdaGrad将 s0 中每个元素初始化为0。在时间步 t ,首先将小批量随机梯度 gt 按元素平方后累加到变量 st :

st←st−1+gt⊙gt,

其中 ⊙ 是按元素相乘。接着,我们将目标函数自变量中每个元素的学习率通过按元素运算重新调整一下:

xt←xt−1−ηst+ϵ−−−−−√⊙gt,

其中 η 是学习率, ϵ 是为了维持数值稳定性而添加的常数,如 10−6 。这里开方、除法和乘法的运算都是按元素运算的。这些按元素运算使得目标函数自变量中每个元素都分别拥有自己的学习率。

特点
需要强调的是,小批量随机梯度按元素平方的累加变量 st 出现在学习率的分母项中。因此,如果目标函数有关自变量中某个元素的偏导数一直都较大,那么该元素的学习率将下降较快;反之,如果目标函数有关自变量中某个元素的偏导数一直都较小,那么该元素的学习率将下降较慢。然而,由于 st 一直在累加按元素平方的梯度,自变量中每个元素的学习率在迭代过程中一直在降低(或不变)。所以,当学习率在迭代早期降得较快且当前解依然不佳时,AdaGrad算法在迭代后期由于学习率过小,可能较难找到一个有用的解。

RMSProp算法

我们在“AdaGrad算法”一节中提到,因为调整学习率时分母上的变量 st 一直在累加按元素平方的小批量随机梯度,所以目标函数自变量每个元素的学习率在迭代过程中一直在降低(或不变)。因此,当学习率在迭代早期降得较快且当前解依然不佳时,AdaGrad算法在迭代后期由于学习率过小,可能较难找到一个有用的解。为了解决这一问题,RMSProp算法对AdaGrad算法做了一点小小的修改。该算法源自Coursera上的一门课,即“机器学习的神经网络” 。

算法
我们在“动量法”一节里介绍过指数加权移动平均。不同于AdaGrad算法里状态变量 st 是截至时间步 t 所有小批量随机梯度 gt 按元素平方和,RMSProp算法将这些梯度按元素平方做指数加权移动平均。具体来说,给定超参数 0≤γ<1 ,RMSProp算法在时间步 t>0 计算

st←γst−1+(1−γ)gt⊙gt.

和AdaGrad算法一样,RMSProp算法将目标函数自变量中每个元素的学习率通过按元素运算重新调整,然后更新自变量

xt←xt−1−ηst+ϵ−−−−−√⊙gt,

其中 η 是学习率, ϵ 是为了维持数值稳定性而添加的常数,如 10−6 。因为RMSProp算法的状态变量 st 是对平方项 gt⊙gt 的指数加权移动平均,所以可以看作最近 1/(1−γ) 个时间步的小批量随机梯度平方项的加权平均。如此一来,自变量每个元素的学习率在迭代过程中就不再一直降低(或不变)。

照例,让我们先观察RMSProp算法对目标函数 f(x)=0.1x21+2x22 中自变量的迭代轨迹。回忆在“AdaGrad算法”一节使用的学习率为0.4的AdaGrad算法,自变量在迭代后期的移动幅度较小。但在同样的学习率下,RMSProp算法可以更快逼近最优解。

AdaDelta算法

除了RMSProp算法以外,另一个常用优化算法AdaDelta算法也针对AdaGrad算法在迭代后期可能较难找到有用解的问题做了改进 。有意思的是,AdaDelta算法没有学习率这一超参数。

算法
AdaDelta算法也像RMSProp算法一样,使用了小批量随机梯度 gt 按元素平方的指数加权移动平均变量 st 。在时间步0,它的所有元素被初始化为0。给定超参数 0≤ρ<1 (对应RMSProp算法中的 γ ),在时间步 t>0 ,同RMSProp算法一样计算

st←ρst−1+(1−ρ)gt⊙gt.

与RMSProp算法不同的是,AdaDelta算法还维护一个额外的状态变量 Δxt ,其元素同样在时间步0时被初始化为0。我们使用 Δxt−1 来计算自变量的变化量:

g′t←Δxt−1+ϵst+ϵ−−−−−−−−−√⊙gt,

其中 ϵ 是为了维持数值稳定性而添加的常数,如 10−5 。接着更新自变量:

xt←xt−1−g′t.

最后,我们使用 Δxt 来记录自变量变化量 g′t 按元素平方的指数加权移动平均:

Δxt←ρΔxt−1+(1−ρ)g′t⊙g′t.

可以看到,如不考虑 ϵ 的影响,AdaDelta算法与RMSProp算法的不同之处在于使用 Δxt−1−−−−−√ 来替代超参数 η 。

Adam算法

Adam算法在RMSProp算法基础上对小批量随机梯度也做了指数加权移动平均 。下面我们来介绍这个算法。

算法
Adam算法使用了动量变量 vt 和RMSProp算法中小批量随机梯度按元素平方的指数加权移动平均变量 st ,并在时间步0将它们中每个元素初始化为0。给定超参数 0≤β1<1 (算法作者建议设为0.9),时间步 t 的动量变量 vt 即小批量随机梯度 gt 的指数加权移动平均:

vt←β1vt−1+(1−β1)gt.

和RMSProp算法中一样,给定超参数 0≤β2<1 (算法作者建议设为0.999), 将小批量随机梯度按元素平方后的项 gt⊙gt 做指数加权移动平均得到 st :

st←β2st−1+(1−β2)gt⊙gt.

由于我们将 v0 和 s0 中的元素都初始化为0, 在时间步 t 我们得到 vt=(1−β1)∑ti=1βt−i1gi 。将过去各时间步小批量随机梯度的权值相加,得到 (1−β1)∑ti=1βt−i1=1−βt1 。需要注意的是,当 t 较小时,过去各时间步小批量随机梯度权值之和会较小。例如,当 β1=0.9 时, v1=0.1g1 。为了消除这样的影响,对于任意时间步 t ,我们可以将 vt 再除以 1−βt1 ,从而使过去各时间步小批量随机梯度权值之和为1。这也叫作偏差修正。在Adam算法中,我们对变量 vt 和 st 均作偏差修正:

v^t←vt1−βt1,

s^t←st1−βt2.

接下来,Adam算法使用以上偏差修正后的变量 v^t 和 s^t ,将模型参数中每个元素的学习率通过按元素运算重新调整:

g′t←ηvtst−−√+ϵ,

其中 η 是学习率, ϵ 是为了维持数值稳定性而添加的常数,如 10−8 。和AdaGrad算法、RMSProp算法以及AdaDelta算法一样,目标函数自变量中每个元素都分别拥有自己的学习率。最后,使用 g′t 迭代自变量:

xt←xt−1−g′t.

深度学习中常用的优化算法相关推荐

  1. 深度学习中常用的优化算法(SGD, Nesterov,Adagrad,RMSProp,Adam)总结

    深度学习中常用的优化算法(SGD, Nesterov,Adagrad,RMSProp,Adam)总结 1. 引言 在深度学习中我们定义了损失函数以后,会采取各种各样的方法来降低损失函数的数值,从而使模 ...

  2. 机器学习、深度学习中常用的优化算法详解——梯度下降法、牛顿法、共轭梯度法

    一.梯度下降法 1.总述: 在机器学习中,基于基本的梯度下降法发展了三种梯度下降方法,分别为随机梯度下降法,批量梯度下降法以及小批量梯度下降法. (1)批量梯度下降法(Batch Gradient D ...

  3. 深度学习中常用的Adam算法

    一.Adam算法 Adam(Adaptive momentum)是一种自适应动量的随机优化方法(A method for stochastic optimization),经常作为深度学习中的优化器算 ...

  4. 深度学习中的Adam优化算法详解

    Adam论文:https://arxiv.org/pdf/1412.6980.pdf (一).什么是Adam算法? Adam(Adaptive momentum)是一种自适应动量的随机优化方法(A m ...

  5. 深度学习中常用的优化方法

    一.basic algorithm 1. SGD 此处的SGD指mini-batch gradient descent,关于batch gradient descent, stochastic gra ...

  6. 深度学习中常用优化器算法Optimizer详解(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)

    本文转载自:https://www.cnblogs.com/guoyaohua/p/8542554.html 在机器学习.深度学习中使用的优化算法除了常见的梯度下降,还有 Adadelta,Adagr ...

  7. 【AI初识境】深度学习中常用的损失函数有哪些?

    这是专栏<AI初识境>的第11篇文章.所谓初识,就是对相关技术有基本了解,掌握了基本的使用方法. 今天来说说深度学习中常见的损失函数(loss),覆盖分类,回归任务以及生成对抗网络,有了目 ...

  8. Keras深度学习实战(4)——深度学习中常用激活函数和损失函数详解

    Keras深度学习实战(4)--深度学习中常用激活函数和损失函数详解 常用激活函数 Sigmoid 激活函数 Tanh 激活函数 ReLU 激活函数 线性激活函数 Softmax 激活函数 损失函数 ...

  9. DL之AF:机器学习/深度学习中常用的激活函数(sigmoid、softmax等)简介、应用、计算图实现、代码实现详细攻略

    DL之AF:机器学习/深度学习中常用的激活函数(sigmoid.softmax等)简介.应用.计算图实现.代码实现详细攻略 目录 激活函数(Activation functions)相关配图 各个激活 ...

最新文章

  1. 【异常】Error: ERROR 1012 (42M03): Table undefined. (state=42M03,code=1012)
  2. RxJava实现事件总线——RxBus
  3. chroot环境怎么重启linux,linux下简易chroot环境的塔建
  4. 顺序容器的访问:访问成员函数的返回是引用(和普通数组一样,普通数组的下标返回值也是数组)
  5. python中dict函数_dict()函数以及Python中的示例
  6. 玩转oracle 11g(45):关系数据库
  7. 漫话:为什么键盘以QWER排列,而不是ABCD?
  8. mysql cmd grep_通过 mysqlbinlog 和 grep 命令定位binlog文件中指定操作
  9. mysql nest loop伪代码_Nested Loop Join
  10. surfaceflinger类图
  11. Java读取URL到字符串
  12. highchart接收后台数据用法
  13. ACM常用算法及练习(2)
  14. 统计单词个数 状态机方法
  15. DotNET企业架构应用实践-数据库表记录的唯一性设计的设计兼议主键设定原则
  16. Java反射高频面试题(附答案),做了5年Java
  17. [从零开始学FPGA编程-4]:快速入门篇 - 操作步骤1 - 常见可编程器件PROM、PLA、PAL、GAL、CPLD、FPGA
  18. c语言输入角度求sin,从键盘输入一个角度x,求10sin(x)的值 c语音编程
  19. 小程序 获取地理位置
  20. 深度学习笔记----计算机视觉的任务及对应的网络模型

热门文章

  1. 国民技术产品系列与解决方案介绍
  2. Map的 entrySet() 方法详解及用法
  3. 流的定位tellg() / tellp()、seekg() / seekp()
  4. 数字图像处理基础概念
  5. pyqt5 显示摄像头画面
  6. Linux 添加IPv6策略路由,基于策略的路由通过IPv6配置示例
  7. OpenInventor实现三维模型的拖动
  8. 李昂 软件工程第一次作业
  9. 尚硅谷VUE项目-前端项目问题总结07--产品详情页【vuex-排他操作foreach-放大镜-轮播图-兄弟组件通信$bus-购物车-路由跳转传参-路由传参+会话存储】-游客身份-节流
  10. 【基础篇】JavaScript的4种代码调试输出方式