Optimization algorithms
Mini-batch gradient descent
之前我们介绍的神经网络训练过程是对所有m个样本,称为batch,通过向量化计算方式,同时进行的。我们将这种梯度下降算法称为Batch Gradient Descent。
但是随着数据量的增大,达到百万级,那么训练速度往往会很慢,为了解决这个问题,我们提出了mini-batch gradient descent。即将5百万的样本数量分为5000份,每个mini-batch得到一份,一份含有1000个样本。我们将每个mini-batch记为 X [ t ] X^{[t]} X[t],其维度为 ( n x , 1000 ) (n_x,1000) (nx,1000)。相应的每个mini-batch的输出记为 Y [ t ] Y^{[t]} Y[t],其维度为(1,1000),且t=1,2,…,5000.
Mini-batch Gradient Descent的实现过程是先将总的训练样本分成T个子集,然后对每个mini-batch进行神经网络训练,包括Forward Propagation,Compute Cost Function,Backward Propagation,循环至T个mini-batch都训练完毕。
f
o
r
t
=
1
,
⋯
,
T
{
for t=1,⋯,T\{
fort=1,⋯,T{
F
o
r
w
a
r
d
P
r
o
p
a
g
a
t
i
o
n
Forward Propagation
ForwardPropagation
C
o
m
p
u
t
e
C
o
s
t
F
u
n
c
t
i
o
n
ComputeCostFunction
ComputeCostFunction
B
a
c
k
w
a
r
d
P
r
o
p
a
g
a
t
i
o
n
BackwardPropagation
BackwardPropagation
W
:
=
W
−
α
⋅
d
W
W:=W−α⋅dW
W:=W−α⋅dW
b
:
=
b
−
α
⋅
d
b
b:=b−α⋅db
b:=b−α⋅db
}
\}
}
对于Batch Gradient Descent而言,一个epoch只进行一次梯度下降算法;而Mini-Batch Gradient Descent,一个epoch会进行T次梯度下降算法。
值得一提的是,对于Mini-Batch Gradient Descent,可以进行多次epoch训练。而且,每次epoch,最好是将总体训练数据重新打乱、重新分成T组mini-batches,这样有利于训练出最佳的神经网络模型。
Understanding mini-batch gradient descent
普通的batch梯度下降法和Mini-batch梯度下降法代价函数的变化趋势,如下图所示:
- batch梯度下降:
- 对所有m个训练样本执行一次梯度下降,每一次迭代时间较长;
- Cost function 总是向减小的方向下降。
- 随机梯度下降:
- 对每一个训练样本执行一次梯度下降,但是丢失了向量化带来的计算加速;
- Cost function总体的趋势向最小值的方向下降,但是无法到达全局最小值点,呈现波动的形式。
- Mini-batch梯度下降:
- 选择一个1<size<m的合适的size进行Mini-batch梯度下降,可以实现快速学习,也应用了向量化带来的好处。
- Cost function的下降处于前两者之间。
上图蓝线表示batch gradient descent,会比较平稳地接近全局最小值,但是因为使用了所有m个样本,每次前进的速度有些慢。紫线表示stochastic gradient descent每次前进速度很快,但是路线曲折,有较大的振荡,最终会在最小值附近来回波动,难以真正达到最小值处。绿线表示mini-batch gradient descent,每次前进速度较快,且振荡较小,基本能接近全局最小值。
Mini-batch 大小的选择
- 如果训练样本的大小比较小时,如m⩽2000时 —— 选择batch梯度下降法;
- 如果训练样本的大小比较大时,典型的大小为: 64,128,256,512,1024(不常见)
- Mini-batch的大小要符合CPU/GPU内存。
Exponentially weighted averages
指数加权平均的关键函数:
v t = β v t − 1 + ( 1 − β ) θ t v_t=βv_{t−1}+(1−β)θ_t vt=βvt−1+(1−β)θt
下面是一个关于天数和温度的散点图:
上图中, β \beta β=0.9. β \beta β值决定了指数加权平均的天数,可以近似表示为:
1 1 − β \frac{1}{1-\beta} 1−β1
例如,当β=0.9,则 1 1 − β = 10 \frac{1}{1−β}=10 1−β1=10,表示将前10天进行指数加权平均。当β=0.98,则 1 1 − β = 50 \frac{1}{1−β}=50 1−β1=50,表示将前50天进行指数加权平均。β值越大,则指数加权平均的天数越多,平均后的趋势线就越平缓,但是同时也会向右平移。下图绿色曲线和黄色曲线分别表示了β=0.98和β=0.5时,指数加权平均的结果。
Understanding exponentially weighted averages
例子,当β=0.9时:
v
100
=
0.9
v
99
+
0.1
θ
100
v_{100}=0.9v_{99}+0.1θ_{100}
v100=0.9v99+0.1θ100
v
99
=
0.9
v
98
+
0.1
θ
99
v_{99}=0.9v_{98}+0.1θ_{99}
v99=0.9v98+0.1θ99
v
98
=
0.9
v
97
+
0.1
θ
98
v_{98}=0.9v_{97}+0.1θ_{98}
v98=0.9v97+0.1θ98
…
展开:
v 100 = 0.1 θ 100 + 0.9 ( 0.1 θ 99 + 0.9 ( 0.1 θ 98 + 0.9 v 97 ) ) v_{100}=0.1θ_{100}+0.9(0.1θ_{99}+0.9(0.1θ_{98}+0.9v_{97})) v100=0.1θ100+0.9(0.1θ99+0.9(0.1θ98+0.9v97))
= 0.1 θ 100 + 0.1 × 0.9 θ 99 + 0.1 × ( 0.9 ) 2 θ 98 + 0.1 × ( 0.9 ) 3 θ 97 + ⋯ =0.1θ_{100}+0.1×0.9θ_{99}+0.1×(0.9)^2θ_{98}+0.1×(0.9)^3θ_{97}+⋯ =0.1θ100+0.1×0.9θ99+0.1×(0.9)2θ98+0.1×(0.9)3θ97+⋯
上式中所有θ前面的系数相加起来为1或者接近于1。
通常来说, ( 1 − ϵ ) 1 ϵ = 1 e (1-\epsilon)^{\frac{1}{\epsilon}}=\frac{1}{e} (1−ϵ)ϵ1=e1,在我们的例子中, 1 − ϵ = β = 0.9 1-\epsilon=\beta=0.9 1−ϵ=β=0.9,即 0. 9 10 ≈ 0.35 ≈ 1 e 0.9^{10}≈0.35≈\frac{1}{e} 0.910≈0.35≈e1.相当于大约10天后,系数的峰值(这里是0.1)下降到原来的 1 e \frac{1}{e} e1,只关注了过去10天的天气.
我们已经知道了指数加权平均的递推公式。实际应用中,为了减少内存的使用,我们可以使用这样的语句来实现指数加权平均算法:
V
θ
=
0
V_θ=0
Vθ=0
R
e
p
e
a
t
{
Repeat \{
Repeat{
G
e
t
n
e
x
t
θ
t
Get \ next\ θ_t
Get next θt
V
θ
:
=
β
V
θ
+
(
1
−
β
)
θ
t
V_θ:=βV_{θ}+(1−β)θ_t
Vθ:=βVθ+(1−β)θt
}
\}
}
当你需要计算很多变量的平均值时,不论是计算还是存储效率,上述算法都是十分的高效.
###Bias correction in exponentially weighted averages
上文中提到当β=0.98时,指数加权平均结果如下图绿色曲线所示。但是实际上,真实曲线如紫色曲线所示。
我们注意到,紫色曲线与绿色曲线的区别是,紫色曲线开始的时候相对较低一些。这是因为开始时我们设置
V
0
=
0
V_0=0
V0=0,所以初始值会相对小一些,直到后面受前面的影响渐渐变小,趋于正常。
修正这种问题的方法是进行偏差校正(bias correction),即在每次计算完
V
t
V_t
Vt后,对
V
t
V_t
Vt进行下式处理:
V t 1 − β t \frac{V_t}{1-\beta^t} 1−βtVt
在刚开始的时候,t比较小, ( 1 − β t ) < 1 (1−β^t)<1 (1−βt)<1,这样就将 V t V_t Vt修正得更大一些,效果是把紫色曲线开始部分向上提升一些,与绿色曲线接近重合。随着t增大, ( 1 − β t ) ≈ 1 (1−β^t)≈1 (1−βt)≈1, V t V_t Vt基本不变,紫色曲线与绿色曲线依然重合。这样就实现了简单的偏差校正,得到我们希望的绿色曲线。
值得一提的是,机器学习中,偏差校正并不是必须的。因为,在迭代一次次数后(t较大), V t V_t Vt受初始值影响微乎其微,紫色曲线与绿色曲线基本重合。所以,一般可以忽略初始迭代过程,等到一定迭代之后再取值,这样就不需要进行偏差校正了。
Gradient descent with momentum
该部分将介绍动量梯度下降算法,其速度要比传统的梯度下降算法快很多。做法是在每次训练时,对梯度进行指数加权平均处理,然后用得到的梯度值更新权重W和常数项b。下面介绍具体的实现过程。
在利用梯度下降法来最小化该函数的时候,每一次迭代所更新的代价函数值如图中蓝色线所示在上下波动,而这种幅度比较大波动,减缓了梯度下降的速度,而且我们只能使用一个较小的学习率来进行迭代。
但是我们又希望在如图的纵轴方向梯度下降的缓慢一些,不要有如此大的上下波动,在横轴方向梯度下降的快速一些,使得能够更快的到达最小值点,而这里用动量梯度下降法就可以实现,如红色线所示。
算法实现
β常用的值是0.9。
在我们进行动量梯度下降算法的时候,由于使用了指数加权平均的方法。原来在纵轴方向上的上下波动,经过平均以后,接近于0,纵轴上的波动变得非常的小;但在横轴方向上,所有的微分都指向横轴方向,因此其平均值仍然很大。最终实现红色线所示的梯度下降曲线。
从动量的角度来看,以权重W为例, V d W V_{dW} VdW可以成速度V, d W d_W dW可以看成是加速度a。指数加权平均实际上是计算当前的速度,当前速度由之前的速度和现在的加速度共同影响。而β<1,又能限制速度 V d W V_{dW} VdW过大。也就是说,当前的速度是渐变的,而不是瞬变的,是动量的过程。这保证了梯度下降的平稳性和准确性,减少振荡,较快地达到最小值处。
另外,关于偏移校正,一般来说不使用。因为经过10次迭代后,随着滑动平均的过程,偏移情况会逐渐消失。而且梯度下降迭代的次数一般远大于10次。
RmSprop(Root Mean Square prop均方根传递)
RMSprop是另外一种优化梯度下降速度的算法。每次迭代训练过程中,其权重W和常数项b的更新表达式为:
S
d
W
=
β
S
d
W
+
(
1
−
β
)
d
W
2
S_{dW}=βS_{dW}+(1−β)dW^2
SdW=βSdW+(1−β)dW2
S
d
b
=
β
S
d
b
+
(
1
−
β
)
d
b
2
S_{db}=βS_{db}+(1−β)db^2
Sdb=βSdb+(1−β)db2
W
:
=
W
−
α
d
W
S
d
W
,
b
:
=
b
−
α
d
b
S
d
b
W:=W−α\frac{dW}{\sqrt{S_{dW}}}, b:=b−α\frac{db}{\sqrt{S_{db}}}
W:=W−αSdWdW,b:=b−αSdbdb
下面简单解释一下RMSprop算法的原理,仍然以下图为例,为了便于分析,令水平方向为W的方向,垂直方向为b的方向。
从图中可以看出,梯度下降(蓝色折线)在垂直方向(b)上振荡较大,在水平方向(W)上振荡较小,表示在b方向上梯度较大,即db较大,而在W方向上梯度较小,即dW较小。因此,上述表达式中 S d b S_{db} Sdb较大,而 S d W S_{dW} SdW较小。在更新W和b的表达式中,变化值 d w S d w \frac{dw}{\sqrt{S_{dw}}} Sdwdw较大,而 d b S d b \frac{db}{\sqrt{S_{db}}} Sdbdb较小。也就使得W变化得多一些,b变化得少一些。即加快了W方向的速度,减小了b方向的速度,减小振荡,实现快速梯度下降算法,其梯度下降过程如绿色折线所示。总得来说,就是如果哪个方向振荡大,就减小该方向的更新速度,从而减小振荡。
还有一点需要注意的是为了避免RMSprop算法中分母为零,通常可以在分母增加一个极小的常数ε:
W
:
=
W
−
α
d
W
S
W
+
ε
,
b
:
=
b
−
α
d
b
S
b
+
ε
W:=W−α\frac{dW}{\sqrt{S_W}+ε}, b:=b−α\frac{db}{\sqrt{S_b}+ε}
W:=W−αSW+εdW,b:=b−αSb+εdb
其中,
ε
=
1
0
−
8
ε=10^{−8}
ε=10−8,或者其它较小值。
Adam optimization algorithm
Adam 优化算法的基本思想就是将 Momentum 和 RMSprop 结合起来形成的一种适用于不同深度学习结构的优化算法。
算法实现
-
初始化: V d w = 0 , S d w = 0 , V d b = 0 , S d b = 0 V_{dw}=0,S_{dw}=0,V_{db}=0,S_{db}=0 Vdw=0,Sdw=0,Vdb=0,Sdb=0
-
第t次迭代:
- Compute dw,db on the current mini-batch
- V d w = β 1 V d w + ( 1 − β 1 ) d w , V d b = β 1 V d b + ( 1 − β 1 ) d b V_{dw}=\beta_1V_{dw}+(1-\beta_1)dw, V_{db}=\beta_1V_{db}+(1-\beta_1)db Vdw=β1Vdw+(1−β1)dw,Vdb=β1Vdb+(1−β1)db<–“Momentum”
- S d w = β 2 S d w + ( 1 − β 2 ) ( d w ) 2 , S d b = β 2 S d b + ( 1 − β 2 ) ( d b ) 2 S_{dw}=\beta_2S_{dw}+(1-\beta_2)(dw)^2, S_{db}=\beta_2S_{db}+(1-\beta_2)(db)^2 Sdw=β2Sdw+(1−β2)(dw)2,Sdb=β2Sdb+(1−β2)(db)2<–“Momentum”
- V d w c o r r e c t e d = V d w / ( 1 − β 1 ′ ) , V d b c o r r e c t e d = V d b / ( 1 − β 1 ′ ) V^{corrected}_{dw}=V_{dw}/(1-\beta_1'), V^{corrected}_{db}=V_{db}/(1-\beta_1') Vdwcorrected=Vdw/(1−β1′),Vdbcorrected=Vdb/(1−β1′)<—偏差修正
- S d w c o r r e c t e d = S d w / ( 1 − β 2 ′ ) , S d b c o r r e c t e d = S d b / ( 1 − β 2 ′ ) S^{corrected}_{dw}=S_{dw}/(1-\beta_2'), S^{corrected}_{db}=S_{db}/(1-\beta_2') Sdwcorrected=Sdw/(1−β2′),Sdbcorrected=Sdb/(1−β2′)<—偏差修正
- w : = w − α V d W c o r r e c t e d S d w c o r r e c t e d + ε , b : = b − α V d b c o r r e c t e d S d b c o r r e c t e d + ε w:=w−α\frac{V_{dW}^{corrected}}{\sqrt{S_{dw}^{corrected}}+ε}, b:=b−α\frac{V_{db}^{corrected}}{\sqrt{S_{db}^{corrected}}+ε} w:=w−αSdwcorrected+εVdWcorrected,b:=b−αSdbcorrected+εVdbcorrected
超参数的选择
- α:需要进行调试;
- β 1 β_1 β1:常用缺省值为0.9, d w dw dw的加权平均;
- β 2 β_2 β2:推荐使用0.999, d w 2 dw^2 dw2的加权平均值;
- ε:推荐使用 1 0 − 8 10^{−8} 10−8。
Adam代表的是Adaptive Moment Estimation。
实际应用中,Adam算法结合了动量梯度下降和RMSprop各自的优点,使得神经网络训练速度大大提高。
Learning rate decay
减小学习因子α也能有效提高神经网络训练速度,这种方法被称为learning rate decay。
Learning rate decay就是随着迭代次数增加,学习因子α逐渐减小。下面用图示的方式来解释这样做的好处。下图中,蓝色折线表示使用恒定的学习因子α,由于每次训练α相同,步进长度不变,在最优值附近较大范围内振荡,与最优值距离就比较远。绿色折线表示使用不断减小的α,随着训练次数增加,α逐渐减小,步进长度减小,使得能够在最优值处较小范围内微弱振荡,不断逼近最优值。相比较恒定的α来说,learning rate decay更接近最优值。
-
常见:
Learning rate decay中对α可由下列公式得到:
α = 1 1 + d e c a y _ r a t e ∗ e p o c h α 0 \alpha=\frac{1}{1+decay\_rate*epoch}\alpha_0 α=1+decay_rate∗epoch1α0其中,decay_rate是参数(可调),epoch是训练完所有样本的次数。随着epoch增加, α \alpha α会不断变小。
-
指数衰减:
α = 0.9 5 e p o c h _ n u m α 0 \alpha=0.95^{epoch\_num}\alpha_0 α=0.95epoch_numα0 -
其他:
α = k e p o c h _ n u m ⋅ α 0 \alpha=\frac{k}{epoch\_num}⋅\alpha_0 α=epoch_numk⋅α0
-
离散下降(不同阶段使用不同的学习速率)
The problem of local optima
在使用梯度下降算法不断减小cost function时,可能会得到局部最优解(local optima)而不是全局最优解(global optima)。之前我们对局部最优解的理解是形如碗状的凹槽,如下图左边所示。但是在神经网络中,local optima的概念发生了变化。准确地来说,大部分梯度为零的“最优点”并不是这些凹槽处,而是形如右边所示的马鞍状,称为saddle point。也就是说,梯度为零并不能保证都是convex(极小值),也有可能是concave(极大值)。特别是在神经网络中参数很多的情况下,所有参数梯度为零的点很可能都是右边所示的马鞍状的saddle point,而不是左边那样的local optimum。
类似马鞍状的plateaus会降低神经网络学习速度。Plateaus是梯度接近于零的平缓区域,如下图所示。在plateaus上梯度很小,前进缓慢,到达saddle point需要很长时间。到达saddle point后,由于随机扰动,梯度一般能够沿着图中绿色箭头,离开saddle point,继续前进,只是在plateaus上花费了太多时间。
总的来说,关于local optima,有两点总结:
- 只要选择合理的强大的神经网络,一般不太可能陷入local optima
- Plateaus可能会使梯度下降变慢,降低学习速度
值得一提的是,上文介绍的动量梯度下降,RMSprop,Adam算法都能有效解决plateaus下降过慢的问题,大大提高神经网络的学习速度。