SGD
一般指 Batch Gradient Descent。
有时会出现的一个问题:某方向太快,某方向太慢, 如图
甚至,学习率稍微大一点就发散的问题
指数加权移动平均
指数加权移动平均并不是优化算法,但是下面这些基于 SGD 的改进算法都用到了指数加权移动平均。
exponentially weighted moving average, 给定超参数
0
≤
γ
<
10
0≤\gamma<10
0≤γ<10 ,当前时间步
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
.
.
.
\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}\\ & ... \end{aligned}
yt=(1−γ)xt+γyt−1=(1−γ)xt+(1−γ)⋅γxt−1+γ2yt−2=(1−γ)xt+(1−γ)⋅γxt−1+(1−γ)⋅γ2xt−2+γ3yt−3...
在实际中,我们常常将
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 值的加权平均;而且,离当前时间步
t
t
t 越近的
x
t
x_t
xt 值获得的权重越大(越接近1)。
这样统计的意义在于,新的变化量需要考虑历史,且会有累计效果。
这样用指数加权移动平均代替原参数,会使最初几个统计变小(因为初始值为0),为了消除影响可以引入修正。见 Adam 部分。
动量法
动量法从指数加权移动平均中获得灵感。
将 SGD 的迭代公式变形:
S
G
D
算法
x
t
←
x
t
−
1
−
η
t
g
t
⇓
M
o
m
e
n
t
u
m
算法
v
t
←
γ
v
t
−
1
+
η
t
g
t
x
t
←
x
t
−
1
−
v
t
\begin{array}{c} SGD\text{算法}\\[2ex] x_t \leftarrow x_{t - 1} - \eta_t g_t & \text{}\\[2ex] \Downarrow\\[2ex] Momentum\text{算法}\\[2ex] v_t \leftarrow \gamma v_{t - 1} + \eta_t g_t\\[2ex] x_t \leftarrow x_{t - 1} - v_t\\[2ex] \end{array}
SGD算法xt←xt−1−ηtgt⇓Momentum算法vt←γvt−1+ηtgtxt←xt−1−vt
v
t
v_t
vt称为速度(动量),初始化为
v
0
=
0
v_0=0
v0=0,可以看出:Momentum将梯度的更新量进行了指数加权移动平均。效果就是:新的变化量需要考虑历史。 尤其是异常值的影响降低,
使用动量法之后的梯度下降:
在本例中的效果:所有梯度在水平方向上为正(累加),而在竖直方向上时正时负(绝对值变得更小)。
AdaGrad
SGD 的梯度是一个定值,而梯度的每个分量可能有较大的差别,需要选择足够小的学习率使得自变量在梯度值较大的维度上不发散。但这样会导致自变量在梯度值较小的维度上迭代过慢。
AdaGrad算法,它根据自变量在每个维度的梯度值的大小来调整各个维度上的学习率,从而避免统一的学习率难以适应所有维度的问题。
将 SGD 的迭代公式变形为:
S
G
D
算法
x
t
←
x
t
−
1
−
η
t
g
t
⇓
A
d
a
G
r
a
d
算法
s
t
←
s
t
−
1
+
g
t
⊙
g
t
x
t
←
x
t
−
1
−
η
s
t
+
ϵ
⊙
g
t
\begin{array}{c} SGD\text{算法}\\[2ex] x_t \leftarrow x_{t - 1} - \eta_tg_t & \text{}\\[2ex] \Downarrow\\[2ex] AdaGrad\text{算法}\\[2ex] s_t \leftarrow s_{t - 1} + g_t\odot g_t\\[2ex] x_t \leftarrow x_{t - 1} - \frac{\eta}{\sqrt{s_t+\epsilon}}\odot g_t \\[2ex] \end{array}
SGD算法xt←xt−1−ηtgt⇓AdaGrad算法st←st−1+gt⊙gtxt←xt−1−st+ϵη⊙gt
状态变量
s
t
s_t
st 是
g
t
⊙
g
t
g_t\odot g_t
gt⊙gt平方项的累加。
按位运算使得梯度的每个分量有不同的学习率。
小批量随机梯度按元素平方的累加变量 s t s_t st 出现在学习率的分母项中。因此,如果梯度分量较大,那么该梯度分量的学习率下降得较快;反之,如果梯度分量较小,那么该梯度分量的学习率下降得较慢。
然而,由于 s t s_t st 一直在累加,每个梯度分量的学习率在迭代过程中就一直在降低(或不变)。所以,当学习率在迭代早期降得较快且当前解依然不佳时,AdaGrad算法在迭代后期由于学习率过小,可能较难找到一个有用的解。
RMSProp
为了解决 AdaGrad 中迭代后期学习率过小可能较难找到一个有用的解的问题,RMSProp算法对AdaGrad算法做了一点小小的修改,RMSProp算法将这些梯度按元素平方做指数加权移动平均:
A
d
a
G
r
a
d
算法
s
t
←
s
t
−
1
+
g
t
⊙
g
t
x
t
←
x
t
−
1
−
η
s
t
+
ϵ
⊙
g
t
⇓
R
M
S
P
r
o
p
算法
s
t
←
γ
s
t
−
1
+
(
1
−
γ
)
g
t
⊙
g
t
x
t
←
x
t
−
1
−
η
s
t
+
ϵ
⊙
g
t
\begin{array}{c} AdaGrad\text{算法}\\[2ex] s_t \leftarrow s_{t - 1} + g_t\odot g_t\\[2ex] x_t \leftarrow x_{t - 1} - \frac{\eta}{\sqrt{s_t+\epsilon}}\odot g_t \\[2ex] \Downarrow\\[2ex] RMSProp\text{算法}\\[2ex] s_t \leftarrow \gamma s_{t - 1} + (1-\gamma)g_t\odot g_t\\[2ex] x_t \leftarrow x_{t - 1} - \frac{\eta}{\sqrt{s_t+\epsilon}}\odot g_t \\[2ex] \end{array}
AdaGrad算法st←st−1+gt⊙gtxt←xt−1−st+ϵη⊙gt⇓RMSProp算法st←γst−1+(1−γ)gt⊙gtxt←xt−1−st+ϵη⊙gt
状态变量
s
t
s_t
st 是对平方项
g
t
⊙
g
t
g_t\odot g_t
gt⊙gt的指数加权移动平均,可以看作是最近
1
/
(
1
−
γ
)
1/(1-\gamma)
1/(1−γ) 个时间步的小批量随机梯度平方项的加权平均。如此一来,自变量每个元素的学习率在迭代过程中就不再一直降低或不变(需要理解指数加权移动平均的作用)。
在同样的学习率下,RMSProp算法可以更快逼近最优解。
AdaDelta
AdaDelta算法也针对AdaGrad算法在迭代后期可能较难找到有用解的问题做了改进。有意思的是,AdaDelta算法没有学习率
η
\eta
η 这一超参数。
A
d
a
G
r
a
d
算法
s
t
←
s
t
−
1
+
g
t
⊙
g
t
x
t
←
x
t
−
1
−
η
s
t
+
ϵ
⊙
g
t
⇓
A
d
a
D
e
l
t
a
算法
s
t
←
ρ
s
t
−
1
+
(
1
−
ρ
)
g
t
⊙
g
t
g
t
′
←
Δ
x
t
−
1
+
ϵ
s
t
+
ϵ
⊙
g
t
x
t
←
x
t
−
1
−
g
t
′
Δ
x
t
←
ρ
Δ
x
t
−
1
+
(
1
−
ρ
)
g
t
′
⊙
g
t
′
\begin{array}{c} AdaGrad\text{算法}\\[2ex] s_t \leftarrow s_{t - 1} + g_t\odot g_t\\[2ex] x_t \leftarrow x_{t - 1} - \frac{\eta}{\sqrt{s_t+\epsilon}}\odot g_t \\[2ex] \Downarrow\\[2ex] AdaDelta\text{算法}\\[2ex] s_t \leftarrow \rho s_{t - 1} + (1-\rho)g_t\odot g_t\\[2ex] g^\prime_t \leftarrow \sqrt{\frac{\Delta x_{t-1}+\epsilon}{s_t+\epsilon}}\odot g_t\\[2ex] x_t \leftarrow x_{t - 1} - g^\prime_t\\[2ex] \Delta x_t \leftarrow\rho \Delta x_{t-1}+(1-\rho)g^\prime_t\odot g^\prime_t\\[2ex] \end{array}
AdaGrad算法st←st−1+gt⊙gtxt←xt−1−st+ϵη⊙gt⇓AdaDelta算法st←ρst−1+(1−ρ)gt⊙gtgt′←st+ϵΔxt−1+ϵ⊙gtxt←xt−1−gt′Δxt←ρΔxt−1+(1−ρ)gt′⊙gt′
Δ
x
t
\Delta x_t
Δxt 是
g
t
′
⊙
g
t
′
g^\prime_t\odot g^\prime_t
gt′⊙gt′ 的指数加权移动平均。
AdaDelta算法跟RMSProp算法的不同之处在于使用 Δ x t − 1 \sqrt{\Delta x_{t-1}} Δxt−1 代替学习率 η \eta η
Adam
Adam算法在RMSProp算法基础上对小批量随机梯度也做了指数加权移动平均。所以Adam算法可以看做是RMSProp算法与动量法的结合。
M
o
m
e
n
t
u
m
算法
R
M
S
P
r
o
p
算法
v
t
←
γ
v
t
−
1
+
η
t
g
t
s
t
←
γ
s
t
−
1
+
(
1
−
γ
)
g
t
⊙
g
t
x
t
←
x
t
−
1
−
v
t
x
t
←
x
t
−
1
−
η
s
t
+
ϵ
⊙
g
t
\begin{array}{c} Momentum\text{算法} & RMSProp\text{算法}\\[2ex] v_t \leftarrow \gamma v_{t - 1} + \eta_t g_t & s_t \leftarrow \gamma s_{t - 1} + (1-\gamma)g_t\odot g_t\\[2ex] x_t \leftarrow x_{t - 1} - v_t & x_t \leftarrow x_{t - 1} - \frac{\eta}{\sqrt{s_t+\epsilon}}\odot g_t\\ \end{array}
Momentum算法vt←γvt−1+ηtgtxt←xt−1−vtRMSProp算法st←γst−1+(1−γ)gt⊙gtxt←xt−1−st+ϵη⊙gt
⇓
A
d
a
m
算法
v
t
←
β
1
v
t
−
1
+
(
1
−
β
1
)
g
t
s
t
←
β
2
s
t
−
1
+
(
1
−
β
2
)
g
t
⊙
g
t
v
^
t
←
v
t
1
−
β
1
t
s
^
t
←
s
t
1
−
β
2
t
g
t
′
←
η
v
^
t
s
^
t
+
ϵ
x
t
←
x
t
−
1
−
g
t
′
\begin{array}{c} \Downarrow\\[2ex] Adam\text{算法}\\[2ex] v_t \leftarrow \beta_1v_{t-1}+(1-\beta_1)g_t\\[2ex] s_t\leftarrow\beta_2s_{t-1}+(1-\beta_2)g_t\odot g_t\\[2ex] \hat v_t \leftarrow \frac{v_t}{1-\beta^t_1}\\[2ex] \hat s_t \leftarrow \frac{s_t}{1-\beta^t_2}\\[2ex] g^\prime_t \leftarrow \frac{\eta \hat v_t}{\sqrt{\hat s_t}+\epsilon}\\[2ex] x_t \leftarrow x_{t-1}-g^\prime_t\\[2ex] \end{array}
⇓Adam算法vt←β1vt−1+(1−β1)gtst←β2st−1+(1−β2)gt⊙gtv^t←1−β1tvts^t←1−β2tstgt′←s^t+ϵηv^txt←xt−1−gt′
该算法作者建议设置
β
1
=
0.9
,
β
2
=
0.999
\beta_1=0.9,\beta_2=0.999
β1=0.9,β2=0.999。
v
t
v_t
vt 是
g
t
g_t
gt 的指数加权移动平均,
s
t
s_t
st 是
g
t
⊙
g
t
g_t \odot g_t
gt⊙gt 的指数加权移动平均。初始化值均为0。在时间步
t
t
t 我们得到
v
t
=
(
1
−
β
)
∑
t
=
1
t
β
1
t
−
i
g
i
v_t=(1-\beta)\sum^t_{t=1}\beta^{t-i}_1g_i
vt=(1−β)∑t=1tβ1t−igi。将过去各时间步小批量随机梯度的权值相加,得到
(
1
−
β
)
∑
t
=
1
t
β
1
t
−
i
=
1
−
β
1
t
(1-\beta)\sum^t_{t=1}\beta^{t-i}_1=1-\beta^t_1
(1−β)∑t=1tβ1t−i=1−β1t。需要注意的是,当
t
t
t 较小时,过去各时间步小批量随机梯度权值之和会较小。为了消除这样的影响,对于任意时间步
t
t
t,我们可以将
v
t
v_t
vt 再除以
1
−
β
1
t
1−β^t_1
1−β1t,从而使过去各时间步小批量随机梯度权值之和为1。这也叫作偏差修正。
和AdaGrad算法、RMSProp算法以及AdaDelta算法一样,目标函数自变量中每个元素都分别拥有自己的学习率。