文章目录
1、梯度下降
梯度下降有许多变体,它们在用于计算目标函数梯度的数据量上存在差别。
1.1、Batch 梯度下降
B
a
t
c
h
Batch
Batch 梯度下降计算整个训练集的成本函数相对参数
θ
θ
θ 的梯度。
θ
t
+
1
=
θ
t
−
η
⋅
∇
θ
J
(
θ
t
)
(1)
\theta^{t+1}=\theta^t-\eta \cdot \nabla_{\theta} J(\theta^t)\tag1
θt+1=θt−η⋅∇θJ(θt)(1)
由于每执行一次参数更新,需要计算整个数据集的梯度,所以
B
a
t
c
h
Batch
Batch 梯度下降速度非常慢,而且在数据集很大的情况下会占用很多内存。当添加新样本时,该方法不适合在线更新模型。
但是,
B
a
t
c
h
Batch
Batch 梯度下降能够保证收敛到凸误差曲面的全局最小值,和非凸曲面的局部极小值。
1.2、随机梯度下降(SGD)
随机梯度下降为每个训练样本(
x
i
x_i
xi)和标签(
y
i
y_i
yi)执行参数更新。
θ
t
+
1
=
θ
t
−
η
⋅
∇
θ
J
(
θ
t
;
x
i
;
y
i
)
(2)
\theta^{t+1}=\theta^t-\eta \cdot \nabla_{\theta} J\left(\theta^t ; x_i ; y_i\right)\tag2
θt+1=θt−η⋅∇θJ(θt;xi;yi)(2)
B
a
t
c
h
Batch
Batch 梯度下降对大数据集执行冗余计算,因为它在每个参数更新前重新计算相似样本梯度。
S
G
D
SGD
SGD 一次只执行一个样本上的更新来消除这种冗余。因此它通常更快,而且可以用于在线学习。
S
G
D
SGD
SGD 以很大的方差执行频繁的更新,导致目标函数剧烈波动,如图
1
1
1。
B
a
t
c
h
Batch
Batch 梯度下降能够将参数更新到极小值。
S
G
D
SGD
SGD 的波动性一方面使它能够跳转到新的、可能更好的局部极小值,另一方面,这使收敛到精确的最小值变得复杂,因为
S
G
D
SGD
SGD 会在最小值附近振荡。但是,当缓慢减小学习率时,
S
G
D
SGD
SGD 表现出与
B
a
t
c
h
Batch
Batch 梯度下降相同的收敛性,几乎确定收敛到非凸优化的局部最小值和凸优化的全局最小值。
1.3、Mini-batch 梯度下降
M
i
n
i
−
b
a
t
c
h
Mini-batch
Mini−batch 梯度下降对两种方法进行折中,实现了最佳效果,并为每一个
m
i
n
i
−
b
a
t
c
h
mini-batch
mini−batch 的
n
n
n 个样本执行一次更新。
θ
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
θt+1=θt−η⋅∇θJ(θt;x(i:i+n);y(i:i+n))(3)
这种方法可以:
- 减小参数更新的方差,使收敛过程更稳定
- 利用常见的深度学习库的高度优化的矩阵计算方法,高效计算 m i n i − b a t c h mini-batch mini−batch 梯度
训练神经网络时,通常采用 m i n i − b a t c h mini-batch mini−batch 梯度下降算法,但是使用 S G D SGD SGD 这一术语。然而,普通的 m i n i − b a t c h mini-batch mini−batch 梯度下降不能保证好的收敛性,而且有以下问题需要解决:
- 选择合适的学习率很困难。学习率太小会导致收敛速度过慢,学习率太大会阻碍收敛,导致损失函数在最小值附近波动,甚至发散。
- 学习率 s c h e d u l e s schedules schedules 尝试调整训练时的学习率,比如退火,即根据预定义的 s c h e d u l e s schedules schedules 或者当迭代之间的目标变化低于某一阈值时,减小学习率。但是, s c h e d u l e s schedules schedules 或者阈值必须预定义,因此无法适应数据集特征。
- 所有参数更新使用相同学习率。如果数据是稀疏的,而且特征频率差异较大,那么我们不想同等程度更新所有参数,而是对较少出现的特征执行更大的更新。
- 最小化高度非凸误差函数的另一个关键挑战是避免陷入许多次优局部极小。 D a u p h i n Dauphin Dauphin 等人认为,造成这一困难的原因不是局部极小值,而是鞍点,即在一个维度上坡度增加,另一维度上坡度减小。 S G D SGD SGD 在这些鞍点处很难逃脱,因为在所有维度上的梯度都接近于 0 0 0。
2、梯度下降优化算法
2.1、Momentum
S
G
D
SGD
SGD 很难摆脱沟壑,即曲面的曲线在一个维度比另一维度更平稳,这通常是在局部最优附近。在这些场景下,
S
G
D
SGD
SGD 在峡谷的斜坡上振荡,沿着底部向局部最优方向前进的过程中徘徊不前,如图
2
a
2a
2a 所示。
M
o
m
e
n
t
u
m
Momentum
Momentum 有助于加速相关方向的梯度下降,并抑制振荡,如图
2
b
2b
2b 所示。它通过将之前的更新向量的
γ
\gamma
γ 倍加到当前更新向量来实现这一点。
v
t
=
γ
v
t
−
1
+
η
∇
θ
J
(
θ
t
)
θ
t
+
1
=
θ
t
−
v
t
(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
vtθt+1=γvt−1+η∇θJ(θt)=θt−vt(4)
动量项
γ
\gamma
γ 通常设为
0.9
0.9
0.9。
对于梯度指向相同方向的维度
m
o
m
e
n
t
u
m
momentum
momentum 项增加,对于梯度方向改变的维度,减少更新。这样就能实现更快地收敛,并减少震荡。
2.2、Nesterov 加速梯度
N
A
G
NAG
NAG 是一种给出预见性动量项的方法。由于已知使用动量项
γ
v
t
−
1
\gamma v^{t-1}
γvt−1 来更新参数,因此计算
θ
t
−
γ
v
t
−
1
\theta^t-\gamma v^{t-1}
θt−γvt−1 给出了参数下一个位置的近似。这样做的好处是算法可以提前知道梯度方向发生改变,并相应地减小更新步长,从而加速收敛。
v
t
=
γ
v
t
−
1
+
η
∇
θ
J
(
θ
t
−
γ
v
t
−
1
)
θ
t
+
1
=
θ
t
−
v
t
(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
vtθt+1=γvt−1+η∇θJ(θt−γvt−1)=θt−vt(5)
将
γ
\gamma
γ 设为
0.9
0.9
0.9。
M
o
m
e
n
t
u
m
Momentum
Momentum 首先计算当前梯度(图
3
3
3 小蓝色向量)然后在更新的累积梯度方向上前进一大步(大蓝色向量),
N
A
G
NAG
NAG 首先在之前累积的梯度方向进行大的跳跃(棕色向量),测量梯度然后进行校正(绿色向量)。这一预见性更新防止了参数更新过快并提升了响应能力,极大提升了
R
N
N
RNN
RNN 在许多任务上的性能。
既然能够根据误差函数调整更新并相应加快
S
G
D
SGD
SGD 速度,我们也希望根据每个参数的重要性来决定更新参数的程度。
K e r a s Keras Keras 中调用相关优化器方法
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
A d a g r a d Adagrad Adagrad 是一种基于梯度的优化算法,它使学习率适应于参数,对低频参数执行更大的更新,对高频参数执行更小的更新。因此,它非常适合处理稀疏数据。 A d a g r a d Adagrad Adagrad 极大地提升了 S G D SGD SGD 的鲁棒性。
过去,执行一次更新,每个参数使用相同的学习率
η
\eta
η。
A
d
a
g
r
a
d
Adagrad
Adagrad 在每次更新时,不同的参数的学习率不同。单个参数
θ
i
\theta_i
θi 的更新如下:
g
i
t
=
∇
θ
t
J
(
θ
i
t
)
(6)
g_i^t=\nabla_{\theta^t} J\left(\theta_i^t\right)\tag6
git=∇θtJ(θit)(6)
θ
i
t
+
1
=
θ
i
t
−
η
G
i
i
t
+
ϵ
⋅
g
i
t
(7)
\theta_i^{t+1}=\theta_i^{t}-\frac{\eta}{\sqrt{G_{i i}^t+\epsilon}} \cdot g_i^t\tag7
θit+1=θit−Giit+ϵη⋅git(7)
所有参数更新的矩阵形式为:
θ
(
t
+
1
)
=
θ
(
t
)
−
η
(
G
t
)
−
1
⊙
∇
θ
t
J
(
θ
t
)
(8)
\theta^{(t+1)}=\theta^{(t)}-\eta\left(G^{t}\right)^{-1}\odot\nabla_{\theta^t} J\left(\theta^t\right)\tag8
θ(t+1)=θ(t)−η(Gt)−1⊙∇θtJ(θt)(8)
其中:
G
t
=
[
∑
τ
=
1
t
g
1
τ
+
ϵ
0
⋯
0
0
∑
τ
=
1
t
g
2
τ
+
ϵ
⋯
0
⋮
⋮
⋱
⋮
0
0
⋯
∑
τ
=
1
t
g
d
τ
+
ϵ
]
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]
Gt=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡τ=1∑tg1τ+ϵ0⋮00τ=1∑tg2τ+ϵ⋮0⋯⋯⋱⋯00⋮τ=1∑tgdτ+ϵ⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
G
t
G^t
Gt 是一个对角矩阵,每一个对角线元素为该位置对应参数的前
t
t
t 次更新中梯度的平方和。
ϵ
\epsilon
ϵ 为平滑参数,避免分母为
0
0
0(通常为
1
e
−
8
1e-8
1e−8)。有趣的是,如果没有平方根运算,该算法效果更差。
A d a g r a d Adagrad Adagrad 主要的优点是它不需要手动调整学习率,通常使用默认值 0.01 0.01 0.01。
A d a g r a d Adagrad Adagrad 主要的缺点是,它在分母中积累了平方梯度:由于增加的每一项都是正的,训练过程中累计和不断增加。这相应地导致学习率减小,最终趋于无穷小,此时算法难以继续学习。
K e r a s Keras Keras 调用优化器方法:
keras.optimizers.Adagrad(lr=0.01, epsilon=1e-06)
"""
lr:大于0的浮点数,学习率
epsilon:大于0的小浮点数,防止除0错误
"""
2.4、Adadelta
A d a d e l t a Adadelta Adadelta 是 A d a g r a d Adagrad Adagrad 的延伸。取代累加之前所有梯度平方, A d a d e l t a Adadelta Adadelta 累加之前固定范围 w w w 内的梯度。
梯度和被递归地定义为所有过去平方梯度衰减的平均值,而不是无效地存储
w
w
w 个先前的平方梯度。在时间步
t
t
t 时运行平均
E
[
g
2
]
t
E[g^2]_t
E[g2]t,仅依赖于过去的均值和当前的梯度。:
E
[
g
2
]
t
=
γ
E
[
g
2
]
t
−
1
+
(
1
−
γ
)
g
t
2
(10)
E\left[g^{2}\right]_{t}=\gamma E\left[g^{2}\right]_{t-1}+(1-\gamma) g_{t}^{2}\tag{10}
E[g2]t=γE[g2]t−1+(1−γ)gt2(10)
将
γ
\gamma
γ 设为与动量项类似的值,约为
0.9
0.9
0.9。为清晰起见,根据参数更新向量
Δ
θ
t
\Delta\theta_t
Δθt 重写
S
G
D
SGD
SGD 更新。
Δ
θ
t
=
−
η
⋅
g
t
,
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}
Δθtθt+1=−η⋅gt,i=θt+Δθt(11)
A
d
a
g
r
a
d
Adagrad
Adagrad 的参数更新向量表示为:
Δ
θ
t
=
−
η
G
t
+
ϵ
⊙
g
t
(12)
\Delta \theta_{t}=-\frac{\eta}{\sqrt{G_{t}+\epsilon}} \odot g_{t}\tag{12}
Δθt=−Gt+ϵη⊙gt(12)
现在只需要将对角矩阵
G
t
G_t
Gt 替换为过去平方梯度衰减的平均值
Δ
θ
t
=
−
η
E
[
g
2
]
t
+
ϵ
g
t
(13)
\Delta \theta_{t}=-\frac{\eta}{\sqrt{E\left[g^{2}\right]_{t}+\epsilon}} g_{t}\tag{13}
Δθt=−E[g2]t+ϵηgt(13)
由于分母只是梯度的均方根(
R
M
S
RMS
RMS)误差准则,可以用短期准则来代替它
Δ
θ
t
=
−
η
R
M
S
[
g
]
t
g
t
(14)
\Delta \theta_{t}=-\frac{\eta}{R M S[g]_{t}} g_{t}\tag{14}
Δθt=−RMS[g]tηgt(14)
作者指出,此更新中的单位(以及
S
G
D
SGD
SGD、
M
o
m
e
n
t
u
m
Momentum
Momentum 或
A
d
a
g
r
a
d
Adagrad
Adagrad 中的单位)不匹配,即更新应该具有与参数相同的假设单位。为了实现这一点,他们首先定义了另一个指数衰减平均值,这次不是平方梯度,而是平方参数更新:
E
[
Δ
θ
2
]
t
=
γ
E
[
Δ
θ
2
]
t
−
1
+
(
1
−
γ
)
Δ
θ
t
2
(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}
E[Δθ2]t=γE[Δθ2]t−1+(1−γ)Δθt2(15)
因此,参数更新的均方误差为:
R
M
S
[
Δ
θ
]
t
=
E
[
Δ
θ
2
]
t
+
ϵ
(16)
RMS[\Delta \theta]_{t}=\sqrt{E\left[\Delta \theta^{2}\right]_{t}+\epsilon}\tag{16}
RMS[Δθ]t=E[Δθ2]t+ϵ(16)
由于
R
M
S
[
Δ
θ
]
t
RMS[\Delta \theta]_{t}
RMS[Δθ]t 未知,用直到前一步参数更新的
R
M
S
RMS
RMS 逼近它。用
R
M
S
[
Δ
θ
]
t
−
1
RMS[\Delta \theta]_{t-1}
RMS[Δθ]t−1 替换上一个更新规则中的学习率,最终得到
A
d
a
d
e
l
t
a
Adadelta
Adadelta 更新规则:
Δ
θ
t
=
−
R
M
S
[
Δ
θ
]
t
−
1
R
M
S
[
g
]
t
g
t
θ
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}
Δθtθt+1=−RMS[g]tRMS[Δθ]t−1gt=θt+Δθt(17)
使用
A
d
a
d
e
l
t
a
Adadelta
Adadelta,甚至不需要设置默认学习率,因为它已经被从更新规则中删除了。
K e r a s Keras Keras 调用优化器方法:
keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-06)
"""
lr:大于0的浮点数,学习率
rho:大于0的浮点数
epsilon:大于0的小浮点数,防止除0错误
"""
2.5、RMSprop
R
M
S
p
r
o
p
RMSprop
RMSprop 是一种自适应学习率方法。它与
A
d
a
d
e
l
t
a
Adadelta
Adadelta 均用于解决
A
d
a
g
r
a
d
Adagrad
Adagrad 学习率急剧下降的问题。事实上,
R
M
S
p
r
o
p
RMSprop
RMSprop 与
A
d
a
d
e
l
t
a
Adadelta
Adadelta 的第一个更新向量相同。
E
[
g
2
]
t
=
0.9
E
[
g
2
]
t
−
1
+
0.1
g
t
2
θ
t
+
1
=
θ
t
−
η
E
[
g
2
]
t
+
ϵ
g
t
(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}
E[g2]tθt+1=0.9E[g2]t−1+0.1gt2=θt−E[g2]t+ϵηgt(18)
此外,
R
M
S
p
r
o
p
RMSprop
RMSprop 将学习率除以指数衰减的平方梯度的均值。
γ
\gamma
γ 最好设置为
0.9
0.9
0.9,学习率
η
\eta
η 通常为
0.001
0.001
0.001。
K e r a s Keras Keras 调用优化器方法:
keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-06)
"""
lr:大于0的浮点数,学习率
rho:大于0的浮点数
epsilon:大于0的小浮点数,防止除0错误
"""
2.6、Adam
A
d
a
p
t
i
v
e
M
o
m
e
n
t
E
s
t
i
m
a
t
i
o
n
(
A
d
a
m
)
Adaptive~Moment~Estimation(Adam)
Adaptive Moment Estimation(Adam) 是另一种计算每个参数自适应学习率的方法。除了存储指数衰减的平方梯度均值
v
t
v_t
vt,它还保留了类似于
m
o
m
e
n
t
u
m
momentum
momentum 的,指数衰减的梯度均值
m
t
m_t
mt。
m
t
=
β
1
m
t
−
1
+
(
1
−
β
1
)
g
t
v
t
=
β
2
v
t
−
1
+
(
1
−
β
2
)
g
t
2
(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}
mtvt=β1mt−1+(1−β1)gt=β2vt−1+(1−β2)gt2(19)
m
t
m_t
mt 和
v
t
v_t
vt 分别为梯度的一阶矩(均值)和二阶矩估计,这是该方法名字的由来。当
m
t
m_t
mt 和
v
t
v_t
vt 被初始化为零向量时,在初始时间步,它们都偏向于
0
0
0,特别当衰变率很小时更是如此(即,
β
1
\beta_1
β1 和
β
2
\beta_2
β2 接近于
1
1
1)。
通过计算一阶矩和二阶矩估计偏差修正来抵消偏差。
m
^
t
=
m
t
1
−
β
1
t
v
^
t
=
v
t
1
−
β
2
t
(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}
m^tv^t=1−β1tmt=1−β2tvt(20)
A
d
a
m
Adam
Adam 更新规则如下:
θ
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}
θt+1=θt−v^t+ϵηm^t(21)
β
1
\beta_1
β1 默认为
0.9
0.9
0.9,
β
2
\beta_2
β2 默认为
0.999
0.999
0.999,
ϵ
\epsilon
ϵ 默认为
1
0
−
8
10^{-8}
10−8。实验表明,相比于其他自适应算法,
A
d
a
m
Adam
Adam 效果更好。
K e r a s Keras Keras 调用优化器方法:
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
A
d
a
m
Adam
Adam 中的
v
t
v_t
vt 因子反向缩放之前梯度的
ℓ
2
\ell_2
ℓ2 范数和当前梯度
∣
g
t
∣
2
|g_t|^2
∣gt∣2:
v
t
=
β
2
v
t
−
1
+
(
1
−
β
2
)
∣
g
t
∣
2
(22)
v_{t}=\beta_{2} v_{t-1}+\left(1-\beta_{2}\right)\left|g_{t}\right|^{2}\tag{22}
vt=β2vt−1+(1−β2)∣gt∣2(22)
这里将其改为
ℓ
p
\ell_p
ℓp 范数,同时
β
2
\beta_2
β2 变为
β
2
p
\beta_2^p
β2p
v
t
=
β
2
p
v
t
−
1
+
(
1
−
β
2
p
)
∣
g
t
∣
p
(23)
v_{t}=\beta_{2}^{p} v_{t-1}+\left(1-\beta_{2}^{p}\right)\left|g_{t}\right|^{p}\tag{23}
vt=β2pvt−1+(1−β2p)∣gt∣p(23)
大
p
p
p 值范数通常在数值上不稳定,因此实践中
ℓ
1
\ell_1
ℓ1 和
ℓ
2
\ell_2
ℓ2 范数比较常见。然而,
ℓ
∞
\ell_{\infty}
ℓ∞ 通常表现更稳定。因此作者提出了
A
d
a
M
a
x
AdaMax
AdaMax,并证明了具有
ℓ
∞
\ell_{\infty}
ℓ∞ 的
v
t
v_t
vt 收敛到更稳定的值。为避免与
a
d
a
m
adam
adam 混淆,这里使用
u
t
u_t
ut 表示受无穷范数约束的
v
t
v_t
vt。
u
t
=
β
2
∞
v
t
−
1
+
(
1
−
β
2
∞
)
∣
g
t
∣
∞
=
max
(
β
2
⋅
v
t
−
1
,
∣
g
t
∣
)
(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}
ut=β2∞vt−1+(1−β2∞)∣gt∣∞=max(β2⋅vt−1,∣gt∣)(24)
通过将
v
^
t
+
ϵ
\sqrt{\hat{v}_{t}}+\epsilon
v^t+ϵ 替换为
u
t
u_t
ut 来获取
A
d
a
m
Adam
Adam 更新规则:
θ
t
+
1
=
θ
t
−
η
u
t
m
^
t
(25)
\theta_{t+1}=\theta_{t}-\frac{\eta}{u_{t}} \hat{m}_{t}\tag{25}
θt+1=θt−utηm^t(25)
由于
u
t
u_t
ut 依赖于
m
a
x
max
max 运算,所以不像
A
d
a
m
Adam
Adam 中的
m
t
m_t
mt 和
v
t
v_t
vt 容易偏向于
0
0
0,因此不需要计算
u
t
u_t
ut 的校正。默认值:
η
=
0.002
,
β
1
=
0.9
,
\eta=0.002, \beta_{1}=0.9,
η=0.002,β1=0.9,
β
2
=
0.999
\beta_{2}=0.999
β2=0.999。
K e r a s Keras Keras 调用优化器方法:
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
A d a m Adam Adam 可以看作 R M S p r o p RMSprop RMSprop 和 m o m e n t u m momentum momentum 的结合: R M S p r o p RMSprop RMSprop 贡献指数衰减的之前梯度平方的均值 v t v_t vt, m o m e n t u m momentum momentum 计算指数衰减的之前梯度的均值 m t m_t mt。 N e s t e r o v Nesterov Nesterov 加速梯度优于普通的 m o m e n t u m momentum momentum。
N a d a m ( N e s t e r o v − a c c e l e r a t e d A d a p t i v e M o m e n t E s t i m a t i o n ) Nadam(Nesterov-accelerated~Adaptive~Moment~Estimation) Nadam(Nesterov−accelerated Adaptive Moment Estimation) 将 A d a m Adam Adam 和 N A G NAG NAG 结合起来。为了将 N A G NAG NAG 结合到 A d a m Adam Adam 需要修改动量项 m t m_t mt
当前动量更新规则为:
g
t
=
∇
θ
t
J
(
θ
t
)
m
t
=
γ
m
t
−
1
+
η
g
t
θ
t
+
1
=
θ
t
−
m
t
(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}
gtmtθt+1=∇θtJ(θt)=γmt−1+ηgt=θt−mt(26)
将第二式带入第三式:
θ
t
+
1
=
θ
t
−
(
γ
m
t
−
1
+
η
g
t
)
(27)
\theta_{t+1}=\theta_{t}-\left(\gamma m_{t-1}+\eta g_{t}\right)\tag{27}
θt+1=θt−(γmt−1+ηgt)(27)
N
A
G
NAG
NAG 在计算梯度之前,使用动量步长更新参数,从而实现更精确的参数更新。
g
t
=
∇
θ
t
J
(
θ
t
−
γ
m
t
−
1
)
m
t
=
γ
m
t
−
1
+
η
g
t
θ
t
+
1
=
θ
t
−
m
t
(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}
gtmtθt+1=∇θtJ(θt−γmt−1)=γmt−1+ηgt=θt−mt(28)
D
o
z
a
t
Dozat
Dozat 提出修改
N
A
G
NAG
NAG:不再使用两次动量—一次用于更新梯度,另一次用于更新参数。直接使用前瞻性动量向量更新当前参数。
g
t
=
∇
θ
t
J
(
θ
t
)
m
t
=
γ
m
t
−
1
+
η
g
t
θ
t
+
1
=
θ
t
−
(
γ
m
t
+
η
g
t
)
(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}
gtmtθt+1=∇θtJ(θt)=γmt−1+ηgt=θt−(γmt+ηgt)(29)
注意与
27
27
27 的区别。为了给
A
d
a
m
Adam
Adam 增加
N
e
s
t
e
r
o
v
Nesterov
Nesterov 动量,使用当前动量向量代替之前的动量向量。
A
d
a
m
Adam
Adam 更新规则如下:
m
t
=
β
1
m
t
−
1
+
(
1
−
β
1
)
g
t
m
^
t
=
m
t
1
−
β
1
t
θ
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}
mtm^tθt+1=β1mt−1+(1−β1)gt=1−β1tmt=θt−v^t+ϵηm^t(30)
将前两式代入第三式得:
θ
t
+
1
=
θ
t
−
η
v
^
t
+
ϵ
(
β
1
m
t
−
1
1
−
β
1
t
+
(
1
−
β
1
)
g
t
1
−
β
1
t
)
(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}
θt+1=θt−v^t+ϵη(1−β1tβ1mt−1+1−β1t(1−β1)gt)(31)
由于
β
1
m
t
−
1
1
−
β
1
t
\frac{\beta_{1} m_{t-1}}{1-\beta_{1}^{t}}
1−β1tβ1mt−1 是上一步动量向量的偏移修正项,可以将它用
m
^
t
−
1
\hat{m}_{t-1}
m^t−1 替代:
θ
t
+
1
=
θ
t
−
η
v
^
t
+
ϵ
(
β
1
m
^
t
−
1
+
(
1
−
β
1
)
g
t
1
−
β
1
t
)
(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}
θt+1=θt−v^t+ϵη(β1m^t−1+1−β1t(1−β1)gt)(32)
看起来和等式
27
27
27 类似,我们将仿照等式
29
29
29 的做法添加
N
e
s
t
e
r
o
v
Nesterov
Nesterov 动量。将上一步动量向量的偏移估计
m
^
t
−
1
\hat{m}_{t-1}
m^t−1 用当前动量向量的偏移估计替代:
θ
t
+
1
=
θ
t
−
η
v
^
t
+
ϵ
(
β
1
m
^
t
+
(
1
−
β
1
)
g
t
1
−
β
1
t
)
(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}
θt+1=θt−v^t+ϵη(β1m^t+1−β1t(1−β1)gt)(33)
K e r a s Keras Keras 调用优化器方法:
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、如何选择优化方法
- 如果数据是稀疏的,就选择自适应学习率方法。还可以省去调节学习率的麻烦
- R M S p r o p RMSprop RMSprop 是 A d a g r a d Adagrad Adagrad 的扩展,解决学习率急剧消失的问题
- A d a d e l t a Adadelta Adadelta 和 R M S p r o p RMSprop RMSprop 相同,只不过在更新规则的分子上使用了参数更新均方根
- A d a m Adam Adam 在 R M S p r o p RMSprop RMSprop 的基础上使用了偏移校正和动量
- R M S p r o p RMSprop RMSprop、 A d a d e l t a Adadelta Adadelta 和 A d a m Adam Adam 是相似的算法,在类似的情况的下做的很好。优化快要结束时,梯度变得越来越稀疏,偏移校正使 A d a m Adam Adam 略微超过 R M S p r o p RMSprop RMSprop。目前来说, A d a m Adam Adam 可能是整体优化的最佳选择。
- 训练较深较复杂的网络时,推荐使用学习率自适应的优化方法。