首页 > 图灵资讯 > 技术篇>正文

【深度学习】Adam那么棒,为什么还对SGD念念不忘?一文看懂深度学习优化算法...

2023-05-09 10:02:30

  导读

  本文分析了Adam和SGD算法的优缺点,深入阐述了优化算法的选择和使用策略,希望对读者有所帮助。

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

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

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

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

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

  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 这样的发展过程。谷歌可以看到很多教程文章,详细告诉你这些算法是如何一步一步演变的。在这里,我们改变主意,用框架梳理所有优化算法,做出更高的战略对比。

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

  然后开始迭代优化。每个epoch。: 计算目标函数关于当前参数的梯度: 一阶动量和二阶动量按历史梯度计算: 计算当前时刻的下降梯度: 按下降梯度更新:

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

  我们拿着这个框架,照一照各种玄乎其玄的优化算法的真实身体。步骤3、每个算法都是一致的,主要区别体现在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 另一个问题是被困在当地最好的沟壑中。想象一下,当你走到一个盆地时,周围是一座略高的山。如果你认为没有下坡的方向,你只能呆在这里。但是如果你爬上高地,你会发现外面的世界仍然很广阔。因此,我们不应该停留在当前的位置来观察未来的方向,而应该向前一步,多看一步,远看。

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

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

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

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

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

  可以看出,此时的实质性学习率已经从转变为。一般来说,为了避免分母为0,会在分母上添加一个小的平滑项。因此,恒大超过0,参数更新越频繁,二级动量越大,学习率越小。

  这种方法在稀疏的数据场景中表现得很好。但也存在一些问题:由于单调的增加,学习率单调到0,可能会提前结束训练过程,即使有后续的数据也不能学习必要的知识。AdaDelta / RMSProp

  由于Adagrad单调递减的学习率变化过于激进,我们考虑了一种改变二阶动量计算方法的策略:只关注过去一段时间窗口的下降梯度,而不是积累所有的历史梯度。这就是Delta在Adadelta名称中的起源。

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

  这避免了二阶动量持续积累,导致训练过程提前结束的问题。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、白平衡...一堆自拍党从不在乎的名词。随着技术的进步,傻瓜操作可以取得良好的效果,但在特定场景下,仍然需要对光线、结构和设备有深入的了解。

  优化算法也是如此。在最后一篇文章中,我们使用相同的框架来使用各种算法。可以看出,每个人都有相同的目的,但这相当于在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。也许研究人员已经尝试了每个算法,使用任何效果好的算法。

  从这些愤怒的Adampaper来看,大部分都构建了一些极端的例子来演示Adam失败的可能性。这些例子通常过于极端,在实践中可能不是这样,但这提醒我们**理解数据对设计算法的必要性。**优化算法的演变历史是基于对数据的某种假设的优化,所以一个算法是否有效取决于你的数据是否符合算法的胃口。

  算法很美,数据是基础。

  另一方面,虽然Adam的流量简化了参数调整,但它并没有一劳永逸地解决问题。虽然默认参数很好,但它并不普遍。因此,在充分理解数据的基础上,仍然需要根据数据特征和算法特征进行充分的参数调整实验,以找到自己炼金术的最佳解决方案。此时,Adam和SGD对你来说都不重要。

  少年,好好炼丹吧。

  请继续阅读优化算法的选择和tricks:3 优化算法的选择和使用策略

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

  以下是Adam+SGD的组合策略,以及一些有用的tricks。不同优化算法的核心差异:下降方向

  从第一个框架中,我们可以看到不同优化算法的核心区别是第三步的下降方向:

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

  由于下降方向的不同,不同的算法可能会达到完全不同的局部优势。An empirical analysis of the optimization of deep network loss Surfaces在这篇论文中做了一个有趣的实验。他们将目标函数值和相应参数形成的超平面映射到三维空间,直观地看到每个算法如何在超平面上找到最低点。

【深度学习】Adam那么棒,为什么还对SGD念念不忘?一文看懂深度学习优化算法..._深度学习_02

  上图是论文的实验结果。水平和垂直坐标表示降维后的特征空间,区域颜色表示目标函数值的变化。红色是高原,蓝色是萧条。他们所做的是配对儿实验,使两种算法从同一初始化位置开始,然后比较优化结果。可以看出,几乎任何两种算法都达到了不同的洼地,它们之间往往有一个很高的高原。这说明不同的算法在高原上选择了不同的下降方向。Adam+SGD 组合策略

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

  不同优化算法的优缺点仍然是一个有争议的话题。根据我在paper和各种社区看到的反馈,主流观点认为Adam等自适应学习率算法在稀疏数据方面具有优势,收敛速度快;但是SGD的精确参数(+Momentum)往往能取得更好的最终结果。

  然后我们会想,我们能不能把两者结合起来,先用Adam快速下降,再用SGD调整,一举两得?思路简单,但有两个技术问题: 切换优化算法什么时候?-如果切换太晚,Adam可能已经跑到了自己的盆地,SGD再好也跑不出来了。 切换算法后使用什么样的学习率?-Adam使用自适应学习率,这取决于二级动量的积累。SGD训练后使用什么样的学习率?

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

  首先看第二个问题,切换后用什么样的学习率。Adam的下降方向是

  SGD的下降方向是

  .

  它必须分解为两个方向的总和及其正交方向,因此方向上的投影意味着SGD在Adam算法决定的下降方向上的距离,而正交方向上的投影是 SGD 向前推进你选择的修正方向的距离。

【深度学习】Adam那么棒,为什么还对SGD念念不忘?一文看懂深度学习优化算法..._机器学习_03

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

  如果SGD想走Adam未完成的路,首先要接过Adam的旗帜——沿着方向走一步,然后沿着正交方向走相应的一步。

  这样,我们就知道如何确定SGD的步长(学习率)——SGD在Adam下降方向上的正交投影,应该等于Adam的下降方向(包括步长)。也就是说:

  通过解决这个方程,我们可以获得SGD的学习率:

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

  Adam参数直接在这里重用。

  然后看第一个问题,算法何时切换。

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

  . 每次迭代玩都要计算SGD接班人的相应学习率,如果发现基本稳定,那么SGD认为学习率接班前进。trickss常用于优化算法

  最后,在优化算法的选择和使用中分享一些tricks。 首先,主要算法的优缺点尚无定论。如果你刚开始,优先考虑SGD。+Nesterov Momentum或Adamm.(Standford 231n :The two recommended updates to use are either SGD+Nesterov Momentum or Adam) 选择你熟悉的算法——这样你就可以更熟练地利用你的经验进行参考。 充分了解您的数据——如果模型非常稀疏,则优先考虑自适应学习率的算法。 根据您的需要选择——在模型设计实验过程中,为了快速验证新模型的效果,可以使用Adam进行快速实验优化;在模型启动或结果发布之前,可以使用精确的SGD来优化模型。 先用小数据集进行实验。一些论文研究指出,随机梯度下降算法的收敛速度与数据集的大小关系不大。(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])因此,可以使用具有代表性的小数据集进行实验,测试最佳优化算法,并通过参数搜索找到最佳训练参数。 考虑不同算法的组合。先用Adam快速下降,再换SGD充分调优。切换策略可参考本文介绍的方法。 数据集必须完全分散(shuffle)。这样,在使用自适应学习率算法时,可以避免一些特征集中,有时导致学习过度,有时学习不足,导致下降方向的偏差。 在培训过程中,不断监控培训数据和验证数据上的目标函数值和精度或AUC指标的变化。训练数据的监控是确保模型有正确的下降方向和足够高的学习率;验证数据的监控是为了避免过度拟合。 制定适当的学习率衰减策略。当测试集上的指标保持不变或下降时,可以使用定期衰减策略,如每次EPOCh衰减一次;或者使用精度或AUC等性能指标进行监控下降时,学习率会降低。

  这里只列出一些优化算法的提示。如有遗漏,欢迎在评论中补充。我会继续更新这篇文章。提前感谢!

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

  参考文献:

  [1] CS231n Convolutional Neural Networks for Visual Recognition

  [2] Stochastic Gradient Descent Tricks.

  [3] Efficient BackProp

上一篇 37个Dubbo 连环炮,能扛住几个?最后几个还是有点难度
下一篇 代码看不懂?ChatGPT 帮你解释,详细到爆!

文章素材均来源于网络,如有侵权,请联系管理员删除。