资讯详情

Adam那么棒,为什么还对SGD念念不忘?一个框架看懂深度学习优化算法

 
     
点击上面的小白学视觉"星标"或“置顶” 重磅干货,第一时间送达

作者|Juliuszh,https://zhuanlan.zhihu.com/juliuszh

机器学习界有一群炼丹师,他们的日常生活是:

拿着药材(数据),架起八卦炉(模型),点着六味真火(优化算法),摇着蒲扇等丹药出炉。

然而,做过厨师的人都知道,同样的食材,同样的食谱,但温度是不同的,但味道是非常不同的。火小夹,火大容易糊,火不均匀半糊。

机器学习也是如此,模型优化算法的选择与最终模型的性能直接相关。有时效果不好,不一定是特征问题或模型设计问题,可能是优化算法问题。

说到优化算法,入门级必从SGD老司机会告诉你更好AdaGrad/AdaDelta,或直接无脑使用Adam。但是看看学术界最新的paper,但是发现很多大神还在用入门级SGD,最多加个Moment或者Nesterov ,它经常变黑Adam。比如 UC Berkeley一篇论文就在Conclusion中写道:

Despite the fact that our experimental evidence demonstrates that adaptive methods are not advantageous for machine learning, the Adam algorithm remains incredibly popular. We are not sure exactly as to why ……

无奈与酸楚之情溢于言表。

为什么会这样?平平淡淡是真的吗?

1 框架回顾优化算法

首先,让我们回顾一下各种优化算法。

深度学习优化算法经验 SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam 这样的发展过程。Google你可以看到很多教程文章,详细告诉你这些算法是如何逐步演变的。在这里,我们改变主意,用框架梳理所有优化算法,做出更高的战略对比。

定义:待优化参数: ,目标函数: ,初始学习率。

然后,开始迭代优化。在每一个。epoch :

  1. 计算目标函数关于当前参数的梯度:

  2. 一阶动量和二阶动量按历史梯度计算:

  3. 计算当前时降梯度:

  4. 按下降梯度更新:

掌握了这个框架,就可以轻松设计自己的优化算法。

我们拿着这个框架,看看各种神秘的优化算法的真实身体。步骤3和4对每个算法都是一致的,主要区别体现在1和2上。

SGD

先来看SGD。SGD没有动量的概念,也就是说:

代入步骤3,你可以看到下降梯度是最简单的

SGD最大的缺点是下降速度慢,沟壑两侧可能会继续波动,并保持局部优势。

SGD with Momentum

为了抑制SGD的震荡,SGDM认为惯性可以添加到梯度下降过程中。下坡时,如果发现陡坡,用惯性跑得更快。SGDM全称是SGD with momentum,在SGD一阶动量在此基础上引入:

每个时刻梯度方向的指数移动平均值约等于最近 梯度向量和平均值。

也就是说,t时刻的下降方向不仅取决于当前点的梯度方向,还取决于以往累积的下降方向。 的经验值为0.9.这意味着下降方向主要是以前积累的下降方向,并略微偏向于当前时刻的下降方向。想象一下汽车在高速公路上转弯,在高速公路上同时略有偏差,但急转弯会发生事故。

SGD with Nesterov Acceleration

SGD 另一个问题是被困在当地最好的沟壑中。想象一下,当你走到一个盆地时,周围是一座略高的山。如果你认为没有下坡的方向,你只能呆在这里。但如果你爬上高地,你会发现外面的世界仍然很广阔。因此,我们不能停留在当前的位置来观察未来的方向,而是要向前一步,多看一步,远看。

NAG全称Nesterov Accelerated Gradient,是在SGD、SGD-M进一步改进的基础在于步骤1。我们知道t的主要下降方向是由累积动量决定的,我们自己的梯度方向不是。与其看当前的梯度方向,不如看看当时的累积动量。因此,NAG在步骤1中,不计算当前位置的梯度方向,而是计算当时的下降方向:

然后将下一点的梯度方向与历史累积动量相结合,计算步骤2中当前时刻的累积动量。

AdaGrad

我们以前没有使用过二阶动量。二阶动量的出现,才意味着“自适应学习率”优化算法时代的到来。SGD每个参数以相同的学习率更新,但深度神经网络通常包含大量的参数,并不总是使用(考虑大规模的参数embedding)。对于经常更新的参数,我们积累了大量的知识,不想受到单个样本的太大影响,希望学习速度慢;对于偶尔更新的参数,我们知道的信息太少,希望从每个偶然的样本中学习更多,即学习速度更高。

如何衡量历史更新的频率?即二阶动量-到目前为止所有梯度值的平方和:

让我们回顾一下步骤3中的下降梯度:

可以看出,此时学习率的实质性原因 变成了 。一般为了避免分母为0,会在分母上加一个小的平滑项。因此 恒大于0,参数更新越频繁,二阶动量越大,学习率越低。

这种方法在稀疏数据场景中表现良好。但也有一些问题:因为 单调增加会使学习率单调降至0,可能会使训练过程提前结束,即使有数据也无法学习必要的知识。

AdaDelta / RMSProp

由于AdaGrad单调下降的学习率变化过于激进。我们考虑了一种改变二级动量计算方法的策略:只关注过去窗口的下降梯度,而不是积累所有的历史梯度。AdaDelta名称中Delta的来历。

修改的想法很简单。正如我们前面所说,指数移动的平均值大约是过去一段时间的平均值,所以我们使用这种方法来计算第二阶段的累积动量:

这避免了二阶动量持续积累,导致训练过程提前结束的问题。

Adam

谈到这里,Adam和Nadam它的出现是很自然的——它们是上述方法的集大成者。我们可以看到,SGD-M在SGD一阶动量在此基础上增加,AdaGrad和AdaDelta在SGD二阶动量在此基础上增加。使用一阶动量和二阶动量,即Adam了——Adaptive Momentum。

SGD一步动量:

加上AdaDelta二阶动量:

优化算法中最常见的两个超参数 就在这里,前者控制一阶动量,后者控制二阶动量。

Nadam

最后是Nadam。我们说Adam它是一个集大成者,但它实际上被遗漏了Nesterov,这还能忍吗?必须加上,按照NAG的步骤1:

这就是Nesterov Adam = Nadam了。

补充:指数移动平均值偏差修正

正如我们前面所说,一阶动量和二阶动量按指数移动平均值行计算的:

实际使用过程中,参数的经验值是

初始化:

这个时候我们看到,在初期,  都会接近于0,这个估计是有问题的。因此我们常常根据下式进行误差修正:

说到这里,大概可以理解为什么j经常有人说 Adam / Nadam 目前最主流、最好用的优化算法了。新手上路,先拿来一试,收敛速度嗖嗖滴,效果也是杠杠滴。

那为什么Adam还老招人黑,被学术界一顿鄙夷?难道只是为了发paper灌水吗?

请继续阅读:

2 Adam的两宗罪

可以看到,一代又一代的研究者们为了我们能炼(xun)好(hao)金(mo)丹(xing)可谓是煞费苦心。从理论上看,一代更比一代完善,Adam/Nadam已经登峰造极了,为什么大家还是不忘初心SGD呢?

举个栗子。很多年以前,摄影离普罗大众非常遥远。十年前,傻瓜相机开始风靡,游客几乎人手一个。智能手机出现以后,摄影更是走进千家万户,手机随手一拍,前后两千万,照亮你的美(咦,这是什么乱七八糟的)。但是专业摄影师还是喜欢用单反,孜孜不倦地调光圈、快门、ISO、白平衡……一堆自拍党从不care的名词。技术的进步,使得傻瓜式操作就可以得到不错的效果,但是在特定的场景下,要拍出最好的效果,依然需要深入地理解光线、理解结构、理解器材。

优化算法大抵也如此。在上一篇中,我们用同一个框架让各类算法对号入座。可以看出,大家都是殊途同归,只是相当于在SGD基础上增加了各类学习率的主动控制。如果不想做精细的调优,那么Adam显然最便于直接拿来上手。

但这样的傻瓜式操作并不一定能够适应所有的场合。如果能够深入了解数据,研究员们可以更加自如地控制优化迭代的各类参数,实现更好的效果也并不奇怪。毕竟,精调的参数还比不过傻瓜式的Adam,无疑是在挑战顶级研究员们的炼丹经验!

最近,不少paper开怼Adam,我们简单看看都在说什么:

Adam罪状一:可能不收敛

这篇是正在深度学习领域顶级会议之一 ICLR 2018 匿名审稿中的 On the Convergence of Adam and Beyond,探讨了Adam算法的收敛性,通过反例证明了Adam在某些情况下可能会不收敛。

回忆一下上文提到的各大优化算法的学习率:

其中,SGD没有用到二阶动量,因此学习率是恒定的(实际使用过程中会采用学习率衰减策略,因此学习率递减)。AdaGrad的二阶动量不断累积,单调递增,因此学习率是单调递减的。因此,这两类算法会使得学习率不断递减,最终收敛到0,模型也得以收敛。

但AdaDelta和Adam则不然。二阶动量是固定时间窗口内的累积,随着时间窗口的变化,遇到的数据可能发生巨变,使得  可能会时大时小,不是单调变化。这就可能在训练后期引起学习率的震荡,导致模型无法收敛。

这篇文章也给出了一个修正的方法。由于Adam中的学习率主要是由二阶动量控制的,为了保证算法的收敛,可以对二阶动量的变化进行控制,避免上下波动。

通过这样修改,就保证了  ,从而使得学习率单调递减。

Adam罪状二:可能错过全局最优解

深度神经网络往往包含大量的参数,在这样一个维度极高的空间内,非凸的目标函数往往起起伏伏,拥有无数个高地和洼地。有的是高峰,通过引入动量可能很容易越过;但有些是高原,可能探索很多次都出不来,于是停止了训练。

近期Arxiv上的两篇文章谈到这个问题。

第一篇就是前文提到的吐槽Adam最狠的 The Marginal Value of Adaptive Gradient Methods in Machine Learning 。文中说到,同样的一个优化问题,不同的优化算法可能会找到不同的答案,但自适应学习率的算法往往找到非常差的答案。他们通过一个特定的数据例子说明,自适应学习率算法可能会对前期出现的特征过拟合,后期才出现的特征很难纠正前期的拟合效果。

另外一篇是 Improving Generalization Performance by Switching from Adam to SGD,进行了实验验证。他们CIFAR-10数据集上进行测试,Adam的收敛速度比SGD要快,但最终收敛的结果并没有SGD好。他们进一步实验发现,主要是后期Adam的学习率太低,影响了有效的收敛。他们试着对Adam的学习率的下界进行控制,发现效果好了很多。

于是他们提出了一个用来改进Adam的方法:前期用Adam,享受Adam快速收敛的优势;后期切换到SGD,慢慢寻找最优解。这一方法以前也被研究者们用到,不过主要是根据经验来选择切换的时机和切换后的学习率。这篇文章把这一切换过程傻瓜化,给出了切换SGD的时机选择方法,以及学习率的计算方法,效果看起来也不错。

到底该用Adam还是SGD?

所以,谈到现在,到底Adam好还是SGD好?这可能是很难一句话说清楚的事情。去看学术会议中的各种paper,用SGD的很多,Adam的也不少,还有很多偏爱AdaGrad或者AdaDelta。可能研究员把每个算法都试了一遍,哪个出来的效果好就用哪个了。

而从这几篇怒怼Adam的paper来看,多数都构造了一些比较极端的例子来演示了Adam失效的可能性。这些例子一般过于极端,实际情况中可能未必会这样,但这提醒了我们,**理解数据对于设计算法的必要性。**优化算法的演变历史,都是基于对数据的某种假设而进行的优化,那么某种算法是否有效,就要看你的数据是否符合该算法的胃口了。

另一方面,Adam之流虽然说已经简化了调参,但是并没有一劳永逸地解决问题,默认参数虽然好,但也不是放之四海而皆准。因此,在充分理解数据的基础上,依然需要根据数据特性、算法特性进行充分的调参实验,找到自己炼丹的最优解。而这个时候,不论是Adam,还是SGD,于你都不重要了。

少年,好好炼丹吧。

关于优化算法的选择和tricks,欢迎继续阅读:

3 优化算法的选择与使用策略

上文中,我们用一个框架梳理了各大优化算法,并且指出了以Adam为代表的自适应学习率优化算法可能存在的问题。那么,在实践中我们应该如何选择呢?

下文介绍Adam+SGD的组合策略,以及一些比较有用的tricks。

不同优化算法的核心差异:下降方向

从第一篇的框架中我们看到,不同优化算法最核心的区别,就是第三步所执行的下降方向:

这个式子中,前半部分是实际的学习率(也即下降步长),后半部分是实际的下降方向。SGD算法的下降方向就是该位置的梯度方向的反方向,带一阶动量的SGD的下降方向则是该位置的一阶动量方向。自适应学习率类优化算法为每个参数设定了不同的学习率,在不同维度上设定不同步长,因此其下降方向是缩放过(scaled)的一阶动量方向。

An empirical analysis of the optimization of deep network loss surfaces这篇论文中做了一个有趣的实验,他们把目标函数值和相应的参数形成的超平面映射到一个三维空间,这样我们可以直观地看到各个算法是如何寻找超平面上的最低点的。

3ab77d19a9884add15ba76cb4e44eea2.png

上图是论文的实验结果,横纵坐标表示降维后的特征空间,区域颜色则表示目标函数值的变化,红色是高原,蓝色是洼地。他们做的是配对儿实验,让两个算法从同一个初始化位置开始出发,然后对比优化的结果。可以看到,几乎任何两个算法都走到了不同的洼地,他们中间往往隔了一个很高的高原。这就说明,

Adam+SGD 组合策略

正是在每一个十字路口的选择,决定了你的归宿。如果上天能够给我一个再来一次的机会,我会对那个女孩子说:SGD!

不同优化算法的优劣依然是未有定论的争议话题。据我在paper和各类社区看到的反馈,主流的观点认为:Adam等自适应学习率算法对于稀疏数据具有优势,且收敛速度很快;但精调参数的SGD(+Momentum)往往能够取得更好的最终结果。

那么我们就会想到,可不可以把这两者结合起来,,一举两得?思路简单,但里面有两个技术问题:

  1. ——如果切换太晚,Adam可能已经跑到自己的盆地里去了,SGD再怎么好也跑不出来了。

  2. ——Adam用的是自适应学习率,依赖的是二阶动量的累积,SGD接着训练的话,用什么样的学习率?

上文中提到的论文 Improving Generalization Performance by Switching from Adam to SGD 提出了解决这两个问题的思路。

。Adam的下降方向是

而SGD的下降方向是

.

必定可以分解为  所在方向及其正交方向上的两个方向之和,那么其在  方向上的投影就意味着SGD在Adam算法决定的下降方向上前进的距离,而在  的正交方向上的投影是 SGD 在自己选择的修正方向上前进的距离。

图片来自原文,这里p为Adam下降方向,g为梯度方向,r为SGD的学习率。

如果SGD要走完Adam未走完的路,那就首先要接过Adam的大旗——沿着  方向走一步,而后在沿着其正交方向走相应的一步。

这样我们就知道该如何确定SGD的步长(学习率)了——。也即:

解这个方程,我们就可以得到接续进行SGD的学习率:

为了减少噪声影响,作者使用移动平均值来修正对学习率的估计:

这里直接复用了Adam的  参数。

作者的回答也很简单,那就是当 SGD的相应学习率的移动平均值基本不变的时候,即:

. 每次迭代玩都计算一下SGD接班人的相应学习率,如果发现基本稳定了,那就SGD以  为学习率接班前进。

优化算法的常用tricks

最后,分享一些在优化算法的选择和使用方面的一些tricks。

  1. (Standford 231n : The two recommended updates to use are either SGD+Nesterov Momentum or Adam

  2. ——这样你可以更加熟练地利用你的经验进行调参。

  3. ——如果模型是非常稀疏的,那么优先考虑自适应学习率的算法。

  4. ——在模型设计实验过程中,要快速验证新模型的效果,可以先用Adam进行快速实验优化;在模型上线或者结果发布前,可以用精调的SGD进行模型的极致优化。

  5. 有论文研究指出,随机梯度下降算法的收敛速度和数据集的大小的关系不大。(The mathematics of stochastic gradient descent are amazingly independent of the training set size. In particular, the asymptotic SGD convergence rates are independent from the sample size. [2])因此可以先用一个具有代表性的小数据集进行实验,测试一下最好的优化算法,并通过参数搜索来寻找最优的训练参数。

  6. 先用Adam进行快速下降,而后再换到SGD进行充分的调优。切换策略可以参考本文介绍的方法。

  7. 这样在使用自适应学习率算法的时候,可以避免某些特征集中出现,而导致的有时学习过度、有时学习不足,使得下降方向出现偏差的问题。

  8. 训练过程中上的目标函数值以及精度或者AUC等指标的变化情况。对训练数据的监控是要保证模型进行了充分的训练——下降方向正确,且学习率足够高;对验证数据的监控是为了避免出现过拟合。

  9. 可以使用定期衰减策略,比如每过多少个epoch就衰减一次;或者利用精度或者AUC等性能指标来监控,当测试集上的指标不变或者下跌时,就降低学习率。

这里只列举出一些在优化算法方面的trick,如有遗漏,欢迎各位在评论中补充,我将持续更新此文。提前致谢!

神经网络模型的设计和训练要复杂得多,initialization, activation, normalization 等等无不是四两拨千斤,这些方面的技巧我再慢慢写,欢迎关注作者的知乎专栏和微信公众号(Julius-AI),一起交流学习。

参考文献:

[1] CS231n Convolutional Neural Networks for Visual Recognition

[2] Stochastic Gradient Descent Tricks.

[3] Efficient BackProp

 
     

开始面向外开放啦👇👇👇

 
     

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。


下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。


下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。


交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

标签: 常见传感器可监控司机

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台