4.优化器
4.1优化器函数
tf.train.GradientDescentOptimizer
tf.train.AdadeltaOptimizer
tf.train.AdagradOptimizer
tf.train.AdagradDAOptimizer
tf.train.MomentumOptimizern
tf.train.AdamOptimizer(1e-2) #1e-2学习率0.01
tf.train.FtrlOptimizer
tf.train.ProximalGradientDescentOptimizer
tf.train.ProximalAdagradOptimizer
tf.train.RMSPropOptimizer
4.2各种优化器对比
4.2.1梯度下降法
参数定义:
W
W
W:要训练的参数
J
(
W
)
J(W)
J(W):代价函数
∇
w
J
(
W
)
\nabla w J(W)
∇wJ(W):代价函数的梯度
η
\eta
η:学习率
1.标准梯度下降法:
标准梯度下降先计算所有样本汇总误差,然后根据总误差来更新权值随机梯度下降法:
2.随机梯度下降(SGD)
随机抽取一个样本来计算误差,然后更新权值批量梯度下降法:
W
=
W
−
η
⋅
∇
w
(
W
;
x
(
i
)
;
y
(
i
)
)
\mathrm{W}=\mathrm{W}-\eta \cdot \nabla \mathrm{w} \left(\mathrm{W} ; \mathrm{x}^{(\mathrm{i})} ; \mathrm{y}^{(\mathrm{i})}\right)
W=W−η⋅∇w(W;x(i);y(i))
由于这种方法是在一次更新中,就对整个数据集计算梯度,所以计算起来非常慢,遇到很大量的数据集也会非常棘手,而且不能投入新数据实时更新模型。随机梯度下降是通过每个样本来迭代更新一次,如果样本量很大的情况,那么可能只用其中部分的样本,就已经将theta迭代到最优解了,对比上面的批量梯度下降,迭代一次需要用到十几万训练样本,一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次。缺点是SGD的噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。所以虽然训练速度快,但是准确度下降,并不是全局最优。虽然包含一定的随机性,但是从期望上来看,它是等于正确的导数
的。
3.批量梯度下降(BGD)
是一种折中的方案,从总样本中选取一个批次(比如一共有10000个样本,随机选取100个样本作为一个batch),然后计算这个batch的总误差,根据总误差来更新权值。
θ
=
θ
−
η
⋅
∇
θ
J
(
θ
)
\theta=\theta-\eta \cdot \nabla_{\theta} J(\theta)
θ=θ−η⋅∇θJ(θ)
4.2.2 momentum
1.梯度下降法存在的问题:
通常情况我们在训练深度神经网络的时候把数据拆解成一小批一小批地进行训练,这就是我们常用的mini-batch SGD训练算法,然而虽然这种算法能够带来很好的训练速度,但是在到达最优点的时候并不能够总是真正到达最优点,而是在最优点附近徘徊。另一个缺点就是这种算法需要我们挑选一个合适的学习率,当我们采用小的学习率的时候,会导致网络在训练的时候收敛太慢;当我们采用大的学习率的时候,会导致在训练过程中优化的幅度跳过函数的范围,也就是可能跳过最优点。我们所希望的仅仅是网络在优化的时候网络的损失函数有一个很好的收敛速度同时又不至于摆动幅度太大。
2.Monentun公式
动量的引入就是为了加快学习过程,特别是对于高曲率、小但一致的梯度,或者噪声比较大的梯度能够很好的加快学习过程。动量的主要思想是积累了之前梯度指数级衰减的移动平均(前面的指数加权平均),下面用一个图来对比下,SGD和动量的区别:
SGD每次都会在当前位置上沿着负梯度方向更新(下降,沿着正梯度则为上升),并不考虑之前的方向梯度大小等等。而动量(moment)通过引入一个新的变量 v vv 去积累之前的梯度(通过指数衰减平均得到),得到加速学习过程的目的。
最直观的理解就是,若当前的梯度方向与累积的历史梯度方向一致,则当前的梯度会被加强,从而这一步下降的幅度更大。若当前的梯度方向与累积的梯度方向不一致,则会减弱当前下降的梯度幅度。
所以Momentum优化器刚好可以解决我们所面临的问题,它主要是基于梯度的移动指数加权平均。假设在当前的迭代步骤第 t步中,那么基于Momentum优化算法可以写成下面的公式:
v
d
w
=
β
v
d
w
+
(
1
−
β
)
d
W
v_{d w}=\beta v_{d w}+(1-\beta) d W
vdw=βvdw+(1−β)dW
v
d
b
=
β
v
d
b
+
(
1
−
β
)
d
b
v_{d b}=\beta v_{d b}+(1-\beta) d b
vdb=βvdb+(1−β)db
W = W − α v d w W=W-\alpha v d w W=W−αvdw
b = b − α v d b b=b-\alpha v d b b=b−αvdb
其中,在上面的公式中
v
d
w
v_{d w}
vdw和
v
d
b
v_{d b}
vdb分别是损失函数在前t-1轮迭代过程中累积的梯度梯度动量,
β
β
β是梯度累积的一个指数,这里我们一般设置值为0.9。所以Momentum优化器的主要思想就是利用了类似与移动指数加权平均的方法来对网络的参数进行平滑处理的,让梯度的摆动幅度变得更小。
d
W
dW
dW和
d
b
db
db分别是损失函数反向传播时候所求得的梯度,下面两个公式是网络权重向量和偏置向量的更新公式,
α
\alpha
α是网络的学习率。当我们使用Momentum优化算法的时候,可以解决mini-batch SGD优化算法更新幅度摆动大的问题,同时可以使得网络的收敛速度更快。
3.Monentun存在的问题
参考自博客:https://blog.youkuaiyun.com/u012328159/article/details/80311892
下面再看下 β \beta β取不同值时,曲线的拟合情况:
从上图能够看出:
- 当B较大时(B=0.98相当于每一点前50天的平均气温),曲线波动相对较小更加平滑(绿色曲线),因为对很多天的气温做了平均处理,正因为如此,曲线还会右移。
- 同理,当B较小时(B=0.5相当于每一点前2天的平均气温),曲线波动相对激烈,但是它可以更快的适应温度的变化。
当我们令β=0.98时,我们想得到下图中的“绿线”,实际上我们得到的是下图中的“紫线”。对比这两条线,能够发现在“紫线”的起点相比“绿线”非常的低。
举个例子,如果第一天的温度是40℃,按照上面的公式计算, V = 0.98 v d m + ( 1 − 0.98 ) d W V=0.98 v_{dm}+(1-0.98)d_{W} V=0.98vdm+(1−0.98)dW=0.8,按照这个公式预估第一天的温度是0.8℃,显然距离40℃,差距非常大。同样,继续计算,第二天的温度也没有很好的拟合,也就是说指数加权平均不能很好地拟合前几天的数据,因此需要偏差修正,解决力法就是令 V d w = V d w 1 − β t V_{dw}=\frac{V_{dw}}{1-\beta^{t}} Vdw=1−βtVdw
再来按照上述公式对前两天温度进行计算, V 1 = V 1 1 − β 1 = 0.8 1 − 0.98 = 40 V_{1}=\frac{V_{1}}{1-\beta^{1}}=\frac{0.8}{1-0.98}=40 V1=1−β1V1=1−0.980.8=40,能够发现温度没有偏差。并且当$t \rightarrow \infty $ 时, β t → 0 \beta^{t} \rightarrow 0 βt→0这样在后期$v_{dw} $就和 没有修正的指数加权平均一样了。
**4.NAG(Nesterov acceleratd gradient)**内斯特罗夫加速梯度
Nesterov Momentum是对Momentum的改进,可以理解为nesterov动量在标准动量方法中添加了一个校正因子。用一张图来形象的对比下momentum和nesterov momentum的区别:
公式如下:
v
t
=
γ
V
t
−
1
+
η
∇
w
(
W
−
γ
V
t
−
1
)
W
=
W
−
v
t
\begin{array}{l}{\mathrm{v}_{\mathrm{t}}=\gamma \mathrm{V}_{\mathrm{t}-1}+\mathrm{\eta} \nabla \mathrm{w}\left(\mathrm{W}-\gamma \mathrm{V}_{\mathrm{t}-1}\right)} \\ {\mathrm{W}=\mathrm{W}-\mathrm{v}_{\mathrm{t}}}\end{array}
vt=γVt−1+η∇w(W−γVt−1)W=W−vt
NAG在TF中跟Momentum合并在同一个函数tf.train.MomentumOptimizer
中,可以通过参数配置启用。
在Momentun中小球会盲目地跟从下坡的梯度,容易发生错误,所以我们需要一个更聪明的小球,这个小球提前知道它要去哪里,它还要知道走到坡底的时候速度慢下来而不是又冲上另一个坡。
γ
v
t
−
1
\gamma vt- 1
γvt−1会用来修改
W
W
W的值,计算
W
−
γ
v
t
−
1
W-\gamma vt- 1
W−γvt−1可以表示小球下一个位置大概在哪里。从而我们可以提前计算下一个位置的梯度,然后使用到当前位置。
但是,我们仔细观察这个算法,你会发现一个很大的缺点,这个算法会导致运行速度巨慢无比,因为这个算法每次都要计算 ∇ θ ∑ i L ( f ( x ( i ) ; θ + α v ) , y ( i ) ) \nabla_\theta\sum_iL(f(x^{(i)};\theta + \alpha v),y^{(i)}) ∇θ∑iL(f(x(i);θ+αv),y(i)),这个相当于又要把fp、bp走一遍。 这样就导致这个算法的运行速度比momentum要慢两倍,因此在实际实现过程中几乎没人直接用这个算法。
4.2.3RMSProp(Root Mean Square Prop)
RMSProp算法的全称叫 Root Mean Square Prop,是Geoffrey E.Hinton在Coursera课程中提出的一种优化算法,在上面的Momentum优化算法中,虽然初步解决了优化中摆动幅度大的问题。所谓的摆动幅度就是在优化中经过更新之后参数的变化范围,如下图所示,蓝色的为Momentum优化算法所走的路线,绿色的为RMSProp优化算法所走的路线。
为了进一步优化损失函数在更新中存在摆动幅度过大的问题,并且进一步加快函数的收敛速度,RMSProp算法对权重
w
w
w和偏置
b
b
b的梯度使用了微分平方加权平均数。
其中,假设在第t轮迭代过程中,各个公式如下所示:
s
d
w
=
β
s
d
w
+
(
1
−
β
)
d
W
2
s
d
b
=
β
s
d
b
+
(
1
−
β
)
d
b
2
W
=
W
−
α
d
W
s
d
w
+
ε
b
=
b
−
α
d
b
s
d
b
+
ε
\begin{array}{c}{s_{d w}=\beta s_{d w}+(1-\beta) d W^{2}} \\ {s_{d b}=\beta s_{d b}+(1-\beta) d b^{2}} \\ {W=W-\alpha \frac{d W}{\sqrt{s d w}+\varepsilon}} \\ {b=b-\alpha \frac{d b}{\sqrt{s d b}+\varepsilon}}\end{array}
sdw=βsdw+(1−β)dW2sdb=βsdb+(1−β)db2W=W−αsdw+εdWb=b−αsdb+εdb
算法的主要思想就用上面的公式表达完毕了。在上面的公式中
s
d
w
s_{d w}
sdw和
s
d
b
s_{d b}
sdb分别是损失函数在前t一轮迭代过程中累积的梯度梯度动量,β是梯度累积的一个指数,一般取
0.999
0.999
0.999。所不同的是,RMSProp算法对梯度计算了微分平方加权平均数。这种做法有利于消除了摆动幅度大的方向,用来修正摆动幅度,使得各个维度的摆动幅度都较小。另一方面也使得网络函数收敛更快。(比如当dW或者db中有一个值比较大的时候,那么我们在更新权重或者偏置的时候除以它之前累积的梯度的平方根,这样就可以使得更新幅度变小)。为了防止分母为零,使用了一个很小的数值
ε
\varepsilon
ε来进行平滑,一般取值为
1
0
−
8
10^{-8}
10−8
4.2.4Adam(Adaptive Moment Estimation)
有了上面两种优化算法,一种可以使用类似于物理中的动量来累积梯度,另一种可以使得收敛速度更快同时使得波动的幅度更小。那么讲两种算法结合起来所取得的表现一定会更好。Adam(Adaptive Moment Estimation)算法是将Momentum算法和RMSProp算法结合起来使用的一种算法,我们所使用的参数基本和上面讲的一致,在训练的最开始我们需要初始化梯度的累积量和平方累积量。
v
d
w
=
0
,
v
d
b
=
0
;
s
d
w
=
0
,
s
d
b
=
0
v_{d w}=0, v_{d b}=0 ; s_{d w}=0, s_{d b}=0
vdw=0,vdb=0;sdw=0,sdb=0
假设在训练的第t轮训练中,我们首先可以计算得到Momentum和RMSProp的参数更新:
v
d
w
=
β
1
v
d
w
+
(
1
−
β
1
)
d
W
v
d
b
=
β
1
v
d
b
+
(
1
−
β
1
)
d
b
s
d
w
=
β
2
s
d
w
+
(
1
−
β
2
)
d
W
2
s
d
b
=
β
2
s
d
b
+
(
1
−
β
2
)
d
b
2
\begin{aligned} v_{d w} &=\beta_{1} v_{d w}+\left(1-\beta_{1}\right) d W \\ v_{d b} &=\beta_{1} v_{d b}+\left(1-\beta_{1}\right) d b \\ s_{d w}=& \beta_{2} s_{d w}+\left(1-\beta_{2}\right) d W^{2} \\ s_{d b} &=\beta_{2} s_{d b}+\left(1-\beta_{2}\right) d b^{2} \end{aligned}
vdwvdbsdw=sdb=β1vdw+(1−β1)dW=β1vdb+(1−β1)dbβ2sdw+(1−β2)dW2=β2sdb+(1−β2)db2
由于移动指数平均在迭代开始的初期会导致和开始的值有较大的差异,所以我们需要对上面求得的几个值做偏差修正。
v
d
w
c
=
v
d
w
1
−
β
1
t
v
d
b
c
=
v
d
b
t
1
−
β
1
t
s
d
w
c
=
s
d
w
t
1
−
β
2
t
s
d
b
c
=
s
d
b
t
1
−
β
2
t
\begin{aligned} v_{d w}^{c} &=\frac{v_{d w}}{1-\beta_{1}^{t}} \\ v_{d b}^{c} &=\frac{v_{d b}^{t}}{1-\beta_{1}^{t}} \\ s_{d w}^{c} &=\frac{s_{d w}^{t}}{1-\beta_{2}^{t}} \\ s_{d b}^{c} &=\frac{s_{d b}^{t}}{1-\beta_{2}^{t}} \end{aligned}
vdwcvdbcsdwcsdbc=1−β1tvdw=1−β1tvdbt=1−β2tsdwt=1−β2tsdbt
通过上面的公式,我们就可以求得在第 tt 轮迭代过程中,参数梯度累积量的修正值,从而接下来就可以根据Momentum和RMSProp算法的结合来对权重和偏置进行更新。
W
=
W
−
α
v
d
w
c
s
d
w
c
+
ε
b
=
b
−
α
v
d
b
c
s
d
b
c
+
ε
\begin{aligned} W &=W-\alpha \frac{v_{d w}^{c}}{\sqrt{s_{d w}^{c}+\varepsilon}} \\ b &=b-\alpha \frac{v_{d b}^{c}}{\sqrt{s_{d b}^{c}+\varepsilon}} \end{aligned}
Wb=W−αsdwc+εvdwc=b−αsdbc+εvdbc
上面的所有步骤就是Momentum算法和RMSProp算法结合起来从而形成Adam算法。在Adam算法中,参数B1所对应的就是Momentum算法中的B值,一般取0.9,参数B2所对应的就是RMSProp算法中的β值,一般我们取0.999,而e是一个平滑项,我们一般取值为10-8而学习率
a
a
a则需要我们在训练的时候进行微调。
4.2.5Adagrad
通常,我们在每一次更新参数时,对于所有的参数使用相同的学习率。而AdaGrad算法的思想是:每一次更新参数时(一次迭代),不同的参数使用不同的学习率。它是基于SGD的一种算法,它的核心思想是对比较常见的数据给予它比较小的学习率去调整参数,对于比较罕见的数据给予它比较大的学习率去调整参数。它很适合应用于数据稀疏的数据集(比如一个图片数据集,有10000张狗的照片,10000张猫的照片,只有100张大象的照片)。。AdaGrad 的公式为:
G
t
=
G
t
−
1
+
g
t
2
θ
t
+
1
=
θ
t
−
α
G
t
+
ε
⋅
g
t
\begin{aligned} G_{t} &=G_{t-1}+g_{t}^{2} \\ \theta_{t+1} &=\theta_{t}-\frac{\alpha}{\sqrt{G_{t}}+\varepsilon} \cdot g_{t} \end{aligned}
Gtθt+1=Gt−1+gt2=θt−Gt+εα⋅gt
公式中我们能够发现:
优点:对于梯度较大的参数,
G
t
G_{t}
Gt相对较大,则
α
G
t
+
ε
⋅
\frac{\alpha}{\sqrt{G_{t}}+\varepsilon} \cdot
Gt+εα⋅较小,意味着学习率会变得较小。而对于梯度较小的参数,则效果相反。这样就可以使得参数在平缓的地方下降的稍微快些,不至于徘徊不前。
缺点:由于是累积梯度的平方,到后面
G
t
G_{t}
Gt累积的比较大,会导致梯度
α
G
t
+
ε
→
0
\frac{\alpha}{\sqrt{G_{t}}+\varepsilon}\rightarrow 0
Gt+εα→0这样$
导致梯度消失。
4.2.6Adadelta
4.3视频动态展示
In summary, RMSprop is an extension of Adagrad that deals with its radically diminishing learning rates. It is identical to Adadelta, except that Adadelta uses the RMS of parameter updates in the numerator update rule. Adam, finally, adds bias-correction and momentum to RMSprop. Insofar, RMSprop, Adadelta, and Adam are very similar algorithms that do well in similar circumstances. Kingma et al. [10] show that its bias-correction helps Adam slightly outperform RMSprop towards the end of optimization as gradients become sparser. Insofar, Adam might be the best overall choice
总之,RMSprop是Adagrad的扩展,用于处理其急剧下降的学习率。 它与Adadelta相同,只是Adadelta在分子更新规则中使用参数更新的RMS。 最后,Adam为RMSprop增加了偏差修正和动力。 就此而言,RMSprop,Adadelta和Adam是非常相似的算法,在类似情况下表现良好。 Kingma等人表明,随着梯度变得稀疏,其偏差校正有助于Adam在优化结束时略微优于RMSprop。 就此而言,Adam可能是最好的整体选择