基本框架
定义当前时刻待优化参数 θ t ∈ R \theta_t \in \mathbb R θt∈R,损失函数为 J ( θ ) J(\theta) J(θ),学习率为 η \eta η,参数更新框架为:
1.计算损失函数关于当前参数的梯度:
g
t
=
∇
J
(
θ
t
)
g_t= \nabla J(\theta_t)
gt=∇J(θt)
2.根据历史梯度计算一阶动量和二阶动量:
m
t
=
ϕ
(
g
1
,
g
2
,
.
.
.
,
g
t
)
,
V
t
=
ψ
(
g
1
,
g
2
,
.
.
.
,
g
t
)
m_t=\phi(g_1,g_2,...,g_t),V_t=\psi(g_1,g_2,...,g_t)
mt=ϕ(g1,g2,...,gt),Vt=ψ(g1,g2,...,gt)
- 一阶动量:关于历史梯度的一阶函数
- 二阶动量:关于历史梯度的二阶函数
3.计算当前时刻的下降梯度:
Δ
θ
t
=
−
η
m
t
V
t
\Delta\theta_t=-\eta\frac{m_t}{\sqrt {V_t}}
Δθt=−ηVtmt
4.根据下降梯度更新参数:
θ
t
+
1
=
θ
t
+
Δ
θ
t
\theta_{t+1}=\theta_t+\Delta\theta_t
θt+1=θt+Δθt
SGD
由于SGD没有动量概念,即没有考虑历史梯度,所以当前时刻的一阶动量即为当前时刻的梯度
m
t
=
g
t
m_t=g_t
mt=gt,且二阶动量
V
t
=
E
V_t=E
Vt=E,所以SGD的参数更新公式为
Δ
θ
t
=
−
η
g
t
E
=
−
η
g
t
θ
t
+
1
=
θ
t
+
Δ
θ
t
=
θ
t
−
η
g
t
\Delta\theta_t=-\eta\frac{g_t}{\sqrt E}=-\eta g_t\\ \theta_{t+1}=\theta_t+\Delta\theta_t=\theta_t-\eta g_t
Δθt=−ηEgt=−ηgtθt+1=θt+Δθt=θt−ηgt
Momentum
- 移动指数加权平均值(Exponentially Weighted Moving Average,EWMA)
假设 v t − 1 v_{t-1} vt−1是 t − 1 t-1 t−1时刻的指数加权移动平均值, θ t \theta_t θt是 t t t时刻的观测值,那么 t t t时刻的指数加权移动平均值为
v t = β v t − 1 + ( 1 − β ) θ t = ( 1 − β ) θ t + ∑ i = 1 t − 1 ( 1 − β ) β i θ t − i \begin{aligned} v_t&=\beta v_{t-1}+(1-\beta)\theta_t &\\ &=(1-\beta)\theta_t+\sum_{i=1}^{t-1}(1-\beta)\beta^i\theta_{t-i} \end{aligned} vt=βvt−1+(1−β)θt=(1−β)θt+i=1∑t−1(1−β)βiθt−i
其中, v t − 1 v_{t-1} vt−1被原式递归替换, β \beta β为衰减率, 0 ≤ β < 1 , v 0 = 0 0\le \beta <1,v_0=0 0≤β<1,v0=0。显然,由上式可知, t t t时刻的指数加权平均值其实可以看做前 t t t时刻所有观测值的指数加权平均值,除了第 t t t时刻的观测值权重为 1 − β 1-\beta 1−β外,其它时刻观测值权重为 ( 1 − β ) β i (1-\beta)\beta^i (1−β)βi(指数加权)。由于通常对于那些权重小于 1 e \frac{1}{e} e1的观测值可以忽略不计 (移动窗口),所以忽略掉那些观测值以后,上式子就可以看做在求指数加权移动平均值。
- 哪些项的权重会小于
1
e
\frac{1}{e}
e1呢?由于
l i m n → + ∞ ( 1 − 1 n ) n = 1 e ≈ 0.3679 lim_{n \rightarrow +\infty}(1-\frac{1}{n})^n=\frac{1}{e} \approx0.3679 limn→+∞(1−n1)n=e1≈0.3679
若令 n = 1 1 − β n=\frac{1}{1-\beta} n=1−β1,则
l i m n → + ∞ ( 1 − 1 n ) n = l i m n → + ∞ ( β ) 1 1 − β = 1 e ≈ 0.3679 lim_{n \rightarrow +\infty}(1-\frac{1}{n})^n=lim_{n \rightarrow +\infty}(\beta)^{\frac{1}{1-\beta}}=\frac{1}{e} \approx0.3679 limn→+∞(1−n1)n=limn→+∞(β)1−β1=e1≈0.3679
所以,当 β → 1 \beta \rightarrow1 β→1时,哪些 i ≥ 1 1 − β i \ge \frac{1}{1-\beta} i≥1−β1的 θ t − i \theta_{t-i} θt−i的权重 ( 1 − β ) β i (1-\beta)\beta^i (1−β)βi一定小于 1 e \frac{1}{e} e1。所以指数加权平均值可以近似看做在求最近 1 1 − β \frac{1}{1-\beta} 1−β1个时刻的加权移动平均值, β \beta β常取 ≥ 0.9 \ge0.9 ≥0.9。 - 由于当
t
t
t较小时,指数加权移动平均值的偏差较大,通常会加上一个修正因子
1
−
β
t
1-\beta^t
1−βt,加上修正因子后的公式为
v t = β v t + ( 1 − β ) θ t 1 − β t v_t=\frac{\beta v_t+(1-\beta)\theta_t}{1-\beta^t} vt=1−βtβvt+(1−β)θt
显然,当 t t t很小时,修正因子 1 − β t 1-\beta^t 1−βt会起到作用,当 t t t足够大时修正因子趋于1会自动退场。
- SGD with Momentum
为了一直SGD的震荡,Momentum认为梯度下降过程可以加入惯性,也就是在SGD的基础上引入一阶动量。而所谓一阶动量就是该时刻梯度的指数加权移动平均值: η m t = β m t − 1 + η g t \eta m_t=\beta m_{t-1}+\eta g_t ηmt=βmt−1+ηgt(其中 g t g_t gt并不严格按照指数加权移动平均值的定义采用权重 1 − β 1-\beta 1−β,而是使用我们自定义的学习率 η \eta η,这是一种近似等价)。由于此时仍未使用二阶动量,所以 V t = E V_t=E Vt=E,那么Momentum的参数更新公式为
Δ θ t = − η m t E = − η m t = − ( β m t − 1 + η g t ) θ t + 1 = θ t − ( β m t − 1 + η g t ) \Delta \theta_t=-\eta\frac{m_t}{\sqrt E}=-\eta m_t=-(\beta m_{t-1}+\eta g_t) \\ \theta_{t+1}=\theta_t-(\beta m_{t-1}+\eta g_t) Δθt=−ηEmt=−ηmt=−(βmt−1+ηgt)θt+1=θt−(βmt−1+ηgt)
NAG
除了利用惯性跳出局部沟壑以外,我们可以尝试往前看一步。我们知道momentum在时刻
t
t
t的主要下降方向是由历史梯度(惯性)决定的,当前时刻的梯度权重较小,那不如先看看如果跟着惯性走一步,那个时候外面的世界是怎么样的。也即在momentum的基础上将当前时刻的梯度
g
t
g_t
gt换成下一时刻的梯度
∇
J
(
θ
t
−
β
m
t
−
1
)
\nabla J(\theta_t-\beta m_{t-1})
∇J(θt−βmt−1),由于此时仍然没有用到二阶动量,所以
V
t
=
E
V_t=E
Vt=E,NAG的参数更新公式为
Δ
θ
t
=
−
η
m
t
E
=
−
η
m
t
=
−
(
β
m
t
−
1
+
η
∇
J
(
θ
t
−
β
m
t
−
1
)
)
θ
t
+
1
=
θ
t
−
(
β
m
t
−
1
+
η
∇
J
(
θ
t
−
β
m
t
−
1
)
)
\Delta \theta_t=-\eta \frac{m_t}{\sqrt E}=-\eta m_t=-(\beta m_{t-1}+\eta \nabla J(\theta_t-\beta m_{t-1}))\\ \theta_{t+1}=\theta_t-(\beta m_{t-1}+\eta \nabla J(\theta_t-\beta m_{t-1}))
Δθt=−ηEmt=−ηmt=−(βmt−1+η∇J(θt−βmt−1))θt+1=θt−(βmt−1+η∇J(θt−βmt−1))
AdaGrad
此前我们都没有用到二阶动量。二阶动量的出现,才意味着“自适应学习率”优化算法时代的到来。SGD及其变种一同样的学习率更新每个维度的参数(因为
θ
t
\theta_t
θt通常是向量),但深度神经网络往往包含大量的参数,这些参数并不是总会用的到。对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。因此,AdaGrad则考虑对于不同维度的参数采用不同的学习率。
具体的,对于那些更新幅度很大的参数,通常历史累计梯度的平方和会很大,相反的,对于那些更新幅度很小的参数,通常其累计历史梯度的平方和会很小。所以在一个固定学习率的基础上除以历史累计梯度的平方和就能够使的那些更新幅度很大的参数的学习率变小。同样的也能使得那些更新幅度很小的参数学习率变大,所以AdaGrad的参数更新公式为
v
t
,
i
=
∑
t
=
1
t
g
t
,
i
2
Δ
θ
t
,
i
=
−
η
v
t
,
i
+
ϵ
g
t
,
i
θ
t
+
1
,
i
=
θ
t
,
i
−
η
v
t
,
i
+
ϵ
g
t
,
i
v_{t,i}=\sum_{t=1}^{t}g_{t,i}^2\\ \Delta\theta_{t,i}=-\frac{\eta}{\sqrt{v_{t,i}+\epsilon}}g_{t,i}\\ \theta_{t+1,i}=\theta_{t,i}-\frac{\eta}{\sqrt{v_{t,i}+\epsilon}}g_{t,i}
vt,i=t=1∑tgt,i2Δθt,i=−vt,i+ϵηgt,iθt+1,i=θt,i−vt,i+ϵηgt,i
其中
g
t
,
i
2
g_{t,i}^2
gt,i2表示第
t
t
t时刻第
i
i
i维度参数的梯度值,
ϵ
\epsilon
ϵ是防止分母等于0的平滑项(常取一个很小的值
1
e
−
8
1e-8
1e−8)。显然,此时上式中的
η
v
t
,
i
+
ϵ
\frac{\eta}{\sqrt{v_{t,i}+\epsilon}}
vt,i+ϵη这个整体可以看做是学习率,分母中的历史累计梯度值
v
t
,
i
v_{t,i}
vt,i越大的参数学习率越小。
上式仅仅是第
t
t
t时刻第
i
i
i维度参数的更新公式,对于第
t
t
t时刻的所有维度参数的整体更新公式为
V
t
=
d
i
a
g
(
v
t
,
1
,
v
t
,
2
,
.
.
.
,
v
t
,
d
)
∈
R
d
∗
d
Δ
θ
t
=
−
η
V
t
+
ϵ
g
t
θ
t
+
1
=
θ
t
,
i
−
η
V
t
+
ϵ
g
t
V_t=diag(v_{t,1},v_{t,2},...,v_{t,d}) \in \mathbb{R}^{d*d}\\ \Delta\theta_{t}=-\frac{\eta}{\sqrt{V_{t}+\epsilon}}g_{t}\\ \theta_{t+1}=\theta_{t,i}-\frac{\eta}{\sqrt{V_{t}+\epsilon}}g_{t}
Vt=diag(vt,1,vt,2,...,vt,d)∈Rd∗dΔθt=−Vt+ϵηgtθt+1=θt,i−Vt+ϵηgt
注意,由于
V
t
V_t
Vt是对角矩阵,所以上式中的
ϵ
\epsilon
ϵ只用来平滑
V
t
V_t
Vt对角线上的元素。
缺点:随着时间步数的拉长,历史累计梯度平方和
v
t
,
i
v_{t,i}
vt,i会越来越大,这样会使得所有维度参数的学习率都不断减小(单调递减),无论更新幅度如何。
RMSProp/AdaDelta
由于AdaGrad单调递减的学习率变化过于激进,我们考虑一个改变二阶动量计算方法的策略:不累计全部历史梯度,而只关注过去一段时间窗口的下降梯度,采用momentum中的指数加权平均值的思路。这也就是AdaDelta名称中的Delta的来历。首先看最简单直接版的RMSProp,RMSProp就是在AdaDelta的基础上将普通的历史累计梯度平方和换成指数加权移动平均值,所以只需要将AdaGrad中的
v
t
,
i
v_{t,i}
vt,i的公式改成指数加权移动平均值的形式
v
t
,
i
=
β
v
t
−
1
,
i
+
(
1
−
β
)
g
t
,
i
2
V
t
=
d
i
a
g
(
v
t
,
1
,
v
t
,
2
,
.
.
.
,
v
t
,
d
)
∈
R
d
∗
d
Δ
θ
t
=
−
η
V
t
+
ϵ
g
t
θ
t
+
1
=
θ
t
,
i
−
η
V
t
+
ϵ
g
t
v_{t,i}=\beta v_{t-1,i}+(1-\beta)g_{t,i}^2\\ V_t=diag(v_{t,1},v_{t,2},...,v_{t,d}) \in \mathbb{R}^{d*d}\\ \Delta\theta_{t}=-\frac{\eta}{\sqrt{V_{t}+\epsilon}}g_{t}\\ \theta_{t+1}=\theta_{t,i}-\frac{\eta}{\sqrt{V_{t}+\epsilon}}g_{t}
vt,i=βvt−1,i+(1−β)gt,i2Vt=diag(vt,1,vt,2,...,vt,d)∈Rd∗dΔθt=−Vt+ϵηgtθt+1=θt,i−Vt+ϵηgt
而AdaDelta除了对二阶动量计算指数加权平均以外,还对当前时刻的下降梯度
Δ
θ
t
\Delta \theta_t
Δθt的平方也计算一个指数加权移动平均,具体的
E
[
Δ
θ
2
]
t
,
i
=
γ
E
[
Δ
θ
2
]
t
−
1
,
i
+
(
1
−
γ
)
Δ
θ
t
,
i
2
E[\Delta \theta^2]_{t,i}=\gamma E[\Delta \theta^2]_{t-1,i}+(1-\gamma)\Delta \theta_{t,i}^2
E[Δθ2]t,i=γE[Δθ2]t−1,i+(1−γ)Δθt,i2
由于
θ
t
,
i
2
\theta_{t,i}^2
θt,i2目前是未知的,所以只能用
t
−
1
t-1
t−1时刻的指数加权移动平均来近似替换,也即
E
[
Δ
θ
2
]
t
−
1
,
i
=
γ
E
[
Δ
θ
2
]
t
−
2
,
i
+
(
1
−
γ
)
Δ
θ
t
−
1
,
i
2
E[\Delta \theta^2]_{t-1,i}=\gamma E[\Delta \theta^2]_{t-2,i}+(1-\gamma)\Delta \theta_{t-1,i}^2
E[Δθ2]t−1,i=γE[Δθ2]t−2,i+(1−γ)Δθt−1,i2
除了计算出
t
−
1
t-1
t−1时刻的指数加权移动平均以外,AdaDelta还用此值替换我们预先设置的学习率
η
\eta
η
因此,AdaDelta的参数更新公式为
v
t
,
i
=
β
v
t
−
1
,
i
+
(
1
−
β
)
g
t
,
i
2
V
t
=
d
i
a
g
(
v
t
,
1
,
v
t
,
2
,
.
.
.
,
v
t
,
d
)
∈
R
d
∗
d
E
[
Δ
θ
2
]
t
,
i
=
γ
E
[
Δ
θ
2
]
t
−
1
,
i
+
(
1
−
γ
)
Δ
θ
t
,
i
2
Θ
t
=
d
i
a
g
(
E
[
Δ
θ
2
]
t
−
1
,
1
,
E
[
Δ
θ
2
]
t
−
1
,
2
,
.
.
.
,
E
[
Δ
θ
2
]
t
−
1
,
d
)
∈
R
d
∗
d
Δ
θ
t
=
−
Θ
t
+
ϵ
V
t
+
ϵ
g
t
θ
t
+
1
=
θ
t
,
i
−
Θ
t
+
ϵ
V
t
+
ϵ
g
t
v_{t,i}=\beta v_{t-1,i}+(1-\beta)g_{t,i}^2\\ V_t=diag(v_{t,1},v_{t,2},...,v_{t,d}) \in \mathbb{R}^{d*d}\\ E[\Delta \theta^2]_{t,i}=\gamma E[\Delta \theta^2]_{t-1,i}+(1-\gamma)\Delta \theta_{t,i}^2\\ \Theta_t=diag(E[\Delta \theta^2]_{t-1,1},E[\Delta \theta^2]_{t-1,2,...,E[\Delta \theta^2]_{t-1,d}}) \in \mathbb {R}^{d*d}\\ \Delta\theta_{t}=-\frac{\sqrt{\Theta_t+\epsilon}}{\sqrt{V_{t}+\epsilon}}g_{t}\\ \theta_{t+1}=\theta_{t,i}-\frac{\sqrt{\Theta_t+\epsilon}}{\sqrt{V_{t}+\epsilon}}g_{t}
vt,i=βvt−1,i+(1−β)gt,i2Vt=diag(vt,1,vt,2,...,vt,d)∈Rd∗dE[Δθ2]t,i=γE[Δθ2]t−1,i+(1−γ)Δθt,i2Θt=diag(E[Δθ2]t−1,1,E[Δθ2]t−1,2,...,E[Δθ2]t−1,d)∈Rd∗dΔθt=−Vt+ϵΘt+ϵgtθt+1=θt,i−Vt+ϵΘt+ϵgt
显然,对于AdaDelta算法来说,已经不需要我们自己预设学习率了,只需要预设
β
\beta
β和
γ
\gamma
γ这两个指数加权移动平均值的衰减率即可。
Adam
Adam和Nadam是前述方法的集成者。我们看到,momentum在SGD基础上增加了一阶动量,AdaGrad在SGD基础上增加了二阶动量。把一阶动量和二阶动量都用起来,就是Adam
具体的,首先计算一阶动量:
m
t
=
β
1
m
t
−
1
+
(
1
−
β
1
)
g
t
m_t=\beta_1m_{t-1}+(1-\beta_1)g_t
mt=β1mt−1+(1−β1)gt
然后计算二阶动量
v
t
,
i
=
β
v
t
−
1
,
i
+
(
1
−
β
)
g
t
,
i
2
V
t
=
d
i
a
g
(
v
t
,
1
,
v
t
,
2
,
.
.
.
,
v
t
,
d
)
∈
R
d
∗
d
v_{t,i}=\beta v_{t-1,i}+(1-\beta)g_{t,i}^2\\ V_t=diag(v_{t,1},v_{t,2},...,v_{t,d}) \in \mathbb{R}^{d*d}\\
vt,i=βvt−1,i+(1−β)gt,i2Vt=diag(vt,1,vt,2,...,vt,d)∈Rd∗d
然后分别加上指数加权移动平均值的修正因子
m
^
t
=
m
t
1
−
β
1
t
v
^
t
,
i
=
v
t
,
i
1
−
β
2
t
V
^
t
=
d
i
a
g
(
v
^
t
,
1
,
v
^
t
,
2
,
.
.
.
,
v
^
t
,
d
)
∈
R
d
∗
d
\hat m_t=\frac{m_t}{1-\beta_1^t}\\ \hat v_{t,i}=\frac{v_{t,i}}{1-\beta_2^t}\\ \hat V_t=diag(\hat v_{t,1},\hat v_{t,2},...,\hat v_{t,d}) \in \mathbb{R}^{d*d}\\
m^t=1−β1tmtv^t,i=1−β2tvt,iV^t=diag(v^t,1,v^t,2,...,v^t,d)∈Rd∗d
所以,Adam的参数更新公式
Δ
θ
t
=
−
η
V
^
t
+
ϵ
m
^
t
θ
t
+
1
=
θ
t
−
η
V
^
t
+
ϵ
m
^
t
\Delta\theta_{t}=-\frac{\eta}{\sqrt{\hat V_{t}+\epsilon}}\hat m_{t}\\ \theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat V_{t}+\epsilon}}\hat m_{t}
Δθt=−V^t+ϵηm^tθt+1=θt−V^t+ϵηm^t
Nadam
基于Adam考虑未来因素
θ
t
+
1
=
θ
t
−
η
V
^
t
+
ϵ
m
^
t
=
θ
t
−
η
V
^
t
+
ϵ
(
β
1
m
t
−
1
1
−
β
1
t
+
(
1
−
β
1
)
g
t
1
−
β
1
t
)
\theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat V_{t}+\epsilon}}\hat m_{t}=\theta_{t}-\frac{\eta}{\sqrt{\hat V_{t}+\epsilon}}(\frac{\beta_1 m_{t-1}}{1-\beta_1^t}+\frac{(1-\beta_1)g_t}{1-\beta_1^t})
θt+1=θt−V^t+ϵηm^t=θt−V^t+ϵη(1−β1tβ1mt−1+1−β1t(1−β1)gt)
此时,如果我们将
t
−
1
t-1
t−1时刻的动量
m
t
−
1
m_{t-1}
mt−1用
t
t
t时刻的动量
m
t
m_t
mt近似替代的话,那么我们就引入了未来因素,所以将
m
t
−
1
m_{t-1}
mt−1替换成
m
t
m_t
mt即得到式子
θ
t
+
1
=
θ
t
−
η
V
^
t
+
ϵ
(
β
1
m
t
1
−
β
1
t
+
(
1
−
β
1
)
g
t
1
−
β
1
t
)
=
θ
t
−
η
V
^
t
+
ϵ
(
β
1
m
^
t
+
(
1
−
β
1
)
g
t
1
−
β
1
t
)
\theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat V_{t}+\epsilon}}(\frac{\beta_1 m_{t}}{1-\beta_1^t}+\frac{(1-\beta_1)g_t}{1-\beta_1^t})=\theta_{t}-\frac{\eta}{\sqrt{\hat V_{t}+\epsilon}}(\beta_1 \hat m_t+\frac{(1-\beta_1)g_t}{1-\beta_1^t})
θt+1=θt−V^t+ϵη(1−β1tβ1mt+1−β1t(1−β1)gt)=θt−V^t+ϵη(β1m^t+1−β1t(1−β1)gt)
参考
datawhale串讲深度学习中的优化算法