optimizer

在不少机器学习和深度学习的应用中,咱们发现用的最多的优化器是 Adam,为何呢?html

下面是 TensorFlow 中的优化器, 
https://www.tensorflow.org/api_guides/python/train 
这里写图片描述python

在 keras 中也有 SGD,RMSprop,Adagrad,Adadelta,Adam 等: 
https://keras.io/optimizers/算法

咱们能够发现除了常见的梯度降低,还有 Adadelta,Adagrad,RMSProp 等几种优化器,都是什么呢,又该怎么选择呢?api

在 Sebastian Ruder 的这篇论文中给出了经常使用优化器的比较,今天来学习一下: 
https://arxiv.org/pdf/1609.04747.pdf网络

本文将梳理:机器学习

  • 每一个算法的梯度更新规则和缺点
  • 为了应对这个不足而提出的下一个算法
  • 超参数的通常设定值
  • 几种算法的效果比较
  • 选择哪一种算法

优化器算法简述?

首先来看一下梯度降低最多见的三种变形 BGD,SGD,MBGD, 
这三种形式的区别就是取决于咱们用多少数据来计算目标函数的梯度, 
这样的话天然就涉及到一个 trade-off,即参数更新的准确率和运行时间。ide

1. Batch gradient descent
  • 1
  • 2

梯度更新规则
BGD 采用整个训练集的数据来计算 cost function 对参数的梯度: 函数

θ=θαθJ(θ)

 

缺点
因为这种方法是在一次更新中,就对整个数据集计算梯度,因此计算起来很是慢,遇到很大量的数据集也会很是棘手,并且不能投入新数据实时更新模型学习

咱们会事先定义一个迭代次数 epoch,首先计算梯度向量 params_grad,而后沿着梯度的方向更新参数 params,learning rate 决定了咱们每一步迈多大。优化

Batch gradient descent 对于凸函数能够收敛到全局极小值,对于非凸函数能够收敛到局部极小值。

2. Stochastic gradient descent
  • 1
  • 2

梯度更新规则
和 BGD 的一次用全部数据计算梯度相比,SGD 每次更新时对每一个样本进行梯度更新, 对于很大的数据集来讲,可能会有类似的样本,这样 BGD 在计算梯度时会出现冗余, 而 SGD 一次只进行一次更新,就没有冗余,并且比较快,而且能够新增样本。

缺点
SGD 由于更新比较频繁,会形成 cost function 有严重的震荡,此外SGD对噪声比较敏感。

这里写图片描述

BGD 能够收敛到局部极小值,固然 SGD 的震荡可能会跳到更好的局部极小值处。

当咱们稍微减少 learning rate,SGD 和 BGD 的收敛性是同样的。

3. Mini-batch gradient descent
  • 1
  • 2

梯度更新规则
MBGD 每一次利用一小批样本,即 n 个样本进行计算, 这样它能够下降参数更新时的方差,收敛更稳定, 另外一方面能够充分地利用深度学习库中高度优化的矩阵操做来进行更有效的梯度计算。 
和 SGD 的区别是每一次循环不是做用于每一个样本,而是具备 n 个样本的Batch。

超参数设定值: 
n 通常取值在 50~200

缺点
Mini-batch gradient descent 不能保证很好的收敛性,

①learning rate 若是选择的过小,收敛速度会很慢,若是太大,loss function 就会在极小值处不停地震荡甚至偏离。

②有一种措施是先设定大一点的学习率,当两次迭代之间的变化低于某个阈值后,就减少 learning rate,不过这个阈值的设定须要提早写好,这样的话就不可以适应数据集的特色。此外,这种方法是对全部参数更新时应用一样的 learning rate,若是咱们的数据是稀疏的,咱们更但愿对出现频率低的特征进行大一点的更新

③另外,对于非凸函数,还要避免陷于局部极小值处,或者鞍点处,由于鞍点周围的error 是同样的,全部维度的梯度都接近于0,SGD 很容易被困在这里。

鞍点:一个光滑函数的鞍点邻域的曲线,曲面,或超曲面,都位于这点的切线的不一样边。 
例如这个二维图形,像个马鞍:在x-轴方向往上曲,在y-轴方向往下曲,鞍点就是(0,0)

这里写图片描述

为了应对上面的三点挑战就有了下面这些算法。

[应对挑战 1]

4. Momentum(动量法)
  • 1
  • 2

SGD 在 ravines 的状况下容易被困住, ravines就是曲面的一个方向比另外一个方向更陡,这时 SGD 会发生震荡而迟迟不能接近极小值:

这里写图片描述

梯度更新规则
Momentum 经过加入 γvt1 ,能够加速 SGD, 而且抑制震荡 

vt=γvt1+αθJ(θ)

 

θ=θvt


当咱们将一个小球从山上滚下来时,没有阻力的话,它的动量会愈来愈大,可是若是遇到了阻力,速度就会变小。 
加入的这一项,可使得梯度方向不变的维度上速度变快,梯度方向有所改变的维度上的更新速度变慢,这样就能够加快收敛并减少震荡。

 

超参数设定值: 
通常 γ取值 0.9 左右。

缺点: 
这种状况至关于小球从山上滚下来时是在盲目地沿着坡滚,若是它能具有一些先知,例如快要上坡时,就知道须要减速了的话,适应性会更好。

5. Nesterov accelerated gradient(NAG)
  • 1
  • 2

梯度更新规则
用 θγvt1来近似当作参数下一步会变成的值,则在计算梯度时,不是在当前位置,而是将来的位置上 

vt=γvt1+αθJ(θγvt1)


θ=θvt


超参数设定值: 
γ仍然取值 0.9 左右。

 

效果比较: 
这里写图片描述

蓝色是 Momentum 的过程,会先计算当前的梯度,而后在更新后的累积梯度后会有一个大的跳跃。 
而 NAG 会先在前一步的累积梯度上(brown vector)有一个大的跳跃,而后衡量一下梯度作一下修正(red vector),这种预期的更新能够避免咱们走的太快。

NAG 可使 RNN 在不少任务上有更好的表现。

目前为止,咱们能够作到,在更新梯度时顺应 loss function 的梯度来调整速度,而且对 SGD 进行加速。

咱们还但愿能够根据参数的重要性而对不一样的参数进行不一样程度的更新。

[应对挑战 2]

6. Adagrad
  • 1
  • 2

这个算法就能够对低频的参数作较大的更新,对高频的作较小的更新,也所以,对于稀疏的数据它的表现很好,很好地提升了 SGD 的鲁棒性,例如识别 Youtube 视频里面的猫,训练 GloVe word embeddings,由于它们都是须要在低频的特征上有更大的更新。

梯度更新规则

θt+1,i=θt,iαGt,ii+ϵ−−−−−−−√gt,i

 

其中gt,i为:t 时刻参数 θi的梯度;Gt是个对角矩阵, (i,i) 元素就是 t 时刻参数 θi 的梯度gt,i的平方和。

Adagrad 的优势是减小了学习率的手动调节

超参数设定值: 
通常 η 就取 0.01。

缺点: 
它的缺点是分母会不断积累,这样学习率就会收缩并最终会变得很是小。

7. Adadelta
  • 1
  • 2

这个算法是对 Adagrad 的改进, 

Δθt=αE[g2]t+ϵ−−−−−−−−√gt


和 Adagrad 相比,就是分母的G换成了过去的梯度平方E[g2]t的衰减平均值。

 

这个分母至关于梯度的均方根 root mean squared (RMS) ,因此能够用 RMS 简写: 

Δθt=αRMS[g]tgt

 

其中 E 的计算公式以下,t 时刻的依赖于前一时刻的平均和当前的梯度:

 

E[g2]t=γE[g2]t1+(1γ)g2t

 

梯度更新规则:

此外,还将学习率 α换成了 RMS[Δθ],这样的话,咱们甚至都不须要提早设定学习率了: 
这里写图片描述

超参数设定值: 
γ 通常设定为 0.9,

7. RMSprop
  • 1
  • 2

RMSprop 是 Geoff Hinton 提出的一种自适应学习率方法。

RMSprop 和 Adadelta 都是为了解决 Adagrad 学习率急剧降低问题的。

梯度更新规则
RMSprop 与 Adadelta 的第一种形式相同: 

E[g2]t=0.9E[g2]t1+0.1g2t


θt+1=θtαE[g2]t+ϵ−−−−−−−−√gt

 

超参数设定值: 
Hinton 建议设定 γ为 0.9, 学习率 α为 0.001。

8. Adam
  • 1
  • 2

这个算法是另外一种计算每一个参数的自适应学习率的方法。目前在DL领域,是最多见的优化器。

除了像 Adadelta 和 RMSprop 同样存储了过去梯度的平方 vt 的指数衰减平均值 ,也像 momentum 同样保持了过去梯度 mt的指数衰减平均值: 
这里写图片描述

若是 mt和 vt 被初始化为 0 向量,那它们就会向 0 偏置,因此作了误差校订, 
经过计算误差校订后的 mt 和 vt 来抵消这些误差: 
这里写图片描述

梯度更新规则

θt+1=θtαvt+ϵ−−−−−√mt

 

超参数设定值: 
建议 β1 = 0.9,β2 = 0.999,ϵ = 10e−8

实践代表,Adam 比其余适应性学习方法效果要好。

效果比较?

下面看一下几种算法在鞍点和等高线上的表现: 
这里写图片描述 
这里写图片描述 
上面两种状况均可以看出,Adagrad, Adadelta, RMSprop 几乎很快就找到了正确的方向并前进,收敛速度也至关快,而其它方法要么很慢,要么走了不少弯路才找到。

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

如何选择?

若是数据是稀疏的,就用自适应方法,即 Adagrad, Adadelta, RMSprop, Adam。

RMSprop, Adadelta, Adam 在不少状况下的效果是类似的。

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

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

总体来说,Adam 是最好的选择。

不少论文里都会用 SGD,没有 momentum 等。SGD 虽然能达到极小值,可是比其它算法用的时间长,并且可能会被困在鞍点。

若是须要更快的收敛,或者是训练更深更复杂的神经网络,须要用一种自适应的算法。

参考:

http://sebastianruder.com/optimizing-gradient-descent/index.html#fn:24 
http://www.redcedartech.com/pdfs/Select_Optimization_Method.pdf 
https://stats.stackexchange.com/questions/55247/how-to-choose-the-right-optimization-algorithm

相关文章
相关标签/搜索