目标函数有关自变量的梯度代表了目标函数在自变量当前位置下降最快的方向。因此,梯度下降也叫作最陡下降(steepest descent)。在每次迭代中,梯度下降根据自变量当前位置,沿着当前位置的梯度更新自变量。然而,如果自变量的迭代方向仅仅取决于自变量当前位置,这可能会带来一些问题。
梯度下降法的弊端
如果同一位置上,目标函数在竖直方向( x 2 x_2 x2轴方向)比在水平方向( x 1 x_1 x1轴方向)的斜率的绝对值更大,在给定学习率的情况下,梯度下降迭代自变量时会使自变量在竖直方向比在水平方向移动幅度更大。那么,我们需要一个较小的学习率从而避免自变量在竖直方向上越过目标函数最优解。然而,这会造成自变量在水平方向上朝最优解移动变慢。然而如果试着将学习率调得稍大一点,自变量就会在在竖直方向不断越过最优解并逐渐发散。
动量法(Momentum)
动量法的提出是为了解决梯度下降的上述问题。设时间步
t
t
t的自变量为
x
t
\boldsymbol{x}_t
xt,学习率为
η
t
\eta_t
ηt。在时间步
0
0
0,动量法创建速度变量
v
0
\boldsymbol{v}_0
v0,并将其元素初始化成0。在时间步
t
>
0
t>0
t>0,动量法对每次迭代的步骤做如下修改:
v
t
←
γ
v
t
−
1
+
η
t
g
t
,
x
t
←
x
t
−
1
−
v
t
,
\begin{aligned} \boldsymbol{v}_t &\leftarrow \gamma \boldsymbol{v}_{t-1} + \eta_t \boldsymbol{g}_t, \\ \boldsymbol{x}_t &\leftarrow \boldsymbol{x}_{t-1} - \boldsymbol{v}_t, \end{aligned}
vtxt←γvt−1+ηtgt,←xt−1−vt,
其中,动量超参数
γ
\gamma
γ满足
0
≤
γ
<
1
0 \leq \gamma < 1
0≤γ<1。当
γ
=
0
\gamma=0
γ=0时,动量法等价于小批量随机梯度下降。
动量法的数学原理
指数加权平均
给定超参数 0 ≤ γ < 1 0 \leq \gamma < 1 0≤γ<1,当前时间步 t t t的变量 y t y_t yt是上一时间步 t − 1 t-1 t−1的变量 y t − 1 y_{t-1} yt−1和当前时间步另一变量 x t x_t xt的线性组合:
y
t
=
γ
y
t
−
1
+
(
1
−
γ
)
x
t
.
y_t = \gamma y_{t-1} + (1-\gamma) x_t.
yt=γyt−1+(1−γ)xt.
我们可以对
y
t
y_t
yt展开:
y t = ( 1 − γ ) x t + γ y t − 1 = ( 1 − γ ) x t + ( 1 − γ ) ⋅ γ x t − 1 + γ 2 y t − 2 = ( 1 − γ ) x t + ( 1 − γ ) ⋅ γ x t − 1 + ( 1 − γ ) ⋅ γ 2 x t − 2 + γ 3 y t − 3 = ( 1 − γ ) x t + ( 1 − γ ) ⋅ γ x t − 1 + ( 1 − γ ) ⋅ γ 2 x t − 2 + … + γ n y t − n ≈ ( 1 − γ ) ( x t + γ x t − 1 + γ 2 x t − 2 + … + γ n − 1 x t − n ) … \begin{aligned} y_t &= (1-\gamma) x_t + \gamma y_{t-1}\\ &= (1-\gamma)x_t + (1-\gamma) \cdot \gamma x_{t-1} + \gamma^2y_{t-2}\\ &= (1-\gamma)x_t + (1-\gamma) \cdot \gamma x_{t-1} + (1-\gamma) \cdot \gamma^2x_{t-2} + \gamma^3y_{t-3}\\ &= (1-\gamma)x_t + (1-\gamma) \cdot \gamma x_{t-1} + (1-\gamma) \cdot \gamma^2x_{t-2} + \ldots + \gamma^ny_{t-n}\\ &\approx (1-\gamma)(x_t + \gamma x_{t-1} + \gamma^2x_{t-2} + \ldots + \gamma^{n-1}x_{t-n})\\ &\ldots \end{aligned} yt=(1−γ)xt+γyt−1=(1−γ)xt+(1−γ)⋅γxt−1+γ2yt−2=(1−γ)xt+(1−γ)⋅γxt−1+(1−γ)⋅γ2xt−2+γ3yt−3=(1−γ)xt+(1−γ)⋅γxt−1+(1−γ)⋅γ2xt−2+…+γnyt−n≈(1−γ)(xt+γxt−1+γ2xt−2+…+γn−1xt−n)…
上式最后一步成立,由于 n → ∞ n \rightarrow \infty n→∞,因此可令 n = 1 / ( 1 − γ ) n = 1/(1-\gamma) n=1/(1−γ),当 γ → 1 \gamma \rightarrow 1 γ→1时, n → ∞ n \rightarrow \infty n→∞,则 γ n = γ 1 / ( 1 − γ ) = ( 1 − 1 / n ) n \gamma^n = \gamma^{1/(1-\gamma)} = \left(1-1/n\right)^n γn=γ1/(1−γ)=(1−1/n)n。因为
lim
n
→
∞
(
1
−
1
n
)
n
=
e
−
1
≈
0.3679
,
\lim_{n \rightarrow \infty} \left(1-\frac{1}{n}\right)^n = \boldsymbol{e}^{-1} \approx 0.3679,
n→∞lim(1−n1)n=e−1≈0.3679,
所以当
γ
→
1
\gamma \rightarrow 1
γ→1时,
γ
1
/
(
1
−
γ
)
=
e
−
1
\gamma^{1/(1-\gamma)}=\boldsymbol{e}^{-1}
γ1/(1−γ)=e−1,如
0.9
5
20
≈
e
−
1
0.95^{20} \approx \boldsymbol{e}^{-1}
0.9520≈e−1如果把
e
−
1
\boldsymbol{e}^{-1}
e−1当作一个比较小的数,我们可以在近似中忽略所有含
γ
1
/
(
1
−
γ
)
\gamma^{1/(1-\gamma)}
γ1/(1−γ)和比
γ
1
/
(
1
−
γ
)
\gamma^{1/(1-\gamma)}
γ1/(1−γ)更高阶的系数的项。例如,当
γ
=
0.95
\gamma=0.95
γ=0.95时,
y
t
≈
0.05
∑
i
=
0
19
0.9
5
i
x
t
−
i
.
y_t \approx 0.05 \sum_{i=0}^{19} 0.95^i x_{t-i}.
yt≈0.05i=0∑190.95ixt−i.
因此,在实际中,我们常常将
y
t
y_t
yt看作是对最近
1
/
(
1
−
γ
)
1/(1-\gamma)
1/(1−γ)个时间步的
x
t
x_t
xt值的加权平均。例如,当
γ
=
0.95
\gamma = 0.95
γ=0.95时,
y
t
y_t
yt可以被看作对最近20个时间步的
x
t
x_t
xt值的加权平均;当
γ
=
0.9
\gamma = 0.9
γ=0.9时,
y
t
y_t
yt可以看作是对最近10个时间步的
x
t
x_t
xt值的加权平均。而且,离当前时间步
t
t
t越近的
x
t
x_t
xt值获得的权重越大(越接近1)。
现在,对动量法的速度变量做变形:
v
t
←
γ
v
t
−
1
+
(
1
−
γ
)
(
η
t
1
−
γ
g
t
)
.
\boldsymbol{v}_t \leftarrow \gamma \boldsymbol{v}_{t-1} + (1 - \gamma) \left(\frac{\eta_t}{1 - \gamma} \boldsymbol{g}_t\right).
vt←γvt−1+(1−γ)(1−γηtgt).
由指数加权移动平均的形式可得,速度变量
v
t
\boldsymbol{v}_t
vt实际上对序列 \({\eta_{t-i}\boldsymbol{g}_{t-i} /(1-\gamma):i=0,\ldots,1/(1-\gamma)-1}\) 做了指数加权移动平均。换句话说,相比于小批量随机梯度下降,动量法在每个时间步的自变量更新量近似于将前者对应的最近
1
/
(
1
−
γ
)
1/(1-\gamma)
1/(1−γ)个时间步的更新量做了指数加权移动平均后再除以
1
−
γ
1-\gamma
1−γ。所以,在动量法中,自变量在各个方向上的移动幅度不仅取决于当前梯度,还取决于过去的各个梯度在各个方向上是否一致。这样,就可以使用较大的学习率,从而使自变量向最优解更快移动。
- 动量法使用了指数加权移动平均的思想。它将过去时间步的梯度做了加权平均,且权重按时间步指数衰减。
- 动量法使得相邻时间步的自变量更新在方向上更加一致。
AdaGrad
在之前,目标函数自变量的每一个元素在相同时间步都使用同一个学习率来自我迭代。当不同维度的梯度值有较大差别时,需要选择足够小的学习率使得自变量在梯度值较大的维度上不发散,但这样会导致自变量在梯度值较小的维度上迭代过慢。AdaGrad算法根据自变量在每个维度的梯度值的大小来调整各个维度上的学习率,从而避免统一的学习率难以适应所有维度的问题 。
AdaGrad算法使用一个小批量随机梯度 g t \boldsymbol{g}_t gt按元素平方的累加变量 s t \boldsymbol{s}_t st。在时间步0,AdaGrad将 s 0 \boldsymbol{s}_0 s0中每个元素初始化为0。在时间步 t t t,首先将小批量随机梯度 g t \boldsymbol{g}_t gt按元素平方后累加到变量 s t \boldsymbol{s}_t st:
s
t
←
s
t
−
1
+
g
t
⊙
g
t
,
\boldsymbol{s}_t \leftarrow \boldsymbol{s}_{t-1} + \boldsymbol{g}_t \odot \boldsymbol{g}_t,
st←st−1+gt⊙gt,
其中
⊙
\odot
⊙是按元素相乘。接着,我们将目标函数自变量中每个元素的学习率通过按元素运算重新调整一下:
x
t
←
x
t
−
1
−
η
s
t
+
ϵ
⊙
g
t
,
\boldsymbol{x}_t \leftarrow \boldsymbol{x}_{t-1} - \frac{\eta}{\sqrt{\boldsymbol{s}_t + \epsilon}} \odot \boldsymbol{g}_t,
xt←xt−1−st+ϵη⊙gt,
其中
η
\eta
η是学习率,
ϵ
\epsilon
ϵ是为了维持数值稳定性而添加的常数,如
1
0
−
6
10^{-6}
10−6。这里开方、除法和乘法的运算都是按元素运算的***。这些按元素运算使得目标函数自变量中每个元素都分别拥有自己的学习率*。
特点
小批量随机梯度按元素平方的累加变量 s t \boldsymbol{s}_t st出现在学习率的分母项中,因此,如果目标函数有关自变量中某个元素的偏导数一直都较大,那么该元素的学习率将下降较快;反之,如果目标函数有关自变量中某个元素的偏导数一直都较小,那么该元素的学习率将下降较慢。然而,由于 s t \boldsymbol{s}_t st一直在累加按元素平方的梯度,自变量中每个元素的学习率在迭代过程中一直在降低(或不变)。所以,当学习率在迭代早期降得较快且当前解依然不佳时,AdaGrad算法在迭代后期由于学习率过小,可能较难找到一个有用的解。
- AdaGrad算法在迭代过程中不断调整学习率,并让目标函数自变量中每个元素都分别拥有自己的学习率。
- 使用AdaGrad算法时,自变量中每个元素的学习率在迭代过程中一直在降低(或不变),因此可以采用较大的学习率(但也不能太大),以避免学习率一直衰减造成的收敛速度变慢。
RMSprop
AdaGrad算法在迭代后期由于学习率过小,可能较难找到一个有用的解。为了解决这一问题,RMSProp算法对AdaGrad算法做了一点小小的修改。
不同于AdaGrad算法里状态变量 s t \boldsymbol{s}_t st是截至时间步 t t t所有小批量随机梯度 g t \boldsymbol{g}_t gt按元素平方和,RMSProp算法将这些梯度按元素平方做指数加权移动平均。具体来说,给定超参数 0 ≤ γ < 1 0 \leq \gamma < 1 0≤γ<1,RMSProp算法在时间步 t > 0 t>0 t>0计算
s
t
←
γ
s
t
−
1
+
(
1
−
γ
)
g
t
⊙
g
t
.
\boldsymbol{s}_t \leftarrow \gamma \boldsymbol{s}_{t-1} + (1 - \gamma) \boldsymbol{g}_t \odot \boldsymbol{g}_t.
st←γst−1+(1−γ)gt⊙gt.
和AdaGrad算法一样,RMSProp算法将目标函数自变量中每个元素的学习率通过按元素运算重新调整,然后更新自变量
x
t
←
x
t
−
1
−
η
s
t
+
ϵ
⊙
g
t
,
\boldsymbol{x}_t \leftarrow \boldsymbol{x}_{t-1} - \frac{\eta}{\sqrt{\boldsymbol{s}_t + \epsilon}} \odot \boldsymbol{g}_t,
xt←xt−1−st+ϵη⊙gt,
其中
η
\eta
η是学习率,
ϵ
\epsilon
ϵ是为了维持数值稳定性而添加的常数,如
1
0
−
6
10^{-6}
10−6。因为RMSProp算法的状态变量
s
t
\boldsymbol{s}_t
st是对平方项
g
t
⊙
g
t
\boldsymbol{g}_t \odot \boldsymbol{g}_t
gt⊙gt的指数加权移动平均,所以可以看作最近
1
/
(
1
−
γ
)
1/(1-\gamma)
1/(1−γ)个时间步的小批量随机梯度平方项的加权平均。如此一来,自变量每个元素的学习率在迭代过程中就不再一直降低(或不变)。
- RMSProp算法和AdaGrad算法的不同在于,RMSProp算法使用了小批量随机梯度按元素平方的指数加权移动平均来调整学习率。
AdaDelta
除了RMSProp算法以外,另一个常用优化算法AdaDelta算法也针对AdaGrad算法在迭代后期可能较难找到有用解的问题做了改进,AdaDelta算法没有学习率这一超参数。
AdaDelta算法也像RMSProp算法一样,使用了小批量随机梯度 g t \boldsymbol{g}_t gt按元素平方的指数加权移动平均变量 s t \boldsymbol{s}_t st。在时间步0,它的所有元素被初始化为0。给定超参数 0 ≤ ρ < 1 0 \leq \rho < 1 0≤ρ<1(对应RMSProp算法中的 γ \gamma γ),在时间步 t > 0 t>0 t>0,同RMSProp算法一样计算
s
t
←
ρ
s
t
−
1
+
(
1
−
ρ
)
g
t
⊙
g
t
.
\boldsymbol{s}_t \leftarrow \rho \boldsymbol{s}_{t-1} + (1 - \rho) \boldsymbol{g}_t \odot \boldsymbol{g}_t.
st←ρst−1+(1−ρ)gt⊙gt.
与RMSProp算法不同的是,AdaDelta算法还维护一个额外的状态变量
Δ
x
t
\Delta\boldsymbol{x}_t
Δxt ,其元素同样在时间步0时被初始化为0。我们使用
Δ
x
t
−
1
\Delta\boldsymbol{x}_{t-1}
Δxt−1 来计算自变量的变化量:
g
t
′
←
Δ
x
t
−
1
+
ϵ
s
t
+
ϵ
⊙
g
t
,
\boldsymbol{g}_t' \leftarrow \sqrt{\frac{\Delta\boldsymbol{x}_{t-1} + \epsilon}{\boldsymbol{s}_t + \epsilon}} \odot \boldsymbol{g}_t,
gt′←st+ϵΔxt−1+ϵ⊙gt,
其中
ϵ
\epsilon
ϵ是为了维持数值稳定性而添加的常数,如
1
0
−
5
10^{-5}
10−5。接着更新自变量:
x
t
←
x
t
−
1
−
g
t
′
.
\boldsymbol{x}_t \leftarrow \boldsymbol{x}_{t-1} - \boldsymbol{g}'_t.
xt←xt−1−gt′.
最后,使用
Δ
x
t
\Delta\boldsymbol{x}_t
Δxt来记录自变量变化量
g
t
′
\boldsymbol{g}'_t
gt′按元素平方的指数加权移动平均:
Δ
x
t
←
ρ
Δ
x
t
−
1
+
(
1
−
ρ
)
g
t
′
⊙
g
t
′
.
\Delta\boldsymbol{x}_t \leftarrow \rho \Delta\boldsymbol{x}_{t-1} + (1 - \rho) \boldsymbol{g}'_t \odot \boldsymbol{g}'_t.
Δxt←ρΔxt−1+(1−ρ)gt′⊙gt′.
可以看到,如不考虑
ϵ
\epsilon
ϵ的影响,AdaDelta算法与RMSProp算法的不同之处在于使用
Δ
x
t
−
1
\sqrt{\Delta\boldsymbol{x}_{t-1}}
Δxt−1来替代超参数
η
\eta
η。
Adam
Adam算法在RMSProp算法基础上对小批量随机梯度也做了指数加权移动平均。
Adam算法使用了动量变量
v
t
\boldsymbol{v}_t
vt和RMSProp算法中小批量随机梯度按元素平方的指数加权移动平均变量
s
t
\boldsymbol{s}_t
st,并在时间步0将它们中每个元素初始化为0。给定超参数
0
≤
β
1
<
1
0 \leq \beta_1 < 1
0≤β1<1(算法作者建议设为0.9),时间步
t
t
t的动量变量
v
t
\boldsymbol{v}_t
vt即小批量随机梯度
g
t
\boldsymbol{g}_t
gt的指数加权移动平均:
v
t
←
β
1
v
t
−
1
+
(
1
−
β
1
)
g
t
.
\boldsymbol{v}_t \leftarrow \beta_1 \boldsymbol{v}_{t-1} + (1 - \beta_1) \boldsymbol{g}_t.
vt←β1vt−1+(1−β1)gt.
和RMSProp算法中一样,给定超参数
0
≤
β
2
<
1
0 \leq \beta_2 < 1
0≤β2<1(算法作者建议设为0.999),
将小批量随机梯度按元素平方后的项
g
t
⊙
g
t
\boldsymbol{g}_t \odot \boldsymbol{g}_t
gt⊙gt做指数加权移动平均得到
s
t
\boldsymbol{s}_t
st:
s
t
←
β
2
s
t
−
1
+
(
1
−
β
2
)
g
t
⊙
g
t
.
\boldsymbol{s}_t \leftarrow \beta_2 \boldsymbol{s}_{t-1} + (1 - \beta_2) \boldsymbol{g}_t \odot \boldsymbol{g}_t.
st←β2st−1+(1−β2)gt⊙gt.
由于我们将
v
0
\boldsymbol{v}_0
v0 和
s
0
\boldsymbol{s}_0
s0 中的元素都初始化为0,在时间步
t
t
t我们得到
v
t
=
(
1
−
β
1
)
∑
i
=
1
t
β
1
t
−
i
g
i
\boldsymbol{v}_t = (1-\beta_1) \sum_{i=1}^t \beta_1^{t-i} \boldsymbol{g}_i
vt=(1−β1)∑i=1tβ1t−igi 。将过去各时间步小批量随机梯度的权值相加,得到
(
1
−
β
1
)
∑
i
=
1
t
β
1
t
−
i
=
1
−
β
1
t
(1-\beta_1) \sum_{i=1}^t \beta_1^{t-i} = 1 - \beta_1^t
(1−β1)∑i=1tβ1t−i=1−β1t 。需要注意的是,当
t
t
t较小时,过去各时间步小批量随机梯度权值之和会较小。例如,当
β
1
=
0.9
\beta_1 = 0.9
β1=0.9 时,
v
1
=
0.1
g
1
\boldsymbol{v}_1 = 0.1\boldsymbol{g}_1
v1=0.1g1 。为了消除这样的影响,对于任意时间步
t
t
t,我们可以将
v
t
\boldsymbol{v}_t
vt 再除以
1
−
β
1
t
1 - \beta_1^t
1−β1t ,从而使过去各时间步小批量随机梯度权值之和为1。这也叫作偏差修正。在Adam算法中,我们对变量
v
t
\boldsymbol{v}_t
vt 和
s
t
\boldsymbol{s}_t
st 均作偏差修正:
v ^ t ← v t 1 − β 1 t , \hat{\boldsymbol{v}}_t \leftarrow \frac{\boldsymbol{v}_t}{1 - \beta_1^t}, v^t←1−β1tvt,
s ^ t ← s t 1 − β 2 t . \hat{\boldsymbol{s}}_t \leftarrow \frac{\boldsymbol{s}_t}{1 - \beta_2^t}. s^t←1−β2tst.
接下来,Adam算法使用以上偏差修正后的变量 v ^ t \hat{\boldsymbol{v}}_t v^t和 s ^ t \hat{\boldsymbol{s}}_t s^t,将模型参数中每个元素的学习率通过按元素运算重新调整:
g
t
′
←
η
v
^
t
s
^
t
+
ϵ
,
\boldsymbol{g}_t' \leftarrow \frac{\eta \hat{\boldsymbol{v}}_t}{\sqrt{\hat{\boldsymbol{s}}_t} + \epsilon},
gt′←s^t+ϵηv^t,
其中
η
\eta
η是学习率,
ϵ
\epsilon
ϵ是为了维持数值稳定性而添加的常数,如
1
0
−
8
10^{-8}
10−8。和AdaGrad算法、RMSProp算法以及AdaDelta算法一样,目标函数自变量中每个元素都分别拥有自己的学习率。最后,使用
g
t
′
\boldsymbol{g}_t'
gt′迭代自变量:
x t ← x t − 1 − g t ′ . \boldsymbol{x}_t \leftarrow \boldsymbol{x}_{t-1} - \boldsymbol{g}_t'. xt←xt−1−gt′.
- Adam算法在RMSProp算法的基础上对小批量随机梯度也做了指数加权移动平均。
- Adam算法使用了偏差修正。