目录
第4章 梯度下降算法总览
梯度下降指的是,在给定模型参数 θ ∈ R d \theta\in \mathbb{R}^d θ∈Rd和目标函数 J ( θ ) J(\theta) J(θ) 后,通过沿梯度 ∇ θ J ( θ ) \nabla_\theta J(\theta) ∇θJ(θ)的反方向更新参数,不断优化函数,找到函数的局部极小值点。随机梯度下降可概括为如下三步:
-
计算当前目标函数关于参数的梯度:
g t = ∇ θ J ( θ t ) g_t=\nabla_\theta J(\theta_t) gt=∇θJ(θt)这里的梯度一般使用的是均方误差的梯度,均方误差的含义是求一个batch中n个样本的n个 输出与期望输出的差的平方的平均值。具体表达为: M S E ( y , h θ ( x ) ) = 1 m ∑ i = 1 m ( y i − h θ ( x i ) ) 2 MSE(y,h_\theta(x))=\frac{1} {m}\sum_{i=1}^m (y^i-h_\theta(x^i))^2 MSE(y,hθ(x))=m1∑i=1m(yi−hθ(xi))2,其中 h θ ( x ) = θ x + b h_\theta(x)=\theta x+b hθ(x)=θx+b。
-
根据历史梯度计算一,二阶动量:
m t = ϕ ( g 1 , g 2 , . . . , g t ) m_t=\phi(g_1,g_2,...,g_t) mt=ϕ(g1,g2,...,gt)
v t = ψ ( g 1 , g 2 , . . . , g t ) v_t=\psi(g_1,g_2,...,g_t) vt=ψ(g1,g2,...,gt) -
更新参数:
θ t + 1 = θ t − m t v t + ε \theta_{t+1}=\theta_t-\frac{m_t}{\sqrt{v_t+\varepsilon}} θt+1=θt−vt+εmt
有精力者可以结合Tensorflow常见优化器总结来阅读本文,可以将理论与实践相结合,学习效果更佳。
4.1 梯度下降算法
4.1.1 批量梯度下降算法(BGD)
批量梯度下降算法为梯度下降算法的最原始形式,使用所有样本梯度数据来更新参数,数学表达如下:
KaTeX parse error: No such environment: split at position 8: \begin{̲s̲p̲l̲i̲t̲}̲ \theta_{t+1} &…
优点:得到全局最优解,易于并行实现;
缺点:当样本数据过大时,训练过程很慢;
4.1.2 随机梯度下降算法(SGD)
随机梯度下降算法是为解决批量梯度下降算法中样本容量过大的情况,两者其实差不多,批量梯度下降算法是每次更新(迭代)使用所有样本,而随机梯度下降算法是每次更新使用一个样本。简而言之,BGD是一次跨一大步,但步频慢。SGD是一次跨一小步,但步频快,或许不必计算所有的样本就已经达到最优点。
SGD是小步快走,能否走到最佳位置要随缘,有点随机的感觉,因此叫做随机梯度下降算法。数学表达如下:
KaTeX parse error: No such environment: split at position 8: \begin{̲s̲p̲l̲i̲t̲}̲ J(\theta_t) &…
所以,
KaTeX parse error: No such environment: split at position 10: \begin{̲s̲p̲l̲i̲t̲}̲ \theta_{t+1}…
**优点:**训练速度快;
**缺点:**准确度低(收敛速度慢),不是全局最优点,在鞍点处震荡,不易并行实现;
4.1.3 最小批量梯度下降算法(MBGD)
最小批量梯度下降算法是BGD与SGD的折衷,它结合了BGD一部分准确度高的特点也结合了一部分SGD训练速度快的优点。为了实现准确度高,MBGD使用一批样本数据;为了保证训练速度较快,该批样本的数据量较小。
MBGD是中步中速走,更新参数时使用n个样本(
m
>
n
>
1
m>n>1
m>n>1),但同时要让n尽量小.数学表达如下:
θ
t
+
1
=
θ
t
−
1
n
∑
i
=
1
n
J
i
(
θ
t
)
=
θ
t
+
1
n
∑
i
=
1
n
(
y
i
−
h
θ
(
x
i
)
)
x
i
\begin{aligned} \theta_{t+1} &= \theta_t - \frac{1}{n} \sum_{i=1}^n J^i(\theta_t)\\ &= \theta_t + \frac{1}{n} \sum_{i=1}^n (y^i-h_\theta(x^i))x^i \end{aligned}
θt+1=θt−n1i=1∑nJi(θt)=θt+n1i=1∑n(yi−hθ(xi))xi
4.2 梯度下降算法的优化
梯度下降算法存在以下缺陷:
- 收敛速度较慢;
- 容易陷于鞍点(局部极值);
- 需在节点间通信;
而梯度下降的优化将会对这些缺陷进行优化。
动量(Momentum),Nesterov,二阶动量(Adgrad,RMSprop,Adam)
4.2.1 动量(Momentum)
动量方法用于解决SGD收敛速度慢,易陷入局部极值点点的情况。引入历史梯度信息,加速SGD在正确方向上的下降并抑制震荡。其数学表达如下:
v
t
+
1
=
α
v
t
−
η
∇
J
(
θ
t
)
=
α
v
t
−
η
g
t
θ
t
+
1
=
θ
t
+
v
t
+
1
\begin{aligned} v_{t+1} &= \alpha v_t - \eta \nabla J(\theta_{t})\\ &= \alpha v_t - \eta g_{t}\\ \theta_{t+1} &= \theta_t + v_{t+1} \end{aligned}
vt+1θt+1=αvt−η∇J(θt)=αvt−ηgt=θt+vt+1
**优点:**收敛速度较SGD快,震荡较少;
**缺点:**比较难学习一个较好的学习率;
上面的纯数学表达似乎有一点难理解,可以从物理角度有较为形象生动的理解,历史梯度可以理解为“惯性”。
梯度
g
t
g_t
gt 可以类比为物体运动中时刻
t
t
t的加速度。那么动量
v
t
v_t
vt 就可以类比为物体运动到时刻
t
t
t 时的速度,而参数
θ
\theta
θ 就是物体在
t
t
t 时刻的运动趋势,这个运动趋势
θ
\theta
θ 不仅与该时刻的运动加速度
g
t
g_t
gt 相关也与运动速度
v
t
v_t
vt 有关。
简而言之,当要改变运动趋势时,不仅要克服加速度的影响也要克服速度的影响,即使加速度为零,剩余的速度(惯性)依然会让物体继续运动。
SGD与Momentum对比:
权威参考如下(On the importance of initialization and momentum in deep learning):
4.2.2 Nesterov_momentum
为了能让梯度改变更加智能且更早预测变化趋势,Nesterov被提了出来。Nesterov求出此时参数
θ
t
\theta_t
θt加上改变量
α
v
t
−
1
\alpha v_{t-1}
αvt−1的梯度,该梯度将作为新的梯度影响动量变化并产生下一时刻的动量。之后则与momentum类似,用当前参数加下一时刻的动量,从而求出下一时刻的参数。数学表达如下:
KaTeX parse error: No such environment: split at position 8: \begin{̲s̲p̲l̲i̲t̲}̲ \widehat g_t &…
**优点:**收敛速度较快;
**缺点:**暂时还不知道;
Nesterov与Momentum的区别就是在于求动量改变量
g
t
g_t
gt时有所不同,Momentum 是利用当前位置求梯度(
∇
J
(
θ
t
)
\nabla J(\theta_{t})
∇J(θt))而 Nesterov 是利用估计的下一时刻位置求梯度(
∇
J
(
θ
t
+
α
v
t
)
\nabla J(\theta_t+\alpha v_t)
∇J(θt+αvt)),其余都一样。因为这个不同,Nesterov可以提前纠正动量方向的偏差。
利用下图可以更好地理解Nesterov:
SGD-M 的步长计算了当前梯度(短蓝向量)和动量项 (长蓝向量)。然而,既然已经利用了动量项来更新 ,那不妨先计算出下一时刻 \theta 的近似位置 (棕向量),并根据该未来位置计算梯度(红向量),然后使用和 SGD-M 中相同的方式计算步长(绿向量)。这种计算梯度的方式可以使算法更好的「预测未来」,提前调整更新速率。
权威参考如下(lan goodfellow 《deep learning》):
4.2.3 AdaGrad
之前谈到的算法都是以相同的频率更新参数
θ
\theta
θ 的分量。然而在现实学习模型中有大量的参数,不同的参数一般有不同的更新频率。对于不频繁更新的参数往往希望单次更新步长更大,学习到更多的知识;而频繁更新的参数则希望更新步长较小,保持参数的稳定性。AdaGrad算法正好满足这一要求。
AdaGrad算法引入了二阶动量,即求出梯度的平方和
r
r
r 并将其平方根作为学习步长的分母,当参数更新越频繁则梯度平方和越大,分母越大,学习步长越小。具体数学表达如下:
r
t
i
=
r
t
−
1
i
+
g
t
i
⊙
g
t
i
θ
t
+
1
i
=
θ
t
i
−
ϵ
δ
+
r
t
i
⊙
g
t
i
,
δ
一
般
默
认
取
1
0
−
7
,
ϵ
为
全
局
学
习
率
\begin{aligned} r_t^i &= r_{t-1}^i + g_t^i\odot g_t^i\\ \theta_{t+1}^i &= \theta_t^i - \frac{\epsilon}{\delta+\sqrt{r_t^i}} \odot g_t^i ,\delta 一般默认取 10^{-7}, \epsilon为全局学习率 \end{aligned}
rtiθt+1i=rt−1i+gti⊙gti=θti−δ+rtiϵ⊙gti,δ一般默认取10−7,ϵ为全局学习率
**优点:**非常适合处理稀疏数据;
**缺点:**累加平方和越来越大,容易导致学习步长趋近零,出现早停,尤其不适合神经网络;依赖于一个全局学习率
ϵ
\epsilon
ϵ。
4.2.4 Adadelta
Adadelta算法是对Adagrad算法的改进,解决早停和依赖全局学习率的问题。
为了解决Adgrad早停的问题,Adadelta只累积过去
ρ
\rho
ρ窗口大小的梯度,从数学角度来看就是利用了指数加权平均,具体公式如下(以下的公式为针对某一参数的更新,不再用
i
i
i标注不同参数):
r
t
=
ρ
r
t
−
1
+
(
1
−
ρ
)
(
g
t
⊙
g
t
)
r_t = \rho r_{t-1} + (1-\rho)(g_t \odot g_t)
rt=ρrt−1+(1−ρ)(gt⊙gt)
为解决Adagrad依赖全局学习率的问题,Adadelta将
t
−
1
t-1
t−1 时刻的变化量
Δ
x
t
−
1
\Delta x_{t-1}
Δxt−1的指数加权平均的平方根为分子(用
E
[
Δ
x
2
]
t
−
1
E[\Delta x^2]_{t-1}
E[Δx2]t−1来表示),当前二阶动量
r
t
r_t
rt 的平方根为分母,分式整体为学习率,具体公式如下:
Δ
x
t
=
−
E
[
Δ
x
2
]
t
−
1
+
ϵ
r
t
+
ϵ
⋅
g
t
,
\Delta x_t = -\frac{\sqrt{E[\Delta x^2]_{t-1}}+\epsilon}{\sqrt{r_t}+\epsilon} \cdot g_t,
Δxt=−rt+ϵE[Δx2]t−1+ϵ⋅gt,
同时还可以求出
t
t
t 时刻变化量的加权平均,具体公式如下:
E
[
Δ
x
2
]
t
=
ρ
E
[
Δ
x
2
]
t
−
1
+
(
1
−
ρ
)
Δ
x
t
2
.
(
ϵ
通
常
取
1
e
−
6
,
防
止
分
母
为
零
)
E[\Delta x^2]_t= \rho E[\Delta x^2]_{t-1} + (1-\rho) \Delta x_t^2.\\ (\epsilon 通常取1e^{-6},防止分母为零)
E[Δx2]t=ρE[Δx2]t−1+(1−ρ)Δxt2.(ϵ通常取1e−6,防止分母为零)
最后可以求得下一时刻
t
+
1
t+1
t+1 的参数,具体公式如下:
θ
t
+
1
=
θ
t
+
Δ
x
t
(
由
于
Δ
x
已
经
带
有
负
号
了
,
所
以
这
里
用
加
号
)
\theta_{t+1} = \theta_t + \Delta x_t \\ (由于\Delta x 已经带有负号了,所以这里用加号)
θt+1=θt+Δxt(由于Δx已经带有负号了,所以这里用加号)
优点: 1. 非常适合处理稀疏数据; 2. 优化了Adgrad的缺点;
**缺点:**暂时不知道;
权威参考如下(《AdaDelta: An Adaptive Learning Rate Method》):
4.2.5 RMSprop
RMSprop算法也是对Adgrad算法的改进,它对Adgrad算法的早停问题进行了改进,采取的思路与Adadelta差不多。具体公式如下:
r
t
=
ρ
r
t
−
1
+
(
1
−
ρ
)
g
t
⊙
g
t
Δ
θ
t
=
−
ϵ
r
t
+
δ
⊙
g
t
θ
t
+
1
=
θ
t
+
Δ
θ
t
\begin{aligned} r_t &= \rho r_{t-1} + (1-\rho) g_t \odot g_t \\ \Delta \theta_t &= -\frac{\epsilon}{\sqrt{r_t+\delta}} \odot g_t \\ \theta_{t+1} &= \theta_t + \Delta \theta_t \end{aligned}
rtΔθtθt+1=ρrt−1+(1−ρ)gt⊙gt=−rt+δϵ⊙gt=θt+Δθt
优点: 1. 非常适合处理稀疏数据; 2. 优化了Adgrad早停的问题;
**缺点:**依赖全局学习率;
权威参考如下(lan goodfellow 《deep learning》):
4.2.6 Adam
Adam 算法结合了 Momentum 和 Rmsporp 两者的思想,对局部震荡和早停的问题做出了改进。具体公式如下:
r
t
=
ρ
1
r
t
−
1
+
(
1
−
ρ
1
)
g
t
⊙
g
t
m
t
=
ρ
2
m
t
−
1
+
(
1
−
ρ
2
)
g
t
r
^
t
=
r
t
(
1
−
ρ
1
t
)
m
^
t
=
m
t
(
1
−
ρ
2
t
)
θ
t
+
1
=
θ
t
−
α
m
^
t
r
^
t
+
ϵ
\begin{aligned} r_t &= \rho_1 r_{t-1} + (1-\rho_1) g_t \odot g_t \\ m_t &= \rho_2 m_{t-1} + (1-\rho_2) g_t \\ \widehat r_t &= \frac{r_t}{(1-\rho_1^t)} \\ \widehat m_t &= \frac{m_t}{(1-\rho_2^t)} \\ \theta_{t+1} &= \theta_t - \alpha \frac{\widehat m_t}{\sqrt{\widehat r_t}+\epsilon} \\ \end{aligned}
rtmtr
tm
tθt+1=ρ1rt−1+(1−ρ1)gt⊙gt=ρ2mt−1+(1−ρ2)gt=(1−ρ1t)rt=(1−ρ2t)mt=θt−αr
t+ϵm
t
ρ
1
t
\rho_1^t
ρ1t与
ρ
2
t
\rho_2^t
ρ2t中t表示t次幂。
权威参考如下(Diederik P. Kingma et al. ADAM: A METHOD FOR STOCHASTIC OPTIMIZATION, ICLR2015):
本文中最后一个公式是当前参数
θ
t
\theta_t
θt减去此时改变量
α
m
^
t
r
^
t
+
ϵ
\alpha \frac{\widehat m_t}{\sqrt{\widehat r_t}+\epsilon}
αr
t+ϵm
t,从而得到下一时刻参数
θ
t
+
1
\theta_{t+1}
θt+1,而参考资料中是当前参数
θ
t
−
1
\theta_{t-1}
θt−1与下一时刻改变量
α
m
^
t
r
^
t
+
ϵ
\alpha \frac{\widehat m_t}{\sqrt{\widehat r_t}+\epsilon}
αr
t+ϵm
t求差,貌似存在矛盾,其实道理一样,本文利用当前参数
θ
t
\theta_t
θt求当前梯度
g
t
g_t
gt,而参考资料是利用前一刻参数
θ
t
−
1
\theta_{t-1}
θt−1求当前梯度
g
t
g_t
gt,如果将资料中的
g
t
g_t
gt写为
g
t
−
1
g_{t-1}
gt−1,结果与本文是相同的。
优点: 1. 非常适合处理稀疏数据; 2. 优化了Adgrad早停的问题;3. 优化了局部震荡问题;
缺点: 依赖全局学习率;