待优化参数:
ω
\omega
ω 目标函数:
f
(
x
)
f(x)
f(x) 初始学习率:
α
\alpha
α 迭代epoch:
t
t
t
参数更新步骤如下:
Ⅰ.计算目标函数关于当前参数的梯度:
g
t
=
∇
f
(
ω
t
)
g_t=\nabla{f(\omega_t)}
gt=∇f(ωt) Ⅱ. 根据历史梯度计算一阶动量和二阶动量:
m
t
=
∅
(
g
1
,
g
2
,
.
.
.
.
,
g
t
)
V
t
=
∑
i
=
0
t
x
i
2
m_t=\varnothing(g1,g2,....,gt)\\V_t=\sum_{i=0}^tx_i^2
mt=∅(g1,g2,....,gt)Vt=∑i=0txi2 Ⅲ. 计算当前时刻的下降梯度:
η
t
=
α
⋅
m
t
/
V
t
\eta_t=\alpha \cdot {m_t}/\sqrt{V_t}
ηt=α⋅mt/Vt Ⅳ. 根据下降梯度进行更新参数:
ω
t
+
1
=
ω
t
−
η
t
\omega_{t+1}=\omega_t-\eta_t
ωt+1=ωt−ηt 步骤Ⅲ、Ⅳ对于各个算法都是一致的,主要的差别就体现在步骤Ⅰ、Ⅱ上
常见方法
随机梯度下降法(Stochastic Gradient Descent,SGD)
每次从训练集中随机选择一个样本来进行学习,SGD没有动量的概念
m
t
=
g
t
;
V
t
=
I
2
m_t=g_t;V_t=I^2
mt=gt;Vt=I2
η
t
=
α
⋅
g
t
g
t
\eta_t=\alpha \cdot {g_t} \qquad g_t
ηt=α⋅gtgt是当前参数的梯度
ω
t
+
1
=
ω
t
−
η
t
=
ω
t
−
α
⋅
g
t
\omega_{t+1}=\omega_t-\eta_t=\omega_t-\alpha \cdot {g_t}
ωt+1=ωt−ηt=ωt−α⋅gt
在SGD基础上引入了一阶动量:
m
t
=
β
1
⋅
m
t
−
1
+
(
1
−
β
1
)
⋅
g
t
m_t=\beta_1 \cdot m_{t-1}+(1-\beta_1)\cdot {g_t}
mt=β1⋅mt−1+(1−β1)⋅gt
ω
t
+
1
=
ω
t
−
α
⋅
m
t
=
ω
t
−
α
⋅
(
β
1
⋅
m
t
−
1
+
(
1
−
β
1
)
⋅
g
t
)
\omega_{t+1}=\omega_t-\alpha\cdot m_t=\omega_t-\alpha \cdot (\beta_1 \cdot m_{t-1}+(1-\beta_1)\cdot {g_t})
ωt+1=ωt−α⋅mt=ωt−α⋅(β1⋅mt−1+(1−β1)⋅gt)
NAG在步骤Ⅰ,不计算当前位置的梯度方向,而是计算如果按照累积动量走了一步,那个时候的下降方向:
g
t
=
∇
f
(
ω
−
α
⋅
m
t
−
1
/
V
t
−
1
)
g_t=\nabla{f(\omega-\alpha\cdot m_{t-1}/\sqrt{V_{t-1}})}
gt=∇f(ω−α⋅mt−1/Vt−1)
参数更新公式如下
ω
t
+
1
=
ω
t
−
α
⋅
g
t
=
ω
t
−
α
∗
(
∇
f
(
ω
−
α
⋅
m
t
−
1
/
V
t
−
1
)
)
\omega_{t+1}=\omega_t-\alpha\cdot g_t=\omega_t-\alpha*(\nabla{f(\omega-\alpha\cdot m_{t-1}/\sqrt{V_{t-1}})})
ωt+1=ωt−α⋅gt=ωt−α∗(∇f(ω−α⋅mt−1/Vt−1))
然后用下一个点的梯度方向,与历史累积动量相结合,计算步骤Ⅱ中当前时刻的累积动量
有利于跳出当前局部最优的沟壑,寻找新的最优值,但是收敛速度慢
AdaGrad(自适应学习率算法)
SGD系列的都没有用到二阶动量。二阶动量的出现,才意味着“自适应学习率”优化算法时代的到来
二阶动量——该维度上,记录到目前为止所有梯度值的平方和
V
t
=
∑
τ
=
1
t
g
τ
2
V_t=\sum_{\tau=1}^tg_{\tau}^2
Vt=∑τ=1tgτ2
AdaGrad参数更新公式
ω
t
+
1
=
ω
t
−
α
⋅
m
t
/
V
t
=
ω
−
α
⋅
m
t
/
∑
τ
=
1
t
g
τ
2
\omega_{t+1}=\omega_t-\alpha\cdot m_t/\sqrt{V_t}=\omega-\alpha \cdot m_t/\sqrt{\sum_{\tau=1}^tg_\tau^2}
ωt+1=ωt−α⋅mt/Vt=ω−α⋅mt/∑τ=1tgτ2
此时实质上的学习率由
α
\alpha
α变成了
α
/
V
t
\alpha/\sqrt{V_t}
α/Vt,一般为了避免分母为0,会在分母上加一个小的平滑项,因此
V
t
\sqrt{V_t}
Vt是恒大于0的,而且参数更新越频繁,二阶动量越大,学习率就越小
V
t
=
β
2
⋅
V
t
−
1
+
(
1
−
β
2
)
g
t
2
V_t=\beta_2 \cdot V_{t-1}+(1-\beta_2)g^2_t
Vt=β2⋅Vt−1+(1−β2)gt2
AdaDelta / RMSProp参数更新公式
ω
t
+
1
=
ω
t
−
α
⋅
m
t
/
V
t
=
ω
−
α
⋅
m
t
/
β
2
⋅
V
t
−
1
+
(
1
−
β
2
)
g
t
2
\omega_{t+1}=\omega_t-\alpha\cdot m_t/\sqrt{V_t}=\omega-\alpha \cdot m_t/\sqrt{\beta_2 \cdot V_{t-1}+(1-\beta_2)g^2_t}
ωt+1=ωt−α⋅mt/Vt=ω−α⋅mt/β2⋅Vt−1+(1−β2)gt2
避免了二阶动量持续累积、导致训练过程提前结束的问题了
Adam
把一阶动量和二阶动量都用起来,就是Adam了——Adaptive + Momentum
SGD的一阶动量:
m
t
=
β
1
⋅
m
t
−
1
+
(
1
−
β
1
)
⋅
g
t
m_t=\beta_1 \cdot m_{t-1}+(1-\beta_1)\cdot {g_t}
mt=β1⋅mt−1+(1−β1)⋅gt
加上AdaDelta的二阶动量:
V
t
=
β
2
⋅
V
t
−
1
+
(
1
−
β
2
)
g
t
2
V_t=\beta_2 \cdot V_{t-1}+(1-\beta_2)g^2_t
Vt=β2⋅Vt−1+(1−β2)gt2
Adam参数更新公式
ω
t
+
1
=
ω
t
−
α
⋅
m
t
/
V
t
=
ω
−
α
⋅
(
β
1
⋅
m
t
−
1
+
(
1
−
β
1
)
⋅
g
t
)
/
β
2
⋅
V
t
−
1
+
(
1
−
β
2
)
g
t
2
\omega_{t+1}=\omega_t-\alpha\cdot m_t/\sqrt{V_t}\\\qquad=\omega-\alpha \cdot (\beta_1 \cdot m_{t-1}+(1-\beta_1)\cdot {g_t})/\sqrt{\beta_2 \cdot V_{t-1}+(1-\beta_2)g^2_t}
ωt+1=ωt−α⋅mt/Vt=ω−α⋅(β1⋅mt−1+(1−β1)⋅gt)/β2⋅Vt−1+(1−β2)gt2
二阶动量是固定时间窗口内的累积,随着时间窗口的变化,遇到的数据可能发生巨变,使得
V
t
V_t
Vt可能时大时小,不是单调变化。可能引起学习率震荡,模型无法收敛
修正方法
V
t
=
m
a
x
(
β
2
∗
V
t
−
1
+
(
1
−
β
2
)
g
t
2
,
V
t
−
1
)
V_t=max(\beta_2*V_{t-1}+(1-\beta_2)g_t^2,V_{t-1})
Vt=max(β2∗Vt−1+(1−β2)gt2,Vt−1) 保证
∣
∣
V
t
∣
∣
>
=
∣
∣
V
t
−
1
∣
∣
||V_t||>=||V_{t-1}||
∣∣Vt∣∣>=∣∣Vt−1∣∣,使得学习率单调递减