深度学习中各种优化方法的原理和比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)

举报
leo xiao 1 发表于 2020/04/08 10:00:07 2020/04/08
【摘要】 优化方法原理和比较
  • 梯度下降法英语:Gradient descent)是一个一阶最优化算法,通常也称为最速下降法。 要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索。如果相反地向梯度正方向迭代进行搜索,则会接近函数的局部极大值点;这个过程则被称为梯度上升法

梯度下降算法(Gradient Descent Optimization)是神经网络模型训练最常用的优化算法。对于深度学习模型,基本都是采用梯度下降算法来进行优化训练的。

  1. SGD - Stochastic gradient      descent (SGD) 随机梯度下降法,根据每一条训练示例 x (i)和标签 label y (i)执行参数更新 :

        θ = θ η · θJ(θ; x (i) ; y (i) )

 

批量梯度下降为大型数据集执行了冗余计算,因为它会在参数更新前重新计算类似示例的梯度。 SGD通过每执行一次更新一次参数来取消了这种冗余,从而在在线学习上会有更快的速度。但是会导致目标函数的波动很大,如下图所示:

 image.png


SGD很难通过陡谷,即在一个维度上的表面弯曲程度远大于其他维度的区域[19],这种情况通常出现在局部最优点附近。在这种情况下,SGD摇摆地通过陡谷的斜坡,同时,沿着底部到局部最优点的路径上只是缓慢地前进,这个过程如图a

image.png


 

如图2b所示,动量法[16]是一种帮助SGD在相关方向上加速并抑制摇摆的一种方法。动量法将历史步长的更新向量的一个分量γγ增加到当前的更新向量中(部分实现中交换了公式中的符号)

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

θ=θvt

 

动量项γγ通常设置为0.9或者类似的值。

从本质上说,动量法,就像我们从山上推下一个球,球在滚下来的过程中累积动量,变得越来越快(直到达到终极速度,如果有空气阻力的存在,则γ<1γ<1)。同样的事情也发生在参数的更新过程中:对于在梯度点处具有相同的方向的维度,其动量项增大,对于在梯度点处改变方向的维度,其动量项减小。因此,我们可以得到更快的收敛速度,同时可以减少摇摆。

 

 

  • Adagrad

 

  • AdaGrad 会在学习的过程中自动调整 learning rate, 对于出现频率低的参数使用较大的 learning rate, 出现频率高的参数使用较小的 learning rate.      因此, 这种方法对于训练数据比较稀疏的情况比较适用. AdaGrad 可以提高 SGD 的鲁棒性

 

Adagrad是一种基于梯度的优化算法:让学习率适应参数,对于出现次数较少的特征,我们对其采用更大的学习率,对于出现次数较多的特征,我们对其采用较小的学习率。因此,Adagrad非常适合处理稀疏数据。Dean等人[6]发现Adagrad能够极大提高了SGD的鲁棒性并将其应用于Google的大规模神经网络的训练,其中包含了YouTube视频中的猫的识别。此外,Pennington等人利用Adagrad训练Glove词向量,因为低频词比高频词需要更大的步长。

前面,我们每次更新所有的参数θθ时,每一个参数θiθi都使用的是相同的学习率ηη。由于Adagrad在tt时刻对每一个参数θiθi使用了不同的学习率,我们首先介绍Adagrad对每一个参数的更新,然后我们对其向量化。为了简洁,令gt,igt,i为在tt时刻目标函数关于参数θiθi的梯度:

        gt,i=θJ(θi)

tt时刻,对每个参数θiθi的更新过程变为:

     θt+1,it,iηgt,I

对于上述的更新规则,在tt时刻,基于对θiθi计算过的历史梯度,Adagrad修正了对每一个参数θiθi的学习率:

image.png

 

其中,GtRd×dGtRd×d是一个对角矩阵,对角线上的元素i,ii,i是直到tt时刻为止,所有关于θiθi的梯度的平方和(Duchi等人[7]将该矩阵作为包含所有先前梯度的外积的完整矩阵的替代,因为即使是对于中等数量的参数dd,矩阵的均方根的计算都是不切实际的。),ϵϵ是平滑项,用于防止除数为0(通常大约设置为1e81e8)。比较有意思的是,如果没有平方根的操作,算法的效果会变得很差。

由于GtGt的对角线上包含了关于所有参数θθ的历史梯度的平方和,现在,我们可以通过GtGt和gtgt之间的元素向量乘法向量化上述的操作:

θt+1tηGt+ϵ−−−−−√⊙gtθt+1=θtηGt+ϵgt

Adagrad算法的一个主要优点是无需手动调整学习率。在大多数的应用场景中,通常采用常数0.010.01。

Adagrad的一个主要缺点是它在分母中累加梯度的平方:由于没增加一个正项,在整个训练过程中,累加的和会持续增长。这会导致学习率变小以至于最终变得无限小,在学习率无限小时,Adagrad算法将无法取得额外的信息。接下来的算法旨在解决这个不足。

 

 

 

  • Adadelta 

Adadelta 是Adagrad的一种扩展算法,以处理Adagrad学习速率单调递减的问题。不是计算所有的梯度平方,Adadelta将计算计算历史梯度的窗口大小限制为一个固定值ww。

在Adadelta中,无需存储先前的ww个平方梯度,而是将梯度的平方递归地表示成所有历史梯度平方的均值。在tt时刻的均值E[g2]tE[g2]t只取决于先前的均值和当前的梯度(分量γγ类似于动量项):

image.png

我们将γγ设置成与动量项相似的值,即0.90.9左右。为了简单起见,我们利用参数更新向量ΔθtΔθt重新表示SGD的更新过程:

 

image.png

 

我们先前得到的Adagrad参数更新向量变为:

image.png

现在,我们简单将对角矩阵GtGt替换成历史梯度的均值E[g2]tE[g2]t:

image.png

 

由于分母仅仅是梯度的均方根(root mean squared,RMS)误差,我们可以简写为:

image.png

作者指出上述更新公式中的每个部分(与SGD,动量法或者Adagrad)并不一致,即更新规则中必须与参数具有相同的假设单位。为了实现这个要求,作者首次定义了另一个指数衰减均值,这次不是梯度平方,而是参数的平方的更新:

image.png

因此,参数更新的均方根误差为:

image.png

由于RMS[Δθ]tRMS[Δθ]t是未知的,我们利用参数的均方根误差来近似更新。利用RMS[Δθ]t1RMS[Δθ]t1替换先前的更新规则中的学习率ηη,最终得到Adadelta的更新规则:

image.png

使用Adadelta算法,我们甚至都无需设置默认的学习率,因为更新规则中已经移除了学习率。

 

特点:

  • 训练初中期,加速效果不错,很快

  • 训练后期,反复在局部最小值附近抖动

 

 

  • Adam

自适应矩估计(Adaptive Moment Estimation,Adam)是另一种自适应学习率的算法,Adam对每一个参数都计算自适应的学习率。除了像Adadelta和RMSprop一样存储一个指数衰减的历史平方梯度的平均vtvt,Adam同时还保存一个历史梯度的指数衰减均值mtmt,类似于动量:

image.png

 

mtmt和vtvt分别是对梯度的一阶矩(均值)和二阶矩(非确定的方差)的估计,正如该算法的名称。当mtmt和vtvt初始化为0向量时,Adam的作者发现它们都偏向于0,尤其是在初始化的步骤和当衰减率很小的时候(例如β1β1和β2β2趋向于1)。

通过计算偏差校正的一阶矩和二阶矩估计来抵消偏差:

image.png

正如我们在Adadelta和RMSprop中看到的那样,他们利用上述的公式更新参数,由此生成了Adam的更新规则:

image.png

作者建议β1β1取默认值为0.90.9,β2β2为0.9990.999,ϵϵ108108。他们从经验上表明Adam在实际中表现很好,同时,与其他的自适应学习算法相比,其更有优势。

 

特点:

  • 结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点

  • 对内存需求较小

  • 为不同的参数计算不同的自适应学习率

  • 也适用于大多非凸优化 -      适用于大数据集和高维空间

 

 

 

 

  • Adamax:针对Adam做过优化的算法,

此方法对学习率的上限提供了一个更简单的范围。公式上的变化如下:

 

image.png

 

  • Nadam

Nadam类似于带有Nesterov动量项的Adam。公式如下:

 

image.png

Nadam对学习率有了更强的约束,同时对梯度的更新也有更直接的影响。一般而言,在想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果。

测试代码:

image.png

 

Loss对比图:

image.png

 

测试Accuracy 对比图:

image.png

 

训练 Accuracy 对比图:

image.png

 

参考:

https://arxiv.org/pdf/1609.04747.pdf

 

https://keras.io/optimizers/

 

https://cs.stanford.edu/people/karpathy/convnetjs/demo/trainers.html

 

http://www.matthewzeiler.com/wp-content/uploads/2017/07/googleTR2012.pdf

 

https://blog.csdn.net/u013709270/article/details/78667531

 

https://yoyoyohamapi.gitbooks.io/mit-ml/content/%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92/articles/%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92%E4%B8%8E%E6%A2%AF%E5%BA%A6%E4%B8%8B%E9%99%8D.html


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。