前言
个人对于深度学习的优化一直是未知,所以对此一直充满了疑问,今天休闲读的时候刚好看到书上有关于优化算法的汇总,为方便今后查阅将它copy下来。
SGD(随机梯度下降算法)
参数: 学习率
η
\eta
η
初始化:
θ
\theta
θ
while 停止条件未满足 do:
从 训练数据中抽取m条数据
{
x
(
1
)
,
x
(
2
)
,
x
(
3
)
,
.
.
.
,
x
(
m
)
}
\{x^{(1)}, x^{(2)}, x^{(3)}, ... , x^{(m)}\}
{x(1),x(2),x(3),...,x(m)}及对应的标签
{
y
(
1
)
,
y
(
2
)
,
y
(
3
)
,
.
.
.
,
y
(
m
)
}
\{y^{(1)}, y^{(2)}, y^{(3)}, ... , y^{(m)}\}
{y(1),y(2),y(3),...,y(m)}
计算梯度:
g
(
θ
)
=
∂
1
m
∑
i
=
1
m
L
(
f
(
x
(
i
)
,
y
(
i
)
)
)
∂
θ
g(\theta) = \frac{\partial \frac{1}{m} \sum_{i=1}^mL(f(x^{(i)}, y^{(i)}))}{\partial \theta}
g(θ)=∂θ∂m1∑i=1mL(f(x(i),y(i)))
跟新参数:
θ
=
θ
−
η
.
g
(
θ
)
\theta = \theta - \eta . g(\theta)
θ=θ−η.g(θ)
end while
Momentum
动量(Momentum) 是来自中学物理中力学中的概念,是力的时间积累效应的度量。动量的方法在随机梯度下降的基础上,加上了上一步的梯度:
m
t
=
γ
m
t
−
1
+
g
(
θ
)
m_t = \gamma m_{t-1}+g(\theta)
mt=γmt−1+g(θ)
θ
=
θ
−
η
m
t
\theta = \theta - \eta m_t
θ=θ−ηmt
相比随机梯度下降,动量对使相同的梯度不断累加,而不同方向的梯度则相互抵消,因而可以在一定程度上克服Z字形的震荡,更快的到达最优点。
带动量的随机梯度下降算法。
参数:学习率
η
\eta
η, 动量
μ
\mu
μ
初始化:
θ
\theta
θ
while 停止条件未满足 do:
从训练数据中抽取m条数据
{
x
(
1
)
,
x
(
2
)
,
x
(
3
)
,
.
.
.
,
x
(
m
)
}
\{x^{(1)}, x^{(2)}, x^{(3)}, ... , x^{(m)}\}
{x(1),x(2),x(3),...,x(m)}及对应的标签
{
y
(
1
)
,
y
(
2
)
,
y
(
3
)
,
.
.
.
,
y
(
m
)
}
\{y^{(1)}, y^{(2)}, y^{(3)}, ... , y^{(m)}\}
{y(1),y(2),y(3),...,y(m)}。
计算梯度:
g
(
θ
)
=
∂
1
m
∑
i
=
1
m
L
(
f
(
x
(
i
)
,
y
(
i
)
)
)
∂
θ
g(\theta) = \frac{\partial \frac{1}{m} \sum_{i=1}^mL(f(x^{(i)}, y^{(i)}))}{\partial \theta}
g(θ)=∂θ∂m1∑i=1mL(f(x(i),y(i)))
更新参数:
(1)
m
t
=
γ
m
t
−
1
+
g
(
θ
)
m_t =\gamma m_{t-1}+g(\theta)
mt=γmt−1+g(θ)
(2)
θ
t
+
1
=
θ
t
−
η
m
t
\theta_{t+1} = \theta_t - \eta m_t
θt+1=θt−ηmt
NAG
NAG 加速梯度(Nester Accelerated Gradient, NAG) 与动量;类似,也是考虑最近的梯度情况但是NAG相对超前一点,他先使用动量
m
t
m_t
mt计算参数
θ
\theta
θ的下一个位置,然后在近似计算梯度:
m
t
=
γ
m
t
−
1
+
g
(
θ
t
−
η
γ
m
t
−
1
)
m_t = \gamma m_{t-1} + g(\theta_t - \eta \gamma m_{t-1})
mt=γmt−1+g(θt−ηγmt−1)
θ
t
+
1
=
θ
t
−
η
m
t
\theta_{t+1} = \theta_t - \eta m_t
θt+1=θt−ηmt
算法如下:
参数:学习率
η
\eta
η, 动量衰减率
γ
\gamma
γ.
初始化:
θ
\theta
θ
while 停止条件未满足 do:
从训练数据中抽取m条数据
{
x
(
1
)
,
x
(
2
)
,
x
(
3
)
,
}
\{x^{(1)}, x^{(2)}, x^{(3)}, \}
{x(1),x(2),x(3),}及对应的标签
y
(
1
)
,
y
(
2
)
,
y
(
3
)
,
.
.
.
,
y
(
m
)
{y^{(1)}, y^{(2)}, y^{(3)}, ..., y^{(m)}}
y(1),y(2),y(3),...,y(m)
计算梯度:
g
(
θ
)
=
∂
1
m
∑
i
=
1
m
L
(
f
(
x
(
i
)
,
y
(
i
)
)
)
∂
θ
g(\theta) = \frac{\partial \frac{1}{m} \sum_{i=1}^mL(f(x^{(i)}, y^{(i)}))}{\partial \theta}
g(θ)=∂θ∂m1∑i=1mL(f(x(i),y(i)))
更新梯度积累量:
G
t
=
γ
G
t
−
1
+
(
1
−
γ
)
g
2
(
θ
)
G_t = \gamma G_{t-1}+(1-\gamma)g^2(\theta)
Gt=γGt−1+(1−γ)g2(θ)
更新参数:
θ
t
+
1
=
θ
t
−
η
G
t
+
ϵ
⨀
g
(
θ
)
\theta_{t+1} = \theta_{t}- \frac{\eta}{\sqrt{G_t+\epsilon}}\bigodot g(\theta)
θt+1=θt−Gt+ϵη⨀g(θ)
Adadelta
Adadelta算法
参数:学习率
η
\eta
η, 微小量
ϵ
\epsilon
ϵ,梯度累计量G,衰减率
γ
\gamma
γ.
初始化:
θ
\theta
θ
while 停止条件未满足 do:
从训练数据中抽取m条数据
x
(
1
)
,
x
(
2
)
,
.
.
.
.
.
,
x
(
m
)
{x^{(1)}, x^{(2)}, ....., x^{(m)}}
x(1),x(2),.....,x(m)及对应的标签
计算梯度:
g
(
θ
)
=
∂
1
m
∑
i
=
1
m
L
(
f
(
x
(
i
)
,
y
(
i
)
)
)
∂
θ
g(\theta) = \frac{\partial \frac{1}{m} \sum_{i=1}^mL(f(x^{(i)}, y^{(i)}))}{\partial \theta}
g(θ)=∂θ∂m1∑i=1mL(f(x(i),y(i)))
更新梯度积累量:
G
t
=
γ
G
t
−
1
+
(
1
−
γ
)
g
2
(
θ
)
G_t = \gamma G_{t-1}+(1-\gamma)g^2(\theta)
Gt=γGt−1+(1−γ)g2(θ)
计算参数相关积累量:
Δ
t
=
γ
Δ
t
−
1
+
(
1
−
γ
)
Δ
θ
t
2
\Delta_t = \gamma \Delta_{t-1}+(1-\gamma)\Delta \theta_t^2
Δt=γΔt−1+(1−γ)Δθt2
更新参数:
θ
t
+
1
=
θ
t
+
Δ
θ
\theta_{t+1} = \theta_t + \Delta \theta
θt+1=θt+Δθ
end while
Adam
短发全称为 Adaptive Moment Estimation ,这种方法结合了上面提到的两类算法:基于梯度和基于自适应学习率的算法。基于动量的算法有动量法和NAG法, 这两种方法都基于历史的梯度信息进行参数跟新 ,基于自适应的算法有Adagrad, RM-SProp, Adadelta,他们通过计算梯度的积累量来调整不同的参数的更新量,Adam算法记录了梯度的一阶矩(梯度的期望值),和二阶矩(梯度平方的期望值)。
参数:学习率
η
\eta
η, 微小量,一阶矩
m
t
^
\hat{m_t}
mt^二阶矩
v
t
^
\hat{v_t}
vt^,衰减率
β
1
,
β
2
\beta_1, \beta_2
β1,β2
初始化:
θ
\theta
θ
while 停止条件未满足 do:
从训练数据中抽取m条数据
{
x
(
1
)
,
x
(
2
)
,
x
(
m
)
}
\{x^{(1)}, x^{(2)}, x^{(m)}\}
{x(1),x(2),x(m)}及对应的标签
{
y
(
1
)
,
y
(
2
)
,
y
(
m
)
}
\{y^{(1)}, y^{(2)}, y^{(m)}\}
{y(1),y(2),y(m)}。
计算梯度:
g
(
θ
)
=
∂
(
1
m
∑
i
=
1
m
)
L
(
f
(
x
(
i
)
,
y
(
i
)
)
)
∂
θ
g(\theta) = \frac{\partial (\frac{1}{m} \sum_{i=1}^m)L(f(x^{(i)}, y^{(i)}))}{\partial \theta}
g(θ)=∂θ∂(m1∑i=1m)L(f(x(i),y(i)))
更新一阶矩:
m
t
=
β
1
m
t
−
1
+
(
1
−
β
1
)
g
(
θ
)
m_t = \beta_1m_{t-1}+(1-\beta_1)g(\theta)
mt=β1mt−1+(1−β1)g(θ)
更新二阶矩:
v
t
=
β
2
v
t
−
1
+
(
1
−
β
2
)
g
2
(
θ
)
v_t = \beta_2v_{t-1}+(1-\beta_2)g^2(\theta)
vt=β2vt−1+(1−β2)g2(θ)
纠正一阶矩:
m
t
^
=
m
t
1
−
β
1
t
\hat{m_t} = \frac{m_t}{1-\beta_1^t}
mt^=1−β1tmt
纠正二阶矩:
v
t
^
=
v
t
1
−
β
2
t
\hat{v_t} = \frac{v_t}{1-\beta_2^t}
vt^=1−β2tvt
计算参数更新量:
Δ
θ
=
−
η
v
t
^
+
ϵ
⨀
m
t
^
\Delta \theta = - \frac{\eta}{\sqrt{\hat{v_t}}+\epsilon} \bigodot \hat{m_t}
Δθ=−vt^+ϵη⨀mt^
更新参数:
θ
t
+
1
=
θ
t
+
Δ
θ
\theta_{t+1} = \theta_t +\Delta \theta
θt+1=θt+Δθ
end while
AdaMax
AdaMax 算法主要对Adam算法进行了修改,将二阶矩修改为无穷矩,这样数值上更加稳定:
AdaMax 算法:
参数:学习率
η
\eta
η, 微小量
ϵ
\epsilon
ϵ,一介矩
m
t
^
\hat{m_t}
mt^, 二阶矩
v
t
^
\hat{v_t}
vt^,衰减率
β
1
\beta_1
β1,
β
2
\beta_2
β2
初始化:
θ
\theta
θ
while 停止条件未满足 do:
从训练数据中抽取m条数据
{
x
(
1
)
,
x
(
2
)
,
x
(
m
)
}
\{x^{(1)}, x^{(2)}, x^{(m)}\}
{x(1),x(2),x(m)}及对应的标签
{
y
(
1
)
,
y
(
2
)
,
y
(
m
)
}
\{y^{(1)}, y^{(2)}, y^{(m)}\}
{y(1),y(2),y(m)}。
计算梯度:
g
(
θ
)
=
∂
(
1
m
∑
i
=
1
m
)
L
(
f
(
x
(
i
)
,
y
(
i
)
)
)
∂
θ
g(\theta) = \frac{\partial (\frac{1}{m} \sum_{i=1}^m)L(f(x^{(i)}, y^{(i)}))}{\partial \theta}
g(θ)=∂θ∂(m1∑i=1m)L(f(x(i),y(i)))
更新一阶矩:
m
t
=
β
1
m
t
−
1
+
(
1
−
β
1
)
g
(
θ
)
m_t = \beta_1m_{t-1}+(1-\beta_1)g(\theta)
mt=β1mt−1+(1−β1)g(θ)
更新二阶矩:
u
t
=
max
(
β
2
u
t
−
1
+
∣
g
(
θ
)
∣
)
u_t = \max(\beta_2u_{t-1}+|g(\theta)|)
ut=max(β2ut−1+∣g(θ)∣)
纠正一阶矩:
m
t
^
=
m
t
1
−
β
1
t
\hat{m_t} = \frac{m_t}{1-\beta_1^t}
mt^=1−β1tmt
计算参数更新量:
Δ
θ
=
−
η
u
t
^
+
ϵ
⨀
m
t
^
\Delta \theta = - \frac{\eta}{\sqrt{\hat{u_t}}+\epsilon} \bigodot \hat{m_t}
Δθ=−ut^+ϵη⨀mt^
更新参数:
θ
t
+
1
=
θ
t
+
Δ
θ
\theta_{t+1} = \theta_t +\Delta \theta
θt+1=θt+Δθ
end while
Nadam
6.8节的AdaMax算法修改了二阶矩的估计值,本节的算法则修改了一阶距的估计值,将Nesterov算法和Adam算法结合起来,形成了Nadam(Nesterov-accelerated Adaptive Moment Estimation)算法。
参数:学习率
η
\eta
η, 微小量
ϵ
\epsilon
ϵ,一介矩
m
t
^
\hat{m_t}
mt^, 二阶矩
v
t
^
\hat{v_t}
vt^,衰减率
β
1
\beta_1
β1,
β
2
\beta_2
β2
初始化:
θ
\theta
θ
while 停止条件未满足 do:
从训练数据中抽取m条数据
{
x
(
1
)
,
x
(
2
)
,
x
(
m
)
}
\{x^{(1)}, x^{(2)}, x^{(m)}\}
{x(1),x(2),x(m)}及对应的标签
{
y
(
1
)
,
y
(
2
)
,
y
(
m
)
}
\{y^{(1)}, y^{(2)}, y^{(m)}\}
{y(1),y(2),y(m)}。
计算梯度:
g
(
θ
)
=
∂
(
1
m
∑
i
=
1
m
)
L
(
f
(
x
(
i
)
,
y
(
i
)
)
)
∂
θ
g(\theta) = \frac{\partial (\frac{1}{m} \sum_{i=1}^m)L(f(x^{(i)}, y^{(i)}))}{\partial \theta}
g(θ)=∂θ∂(m1∑i=1m)L(f(x(i),y(i)))
更新一阶矩:
m
t
=
β
1
m
t
−
1
+
(
1
−
β
1
)
g
(
θ
)
m_t = \beta_1m_{t-1}+(1-\beta_1)g(\theta)
mt=β1mt−1+(1−β1)g(θ)
更新一阶矩的Nesterov加速值:
m
t
=
β
m
t
+
(
1
−
β
1
)
g
1
m_t = \beta m_t+(1-\beta_1)g_1
mt=βmt+(1−β1)g1
更新二阶矩:
v
t
=
β
2
v
t
−
1
+
(
1
−
β
2
)
g
2
(
θ
)
v_t = \beta_2v_{t-1}+(1-\beta_2)g^2(\theta)
vt=β2vt−1+(1−β2)g2(θ)
纠正一阶矩:
m
t
^
=
m
t
1
−
β
1
t
\hat{m_t} = \frac{m_t}{1-\beta_1^t}
mt^=1−β1tmt
纠正二阶矩:
v
t
^
=
v
t
1
−
β
2
t
\hat{v_t} = \frac{v_t}{1-\beta_2^t}
vt^=1−β2tvt
计算参数更新量:
Δ
θ
=
−
η
u
t
^
+
ϵ
⨀
m
t
^
\Delta \theta = - \frac{\eta}{\sqrt{\hat{u_t}}+\epsilon} \bigodot \hat{m_t}
Δθ=−ut^+ϵη⨀mt^
更新参数:
θ
t
+
1
=
θ
t
+
Δ
θ
\theta_{t+1} = \theta_t +\Delta \theta
θt+1=θt+Δθ
end while
优化算法的实用
在随机梯度的基础上,上述算法中分别提出了,基于动量的优化,基于自适应的算法。
以动量为核心的算法更容易在山谷型的优化曲面中找到最优解,如果最优曲面在某个地方震荡严重,而在另外一些地方方向趋势明显,那么基于动量的算法能够把握这种趋势,让有趋势的方向基类能量,同时让震荡的方向相互抵消。趋势不明显的话,那么这些积累的能量会继续释放,那么优化的参数的优化路径必然会绕一些弯路。
以自适应为核心的算法容易在各种场景下找到平衡,对于梯度较大的一些场景,他会适当的减少更新量,而对于梯度较小的一些场景,他会适当增加更新量,所以是对优化的做了一定的折中,所以这个优化算法肯定是耗时的,该类算法虽然很有秀,但是很多论文依然会使用经典的梯度下降法。