内容纲要

欢迎转载,作者:Ling,注明出处:深度学习:原理简明教程08-深度学习:优化器

 

本文主要讨论深度学习中优化器问题。

 

之前文章介绍的批量梯度下降GD就是一种优化器,通过它可以不断优化,得到最终比较优的w和b。但是我们一般不会直接使用BGD优化器,主要原因如下:

缺点

1)每次迭代需要对所有训练样本进行一次操作,如果训练样本太大,训练速度会非常慢。

2)不利于增量学习,或者说在线学习,一旦有新的样本过来,整个模型需要重新训练。

优点

可以比较平滑收敛到凸函数的全局最优,非凸函数可以收敛到局部最优(其实当维度很多时候,往往都是全局最优,以后会分析这个问题)

 

所以梯度下降有以下形式

1)梯度下降(BGD):每次要用所有样本

2)随机梯度下降(SGD):每次一个样本,而且样本是打乱顺序的,所以用了随机这个词。

3)Batch随机梯度下降(MBGD,也叫min-batch GD):每次多个样本,将所有样本分成多组,每组数目一样,每次迭代需要分别对每组进行学习。

4)改进后的随机梯度下降(很多变种):学习率自动下降

 

批量梯度下降(BGD):

含义

每次要用所有样本

公式

dl_08_001

伪代码:

dl_08_002

优点

可以比较平滑收敛到凸函数的全局最优,非凸函数可以收敛到局部最优(其实当维度很多时候,往往都是全局最优,以后会分析这个问题)

缺点

1)每次迭代需要对所有训练样本进行一次操作,如果训练样本太大,训练速度会非常慢。

2)不利于增量学习,或者说在线学习,一旦有新的样本过来,整个模型需要重新训练。

 

随机梯度下降(SGD):

含义

每次一个样本,而且样本是打乱顺序的,所以用了随机这个词。

公式

dl_08_003

伪代码

dl_08_004

优点

1)每次更新一个样本,计算量小

2)支持增量学习,每次只要将后来的新样本 加入学习即可

缺点

1)但是 SGD 因为更新比较频繁,会造成 cost function 有严重的震荡。

2)由于一个一个学习,学习比较慢

3)可能会到局部最小,也可能跳出局部最小

注意:当我们稍微减小 learning rate,SGD 和 BGD 的收敛性是一样的。

 

小批量随机梯度下降(MBGD,也叫min-batch GD):

含义

Mini-batch梯度下降综合了batch梯度下降与stochastic梯度下降,在每次更新速度与更新次数中间取得一个平衡,其每次更新从训练集中随机选择m,m<n个样本进行学习

公式

dl_08_005

伪代码:

dl_08_006

优点:

1)每次更新一个小batch的样本,在样本很多的时候性能较好

2)支持增量学习,新来的样本,可以作为下一个小batch输入

缺点:

也会有震荡

注意

1)最终效果和SGD,BGD差不多

2)典型的batch size:64,128,256,512

 

不震荡接近最优值与震荡接近最优值

dl_08_007

三者接近最优点图:

dl_08_008

黑色是:BGD

红色是:SGD

蓝色是:Min-Batch GD

 

改进后的随机梯度下降(很多变种):

含义

如果学习率过小,可能学习很慢,学习率过大,可能跳过最优点,最佳的是,学习率可以自我调节,离最优点远的时候比较大,学习快,离最优点近可以减小,否则跳过最优点

dl_08_009

具体算法见下文。

优点

1)学习率自我调节,可以让学习快,又不容易跳过最优点

2)一般深度学习都会用RMSprop,Adam这样的优化器

 

收敛速度对比

dl_08_010

图一是BGD

图二是SGD

图三是改进后的

 

在介绍优化器之前,还需要介绍几个概念:指数加权平均,momentum,decay,nesterov

指数加权平均

已知当前和之前的温度,如何预测未来温度?

已知温度变化:

dl_08_011

温度和哪天的关系:

dl_08_012

如何得到红色线?

dl_08_013

V0温度认为是0

每天预测温度是前一次预测温度取90%,当天温度取0.1来预测。

 

如果用β表示前一次预测温度在预测温度中占的百分比,我们可以得到如下公式:

dl_08_014

当β取0.9的时候,约等于综合向前考虑了前10天的预测温度的平均值:

为啥是10天?

近似可以通过这个公式计算

dl_08_015

为啥?看下图:越近的温度越高权值,越远越低,并且是指数递减,再往前可以忽略:

dl_08_016

通过此,我们可以知道,指数加权平均可以很好地根据历史值,估计下一个值。我们就可以用它来预测学习率!!

 

另外一个问题就是初始几天的值,从0开始,实际上和真实值不准,这个叫做偏差,如图,紫色线是预测值得线,红色是真实值。

dl_08_017

通过如下公式可以得到绿色线,进行修正:

dl_08_018

其实如果我们训练迭代次数多,可以不考虑最初的偏差,因为后面都是拟合的。

指数加权平均优点

1)每次考虑前m个值,由β决定

2)前m个值越近的权值更大,越远的权值更小,最后取平均,更合理

3)修正后初始值也更符合

 

以上就是指数加权平均,后面很多地方会用到。

 

下面我们介绍第二个概念:momentum

如下图

dl_08_019

梯度下降法可以沿梯度方向一直走,达到最优。

但是如下图:

dl_08_020

普通梯度下降法会沿蓝色线,不断接近最优点。

原因

有很多w参数,有的w的梯度方向变化比较小,有的w梯度方向变化大,一起作用,使得其出现蓝色路径。

是否有办法让梯度变化大的w有更大权值变化,而让梯度变化小的w有更小的权值,这样就可以让其按照红色路径达到最优,更快达到最优?

答案:加入momentum

 

如何加入momentum?

dl_08_021

让梯度dw不是只考虑当前dw,而是综合之前dw变化,通过指数加权平均方法,得到Vdw,然后基于此修改w,b类似,也就是说,如果w之前变化就很大,那么Vdw就会很大,最后w也会修改很大。

注意

1)β常用0.9

2)加入的这一项,可以使得梯度方向不变的维度上速度变快,梯度方向有所改变的维度上的更新速度变慢,这样就可以加快收敛并减小震荡。

3)这种情况相当于小球从山上滚下来时是在盲目地沿着坡滚,如果它能具备一些先知,例如快要上坡时,就知道需要减速了的话,适应性会更好。

4)注意还有的文章中会只用一个参数,我们可以统一除以β即可

5)公式另一种写法

dl_08_022

我们再看第三个概念:Nesterov accelerated gradient

其实Nesterov是在momentum基础上进行了进一步修正:

公式如下:

dl_08_023

也就是w先根据之前的进行修正再求导,其效果如下图:

dl_08_024

蓝色是 Momentum 的过程,会先计算当前的梯度,然后在更新后的累积梯度后会有一个大的跳跃。就是公式的两个向量相加。

而 NAG 会先在前一步的累积梯度上(brown vector)有一个大的跳跃,然后衡量一下梯度做一下修正(red vector),这种预期的更新可以避免我们走的太快。也是新公式两项相加。

注意

1)NAG 可以使 RNN 在很多任务上有更好的表现。

2)momentum和NAG 都是在更新梯度时顺应 loss function 的梯度来调整速度,并且对 SGD 进行加速。

3)公式另一种写法

dl_08_025

我们最后看看第四个概念:Decay

这个概念比较简单,就是让学习率会不断变小,这样可以在接近最优解时候,不要跳过最优解。

公式

dl_08_026

一般框架主要的优化器有以下几种

SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)

Adagrad(lr=0.01, epsilon=1e-08, decay=0.0)
Adadelta(lr=1.0, rho=0.95, epsilon=1e-08, decay=0.0)

RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)

Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)

Adamax(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)

Nadam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08, schedule_decay=0.004)

 

其中大部分参数在上面都有介绍,这里就不一一详细介绍。

SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True):

实际上应该是mini-batch

特点

1)lr是学习率

2)decay参数

3)momentum的β

4)nesterov是否用NAG

 

SGD应用momentum和NAG都是改变梯度值,而不是学习率,decay是改变学习率,但是对所有参数都是相同改变,能否让学习率对不同参数自适应更新?

比如有的参数可能已经到了仅需要微调的阶段,但又有些参数由于对应样本少等原因,还需要较大幅度的调动。

请看如下方法。

 

Adagrad(lr=0.01, epsilon=1e-08, decay=0.0):

公式:

dl_08_027

其中 g 为:t 时刻参数 θ_i 的梯度:

dl_08_028

如果是普通的 SGD, 那么 θ_i 在每一时刻的梯度更新公式为:

dl_08_029

但这里的 learning rate η 也随 t 和 i 而变:

Gt,ii是:

dl_08_030

特点:

1)学习率一般取lr=0.01, epsilon=1e-08

2)Adagrad主要优势在于它能够为每个参数自适应不同的学习速率,而一般的人工都是设定为0.01。这个算法就可以对低频的参数做较大的更新,对高频的做较小的更新,也因此,对于稀疏的数据它的表现很好,很好地提高了 SGD 的鲁棒性,例如识别 Youtube 视频里面的猫,训练 GloVe word embeddings,因为它们都是需要在低频的特征上有更大的更新。

3)缺点在于需要计算参数梯度序列平方和,并且学习速率趋势是不断衰减最终达到一个非常小的值。也就是其学习率是单调递减的,训练后期学习率非常小,且需要设置一个起始学习率。下文中的Adadelta便是用来解决该问题的。

 

Adadelta(lr=1.0, rho=0.95, epsilon=1e-08, decay=0.0):用指数加权平均法更新学习率

公式

形式一

dl_08_031

可以简写:

dl_08_032

其中:

dl_08_033

这就是指数加权平均的公式!!!!越近的影响越大,越远的影响越小,考虑多久的由γ决定。

本文标准写法:

dl_08_034

 

形式二:上述式子还存在的问题是单位不匹配问题和学习率初始化问题。所以有如下修正:

dl_08_035

其中:

dl_08_036

 

dl_08_037

 

本文标准写法:

dl_08_038

为什么通过修正公式可以解决单位不匹配问题?

实际上更新梯度,除了SGD方法,还有一种方法叫拟牛顿法:

dl_08_039

单位问题如下:

dl_08_040

第一个式子可以看出,单位是θ倒数。

第二个式子可以看出,如果用Hession方法没问题

我们通过第二个式子导出第三个式子,得到H^-1的表示

然后最后一个式子告诉我们如何近似得到H^-1

于是我们得到了形式二

特点:

1)解决了Adagrad学习率单纯下降问题,Adadelta是通过指数加权平均求解,更合理。

2)参数一般默认值即可

3)形式二还解决了单位不匹配问题和学习率初始值问题。

 

RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0):

公式:

dl_08_041

特点:

1)Hinton提出,未发表,实际上就是Adadelta的第一种形式

2)Hinton 建议设定 γ 为 0.9, 学习率 η 为 0.001。

3)RMSprop 和 Adadelta 都是为了解决 Adagrad 学习率急剧下降问题的

 

Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0):

公式:

dl_08_042

其中式子一是通过指数加权平均对梯度进行调整

式子二通过指数加权平均对梯度平方进行调整

dl_08_043

由于初始部分可能有偏差(见前面介绍),需要通过这两个公式调整

最终的梯度更新规则

dl_08_044

特点:

1)除了像 Adadelta 和 RMSprop 一样存储了过去梯度的平方 vt 的指数衰减平均值 ,也像 momentum 一样保持了过去梯度 mt 的指数衰减平均值,可以认为是RMSprop+momentum

2)如果 mt 和 vt 被初始化为 0 向量,那它们就会向 0 偏置,所以做了偏差校正, 通过计算偏差校正后的 mt 和 vt 来抵消这些偏差

3)建议 β1 = 0.9,β2 = 0.999,ϵ = 10e−8

4)实践表明,Adam 比其他适应性学习方法效果要好。

 

Adamax(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0):

公式:m同上

dl_08_045

特点:

1)Adamax是Adam的一种变体,此方法对学习率的上限提供了一个更简单的范围。

2)Adamax学习率的边界范围更简单

 

Nadam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08, schedule_decay=0.004)

公式:

dl_08_046

前面四个公式不变,都是来自Adam,如果直接第五个公式计算,就是Adam

这时候我们再用类似NAG的方式进行一个微调,得到最后的m,然后得到最后的公式。

特点:

1)Adam = RMSprop+momentum, Nadam = Adam+NAG

 

经验总结:

1)对于稀疏数据,尽量使用学习率可自适应的优化方法,不用手动调节,而且最好采用默认值:即 Adagrad, Adadelta, RMSprop, Adam,Nadam

2)SGD通常训练时间更长,但是在好的初始化和学习率调度方案的情况下,结果更可靠

3)如果在意更快的收敛,并且需要训练较深较复杂的网络时,推荐使用学习率自适应的优化方法。

4)Adadelta,RMSprop,Adam是比较相近的算法,在相似的情况下表现差不多。

5)Adam 就是在 RMSprop 的基础上加了 bias-correction 和 momentum

6)Nadam 就是Adam基础上加了NAG

7)随着梯度变的稀疏,Adam 比 RMSprop 效果会好

8)在想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果

9)如果需要更快的收敛,或者是训练更深更复杂的神经网络,需要用一种自适应的算法

 

最后附上两幅图:

dl_08_047

dl_08_048

上面两种情况都可以看出,Adagrad, Adadelta, RMSprop 几乎很快就找到了正确的方向并前进,收敛速度也相当快,而其它方法要么很慢,要么走了很多弯路才找到。

由图可知自适应学习率方法即 Adagrad, Adadelta, RMSprop, Adam 在这种情景下会更合适而且收敛性更好。