参考:https://zhuanlan.zhihu.com/p/32230623
仅用作个人记录
通用公式
g t = ▽ f ( w t ) 根 据 l o s s 计 算 出 的 梯 度 值 m t = ϕ ( g 1 , g 2 , . . . , g t ) 根 据 过 去 梯 度 惯 性 和 当 前 梯 度 算 出 的 一 阶 动 量 V t = φ ( g 1 , g 2 , . . . , g t ) 根 据 过 去 梯 度 和 当 前 梯 度 算 出 的 二 阶 动 量 η t = α V t ∗ m t 根 据 一 阶 和 二 阶 动 量 以 及 学 习 率 α 计 算 需 要 更 新 的 梯 度 w t + 1 = w t − η t 更 新 梯 度 g_t = \triangledown f(w_t) \qquad \tiny{根据loss计算出的梯度值} \\ \normalsize{m_t = \phi (g_1, g_2, ..., g_t)} \qquad \tiny{根据过去梯度惯性和当前梯度算出的一阶动量} \\ \normalsize{V_t = \varphi (g_1, g_2, ..., g_t)} \qquad \tiny{根据过去梯度和当前梯度算出的二阶动量} \\ \normalsize{\eta_t = \frac{\alpha}{\sqrt{V_t}}*m_t} \qquad \tiny{根据一阶和二阶动量以及学习率\alpha计算需要更新的梯度} \\ \normalsize{w_{t+1} = w_t - \eta_t} \qquad \tiny{更新梯度} gt=▽f(wt)根据loss计算出的梯度值mt=ϕ(g1,g2,...,gt)根据过去梯度惯性和当前梯度算出的一阶动量Vt=φ(g1,g2,...,gt)根据过去梯度和当前梯度算出的二阶动量ηt=Vtα∗mt根据一阶和二阶动量以及学习率α计算需要更新的梯度wt+1=wt−ηt更新梯度
传统SGD优化器:不考虑一阶动量和二阶动量,直接根据当前梯度优化参数
m t = g t , V t = 1 , η t = α ∗ g t , w t + 1 = w t − η t m_t = g_t, \quad V_t=1, \quad \eta_t = \alpha * g_t, \quad w_{t+1} = w_t - \eta_t mt=gt,Vt=1,ηt=α∗gt,wt+1=wt−ηt
缺点:没有考虑以往梯度的惯性,梯度下降速度慢。且容易陷入局部最优解
SGDM:加入一阶动量moment(各个时刻梯度方向的移动平均值)
m t = β 1 ∗ m t − 1 + ( 1 − β 1 ) ∗ g t , β 1 = 0.9 m_t = \beta_1*m_{t-1} + (1-\beta_1)*g_t, \; \beta_1=0.9 mt=β1∗mt−1+(1−β1)∗gt,β1=0.9
特性:可以看到当前迭代的梯度下降绝大部分依托于以往的梯度惯性,额外考虑了些当前的梯度方向。
缺点:因额外增加了以往的惯性,容易导致梯度下降过猛导致震荡
SGD with NAG(nesterov accelerated gradient),为了防止梯度下降过猛,按照上一迭代的梯度下降作为参考来预测下一迭代的梯度,并将其加入到通用式①来计算当前迭代的梯度
g t = ▽ f ( w t − α V t ∗ m t − 1 ) g_t = \triangledown f(w_t - \frac{\alpha}{\sqrt{V_t}}*m_{t-1}) gt=▽f(wt−Vtα∗mt−1)
以上SGD只考虑了一阶动量,并且针对于所有参数等学习率看待。然而我们希望对经常更新的参数赋予更小的学习率,因为已经获得了大量的只是来更新这些参数。对于不常更新的参数,我们希望获得更多的信息来更新,因此希望有更大的学习率。因此我们希望能够自适应的来调整学习率更新模型参数,这个可以通过二阶动量来解决。
Adagrad
V
t
=
∑
τ
=
1
t
g
τ
2
,
η
t
=
α
V
t
∗
m
t
V_t=\sum_{\tau=1}^{t} g_{\tau}^2, \quad \eta_t=\frac{\alpha}{V_t}*m_t
Vt=τ=1∑tgτ2,ηt=Vtα∗mt
V
t
V_t
Vt对于经常更新的
g
t
g_t
gt会更大,因此学习率会自动减小。然而由于
V
t
V_t
Vt是单调递增函数,因此有可能使得学习率迅速下降接近于0,过早结束训练。
Rmsprop:上述的 V t V_t Vt是过去所有梯度的平方和,为了解决过早结束训练的问题,我们通过动量移动平均的方式,只关注过去一段时间的梯度来计算二阶动量
V t = β 2 ∗ V t − 1 + ( 1 − β 2 ) ∗ V t , β 2 = 0.999 V_t = \beta_2 * V_{t-1} + (1-\beta_2) * V_t, \quad \beta_2=0.999 Vt=β2∗Vt−1+(1−β2)∗Vt,β2=0.999
Adam:同时考虑一阶动量和二阶动量,自适应更新参数
m
t
=
β
1
∗
m
t
−
1
+
(
1
−
β
1
)
∗
g
t
,
β
1
=
0.9
V
t
=
β
2
∗
V
t
−
1
+
(
1
−
β
2
)
∗
V
t
,
β
2
=
0.999
,
w
t
+
1
=
w
t
−
α
V
t
∗
m
t
m_t = \beta_1*m_{t-1} + (1-\beta_1)*g_t, \; \beta_1=0.9 \\ V_t = \beta_2 * V_{t-1} + (1-\beta_2) * V_t, \quad \beta_2=0.999, \\ w_{t+1} = w_t - \frac{\alpha}{\sqrt{V_t}}*m_t
mt=β1∗mt−1+(1−β1)∗gt,β1=0.9Vt=β2∗Vt−1+(1−β2)∗Vt,β2=0.999,wt+1=wt−Vtα∗mt
初始化:
m
0
=
0
,
V
0
=
0
m_0 = 0, V_0 = 0
m0=0,V0=0
然而,按照上述计算公式,训练初期梯度都接近于0,不利于训练,所以需要对梯度进行修正:
m
t
~
=
m
t
1
−
β
1
t
,
V
t
~
=
V
t
1
−
β
2
t
\widetilde{m_t} = \frac{m_t}{1-\beta_1^t}, \\ \widetilde{V_t} = \frac{V_t}{1-\beta_2^t}
mt
=1−β1tmt,Vt
=1−β2tVt
Nadam:Adam + NaG