优化器的发展:从梯度下降➔大模型优化器【SGD➔AdaGrad➔RMSProp➔Adam(自适应)➔AdamW➔LAMB➔AdaFactor➔Shampoo➔Lion】
从梯度下降到大模型优化器的发展历程
机器学习模型的训练离不开优化算法。优化算法的作用是不断调整模型参数,让损失函数的值尽可能降低,相当于帮模型在“错误表面”上找到一个低谷。在本报告中,我们将以循序渐进的方式,介绍优化算法从最基础的梯度下降法(如批量梯度下降和随机梯度下降)发展到深度学习时代常用的优化器(如Momentum动量法、Nesterov加速梯度、AdaGrad、RMSProp、Adam等),再到当前用于大规模模型训练的先进优化器(如AdaFactor、Shampoo、Lion等)的演进历程。
每一种优化算法我们都会提供:
- 数学推导:包括算法公式及其由来,帮助理解优化器背后的原理;
- 直观类比或图示:用形象的比喻或图表帮助大家理解算法如何工作,即使高中的同学也能看懂;
- 优缺点总结:概括每种优化器的优势、不足之处;
- 应用场景和代表性案例:说明哪些问题适合采用该优化器,并举例其成功应用的典型案例。
目录
-
引言
-
梯度下降方法的基础
- 2.1 批量梯度下降(Batch Gradient Descent)
- 2.2 随机梯度下降(Stochastic Gradient Descent, SGD)
- 2.3 小批量梯度下降(Mini-batch Gradient Descent)
- 2.4 梯度下降的局限与挑战
-
加速收敛的优化方法
- 3.1 动量法(Momentum)
- 3.2 Nesterov加速梯度(Nesterov Accelerated Gradient, NAG)
-
自适应学习率优化器
- 4.1 AdaGrad优化器
- 4.2 RMSProp优化器
- 4.3 Adam优化器 (及Adam改进版简介)
-
大模型训练的优化器
- 5.1 大模型训练面临的优化难题
- 5.2 LAMB优化器(大批量自适应矩估计)
- 5.3 AdaFactor优化器
- 5.4 Shampoo优化器
- 5.5 Lion优化器
-
总结与展望
接下来,我们将按照上述顺序逐步展开每一部分的内容。
1. 引言
在机器学习中,我们经常需要通过优化算法来最小化损失函数,从而找到模型的最优参数。损失函数可以被想象成一个关于模型参数的地形表面,山峰对应高损失,山谷对应低损失。优化算法的目标就是引导我们从山坡上一路“下山”,尽量到达谷底(全局最小值或某个局部最小值)。
梯度下降法(Gradient Descent)是最基本也最流行的优化方法之一。它的核心思想是:在当前位置计算损失函数对参数的梯度,梯度指向损失上升最快的方向,而负梯度则指向下降最快的方向。于是,我们沿着负梯度方向迈出一小步,这样损失就会降低一点点。不断重复这个过程,我们就有望逐步走向损失更低的区域,最终逼近谷底。
梯度下降法有不同的变体,主要区别在于每次计算梯度时使用多少数据:
- 批量梯度下降(Batch GD):每次利用全部训练数据计算精确的梯度再更新参数。这样每一步走得很稳健,但计算代价高昂,数据量很大时每一步都很慢。
- 随机梯度下降(SGD):每次只用一个样本计算梯度,立即更新参数。这样单步计算代价很小,更新频繁,但梯度因为仅基于一个样本会有较大随机波动。这使得损失函数的下降轨迹会在谷底附近来回震荡,如下图所示。不过,随机波动也有好处:它可能跳出某些局部低谷,寻找更优的谷底。
- 小批量梯度下降(Mini-batch GD):介于两者之间,每次用一小批样本(如32、64或256个)计算梯度。这在实践中很常用,它在计算效率和梯度估计的稳定性之间取得平衡:相比SGD噪声小一些、更稳定,但又比批量法计算快且能在线更新模型参数。
梯度下降法简单有效,但它也面临一些挑战:
- 学习率难以选择:步子(学习率 η\etaη)太小,会导致收敛缓慢;步子太大,又可能越过谷底甚至发散。选择合适的学习率往往需要反复试验。
- 统一的学习率不灵活:传统梯度下降对所有参数采用相同的学习率。如果数据特征的出现频率相差很大,我们可能希望对稀疏特征(很少出现)调整得更大一些,而对常见特征调整得温和一些。普通梯度下降无法区别对待不同参数的重要性。
- 局部极值和鞍点问题:深度学习的损失表面往往是非凸的,充满了局部极小值和鞍点(鞍点指某些方向上看是最低点,但另一些方向上却不是)。尤其是鞍点附近,梯度在各个方向都接近0,导致优化停滞不前。SGD在鞍点的平台区域容易“困”住,难以及时逃离。
针对这些挑战,研究者提出了各种改进算法来加速梯度下降的收敛、自适应调整学习率,以及提高在复杂地形中找到更好解的能力。下面我们将从基础的梯度下降开始,逐步介绍这些改进算法。
2. 梯度下降方法的基础
本节我们先介绍梯度下降法的基本原理和三种常见变体:批量梯度下降、随机梯度下降和小批量梯度下降。在了解基本方法后,我们再讨论其局限性,这将引出后续的改进算法。
2.1 批量梯度下降(Batch Gradient Descent)
原理:批量梯度下降每次利用全部训练数据来计算损失函数对参数的梯度,然后一次性更新参数。对于模型参数向量θ\thetaθ,损失函数记为J(θ)J(\theta)J(θ),则批量梯度下降一步更新的数学表达为:
θ:=θ−η∇θJ(θ) \theta := \theta - \eta \nabla_{\theta} J(\theta) θ:=θ−η∇θJ(θ)
其中,∇θJ(θ)\nabla_{\theta} J(\theta)∇θJ(θ)表示在当前参数θ\thetaθ处,损失函数关于θ\thetaθ的梯度向量;η\etaη是学习率,即我们沿负梯度方向前进的步长。上述更新要等整个数据集上的梯度算完才能进行,因此每一步计算量大,速度较慢。
特点和性能:由于每次梯度计算都精确考虑了所有样本,批量梯度下降的方向完全朝向整体损失下降最快的方向,因此更新稳健且单调:在凸问题中,它保证朝着全局最小值方向迈进,在非凸问题中也会降低目标函数直到陷入某个局部谷底。批量法通常收敛平滑,不会引入额外噪声。然而,它的缺点也很明显:如果训练集很大,一次完整梯度计算非常耗时,占用大量内存,甚至在数据无法全部载入内存时无法直接使用。另外,批量法不适用于在线学习(online learning)场景,因为它不能逐个样本地动态更新,需要等待所有数据处理完再更新。
代码示例:批量梯度下降的伪代码如下(使用所有数据计算梯度并更新):
for epoch in 1..N_epochs:
grad = ComputeGradient(loss, data_all, params)
params = params - learning_rate * grad
其中每次循环计算整个数据集data_all的梯度,并根据学习率更新参数。
小结:批量梯度下降在数据规模适中且模型相对简单时是有效的,并能在凸优化中收敛到全局最优。但面对海量数据或需要在线不断学习的场景,它既慢又不切实际。
2.2 随机梯度下降(SGD)
原理:随机梯度下降(Stochastic Gradient Descent, SGD)则走向了另一个极端。它每次仅随机抽取一个训练样本(x(i),y(i))(x^{(i)}, y^{(i)})(x(i),y(i))来计算梯度并更新参数。数学上,其更新规则可表示为:
θ:=θ−η∇θJ(θ;x(i),y(i)) \theta := \theta - \eta \nabla_{\theta} J(\theta; x^{(i)}, y^{(i)}) θ:=θ−η∇θJ(θ;x(i),y(i))
也就是说,用样本(x(i),y(i))(x^{(i)}, y^{(i)})(x(i),y(i))产生的损失J(θ;x(i),y(i))J(\theta; x^{(i)}, y^{(i)})J(θ;x(i),y(i))的梯度近似整个数据集损失的梯度。由于样本是随机选择的,这个近似在期望意义上是正确的,但瞬时值上带有较大随机噪声。
特点:SGD的优点是计算效率高且能够在线学习:每看到一个新样本就能快速更新一次参数,使模型及时学习新知识。对大数据集来说,SGD每轮(epoch)要进行的总更新次数虽然等于样本数,但每个更新的计算量小得多,而且可以并行化或在数据流中持续运行。另外,SGD由于其随机性,有时能逃离某些不良的局部极小值——因为当损失表面存在多个谷底时,使用整个数据的确定性梯度可能把我们“推”进某个局部谷底并停留,而SGD的随机抖动有机会跳出这个谷底,找到更好的解。
然而,SGD的缺点也源自其随机性:损失函数值在下降过程中会出现大幅波动,不如批量法那样平滑。如下图所示,SGD在优化过程中使损失值上下震荡,因为每个样本给出的梯度方向都不同,有时甚至彼此矛盾。尽管如果我们逐渐调低学习率,SGD在理论上仍能收敛到一个极小值(凸问题收敛到全局最优,非凸问题则近乎必然收敛到某个局部最优),但噪声使得其收敛路径曲折,需要更多的迭代次数来逼近最优。
图1:随机梯度下降(SGD)使目标函数值发生波动。曲线展示了用SGD优化时损失值随着迭代的变化情况,可以看到它并非单调下降而是在震荡中逐步趋向收敛。SGD的这种“抖动”一方面可能跳出局部最优,另一方面也使得收敛到精确最优变得困难,需要随着训练进行逐步调小学习率来缓解。
代码示例:SGD的伪代码如下,每次循环遍历数据集并逐样本更新参数:
for epoch in 1..N_epochs:
shuffle(data) # 打乱数据顺序
for each example in data:
grad = ComputeGradient(loss, example, params)
params = params - learning_rate * grad
可以看到,与批量法相比,我们在最内层循环对每个样本都进行了参数更新。
小结:SGD非常适合大数据和在线学习场景,因为它能快速迭代并持续吸收新数据的信息。在深度学习中,“SGD”一词通常也包含了小批量的情形(见下节)。SGD的不足在于收敛过程中噪声较大,因此常需要配合学习率衰减策略来逐步降低学习率,从而在后期取得稳定的收敛。
2.3 小批量梯度下降(Mini-batch Gradient Descent)
原理:小批量梯度下降尝试结合批量法和SGD的优点。每次更新时,它使用一个包含nnn个样本的**小批量(mini-batch)**来计算梯度。更新规则为:
θ:=θ−η∇θJ(θ;x(i:i+n),y(i:i+n)) \theta := \theta - \eta \nabla_{\theta} J(\theta; x^{(i:i+n)}, y^{(i:i+n)}) θ:=θ−η∇θJ(θ;x(i:i+n),y(i:i+n))
其中x(i i+n)x^{(i\:i+n)}x(ii+n)表示从iii到i+ni+ni+n的这一小批样本。也就是说,我们取一个适当大小的批(例如32或128个样本),计算在这些样本上的平均梯度,用它来更新参数,然后再取下一个批次。
特点:小批量方法带来了两方面好处:
- 降低方差,稳定收敛:相比单样本的随机梯度,小批量梯度的随机波动小得多,从而每一步的下降方向更准确,收敛过程更平滑。
- 利用向量化提升计算效率:现代深度学习框架对批量运算做了高度优化。例如,用矩阵乘法可以一次性计算一批样本的梯度,充分利用CPU/GPU的并行能力。这样,每个样本的平均计算成本降低,总体速度加快。
实践中,小批量尺寸通常在几十到几百之间(例如32、64、128等),具体取决于任务和硬件(批量过大可能导致内存不足,过小则不能充分利用计算资源)。大多数深度学习的训练都是采用小批量梯度下降的,而社区中说“用SGD训练”时,一般默认也是指用小批量的SGD。
代码示例:小批量GD的伪代码类似,只是内层按批处理而不是单样本:
for epoch in 1..N_epochs:
shuffle(data)
for batch in make_batches(data, batch_size):
grad = ComputeGradient(loss, batch, params)
params = params - learning_rate * grad
小结:小批量梯度下降几乎是深度学习优化的标准方案。它兼顾稳定性和效率:既不像全批量那样慢,也没有纯SGD那样剧烈的抖动。通过合理选择批大小,我们通常能得到比SGD更快且更稳定的收敛。
2.4 梯度下降的局限与挑战
尽管梯度下降(包括小批量SGD)是深度学习训练的基石,但如前所述,它也存在一些固有的挑战,需要我们在实践中加以应对。概括来说有:
-
学习率问题:选定一个合适的学习率往往需要反复实验调整。如果学习率太小,训练会变得非常缓慢;如果太大,损失可能不会降低,甚至出现NAN等数值发散。这就需要预先设计学习率调度(schedule),比如每隔若干epoch降低一次,或者监控验证集损失自动衰减。然而这些调度策略通常是基于经验预设的,不能根据数据特征自适应地调整。
-
统一学习率的低效:对于参数尺度各异或特征频率悬殊的情况,单一学习率并不理想。例如,在处理稀疏特征(如有些单词很少出现)的问题时,我们希望与这些特征相关的参数能获得较大的更新步幅(因为看到相关梯度的机会少),而对于高频特征则步子小一些更稳健。普通的GD无法区别对待这些情况。
-
深层网络的损失地形:深度神经网络的损失函数往往是一个高维、非凸且崎岖的表面,充满了局部极小值和平坦的高原区域(如鞍点)。研究发现,相比局部极小值,鞍点可能是更大的麻烦——在鞍点附近梯度几乎为零,导致训练停滞,而鞍点周围通常有一大片平坦区域,使SGD很难逃离。另外,还有**峡谷(ravine)**结构:在某些方向损失曲面陡峭,而另一些方向相对平缓,形成窄谷地形。这会导致SGD在陡峭方向上来回震荡(左右横跳),却在平缓方向上移动缓慢。下图形象展示了这种情况——SGD在峭壁间振荡,进展迟缓。
图2:带有“峡谷”形状损失曲面的优化轨迹对比。左图(图2-1)显示SGD在等高线较密集的窄谷中会剧烈震荡,难以迅速沿谷底前进;右图(图2-2)显示加入动量后的SGD轨迹更平滑,沿主要方向前进速度加快。动量法通过累积历史更新,减小了梯度在陡峭方向上的来回摆动,从而在此情景下更快逼近谷底。
(注:图2-1和图2-2对应无动量和有动量情况下优化路径在损失等高线图上的对比。这部分将在下节详细解释。)
为了解决上述问题,研究者们发展了多种改进的优化算法。接下来几节中,我们将首先介绍动量法及其改进,它们主要应对梯度下降在峡谷、鞍点处收敛慢的问题;然后介绍自适应学习率算法,它们针对学习率调节和不同参数不同步长的问题;最后讨论面向大模型训练的新型优化器,以应对内存瓶颈和大批量训练等新挑战。
3. 加速收敛的优化方法
本节介绍在梯度下降基础上引入历史梯度信息以加速收敛的方法,主要讨论动量法(Momentum)及其改进Nesterov加速梯度。这些方法的核心思想是:不仅考虑当前梯度,还综合考虑之前积累的更新方向,就像给梯度下降的小球加上“惯性”和“预见性”,以便更快更稳地朝正确方向前进。
3.1 动量法(Momentum)
回顾前面的比喻,梯度下降如同让一颗小球在损失表面上滚动下山。但标准的梯度下降每一步只参考当前所在位置的坡度,缺乏“惯性”,小球不会加速。如果损失表面出现狭长的山谷(ravine),在陡峭方向上梯度来回变号,普通的GD会在这个方向上不断震荡而难以前进。**动量法(Momentum)**通过引入物理中的“动量”概念来解决这一问题。
算法原理:动量法会在参数更新中加入上一时刻更新的一定比例,形成累积效果。用公式表示,动量法引入一个辅助变量vtv_tvt表示“速度”,更新规则为:
{vt=γ vt−1+η ∇θJ(θt−1)θt=θt−1−vt \begin{cases} v_t = \gamma \, v_{t-1} + \eta \, \nabla_{\theta} J(\theta_{t-1}) \\ \theta_t = \theta_{t-1} - v_t \end{cases} {vt=γvt−1+η∇θJ(θt−1)θt=θt−1−vt
其中γ\gammaγ称为动量系数,取值在0到1之间,常用例如γ=0.9\gamma=0.9γ=0.9;η\etaη是学习率。可以看出,第一行更新vtv_tvt时,γvt−1\gamma v_{t-1}γvt−1相当于上一时刻速度的保留(类似惯性),加上当前的梯度推动η∇J(θt−1)\eta \nabla J(\theta_{t-1})η∇J(θt−1)。第二行则用当前累积的速度vtv_tvt来更新参数。如果比较,这一更新等价于:
θt=θt−1−η∇J(θt−1)−γvt−1 \theta_t = \theta_{t-1} - \eta \nabla J(\theta_{t-1}) - \gamma v_{t-1} θt=θt−1−η∇J(θt−1)−γvt−1
也就是在普通梯度下降步伐上再减去γvt−1\gamma v_{t-1}γvt−1(注意vt−1v_{t-1}vt−1本身是上一步的移动量),相当于给当前梯度方向额外加上一点之前移动的“冲量”。
类比解释:用小球下山的比喻来看动量法:想象在斜坡上滚动的小球有质量,遇到下坡会不断加速,速度增大,就算碰到一小段上坡(浅浅的局部升高),如果小球速度足够大也能冲过去,不会被轻易卡住。数学上,当梯度方向在若干步内保持相对一致时(比如一直往下坡),动量的累积项γvt−1\gamma v_{t-1}γvt−1会使小球越滚越快,在这些方向上步子越来越大;反之,如果梯度方向频繁变换(比如在陡峭方向来回震荡),则之前的速度项在矛盾方向上部分抵消当前梯度,使更新幅度变小,从而抑制振荡。

图3:动量法示意。图中蓝球表示参数在损失表面移动的位置。没有动量时(左图),小球每次仅依赖当前坡度前进,容易在狭窄的谷地来回摆动(红色折线);引入动量后(右图),小球像具有惯性一样朝谷底加速滚动,路径更平滑(绿色路径),并减小了在谷地壁面上的左右摆动。
优点:动量法主要有两个优点:
- 加速收敛:在梯度方向稳定的情况下,动量累积可以让步伐越来越大,显著加快沿着谷底方向的移动速度。这对于长“谷”形状的损失面(各方向曲率差异大)尤为有效。实践中,动量常常能减少迭代次数,加速收敛。
- 减缓振荡:由于包含上一时刻速度,梯度在不同方向来回变化时部分会互相抵消,使得沿快速变化方向的更新幅度减小。这在陡峭曲面(如狭窄峡谷)中可以平滑路径,减少震荡。动量就像在梯度下降中加入**“阻尼”**,让小球不会过度来回弹跳。
缺点:动量法也存在一些需要注意的问题:
- 超参数需要调节:动量项γ\gammaγ一般需要调为接近1但小于1(如0.9),若设得过小,惯性不足,加速效果不明显;过大则可能导致过冲(overshoot),在某些曲面中冲过最低点后反复横跳。
- 仍需学习率配合:动量法并未从根本上解决学习率敏感问题,步长η\etaη仍需合理设置。如果η\etaη过大,加上动量后可能比普通SGD震荡更剧烈或者发散;如果η\etaη过小,虽然动量能稍微积累速度,但收敛仍然可能慢。
应用场景:动量法在深度学习中十分常用,尤其在计算机视觉任务中训练卷积神经网络时,**“SGD+Momentum”**长期以来是标准配置。例如,著名的AlexNet网络在训练ImageNet图像分类时就使用了SGD配合0.9的动量系数。动量法在这些高维非凸问题上显著提高了收敛速度和稳定性。甚至在一些凸优化问题(如简单的机器学习模型)中,引入动量也能减少迭代次数。
代表性案例:有研究指出,在一些复杂任务例如训练循环神经网络(RNN)时,加动量的SGD显著提升了性能。Ilya Sutskever在其博士论文中深入分析了动量和Nesterov方法对RNN训练的改善。总体而言,动量法作为一个简单有效的改进,被广泛应用于各类神经网络的训练中。
3.2 Nesterov加速梯度(NAG)
算法动机:有了动量法,我们的小球具备了“惯性”,下山更快。然而,有没有可能更聪明一点,让小球具有“预见性”呢?动量法中的小球有时候像是“蒙眼狂奔”——它积累的速度让它滚得飞快,但如果前方突然上坡,可能一下子冲过头再回来。这就引出了Nesterov加速梯度(Nesterov Accelerated Gradient, NAG)方法,它可以被看作是对动量法的改进,让小球“先瞄一眼前方再决定要不要减速”。
NAG最初由Nesterov在凸优化中提出,后来被应用到深度学习中。它的核心思路是:先按照动量方向试探性地前进一步,再计算梯度,从而调整校正。这样,算法对即将到达的位置的形势有一个预判,可以避免像动量法那样“盲目冲刺”。
数学推导:在标准动量更新中,我们更新vt=γvt−1+η∇J(θt−1)v_t = \gamma v_{t-1} + \eta \nabla J(\theta_{t-1})vt=γvt−1+η∇J(θt−1),然后θt=θt−1−vt\theta_t = \theta_{t-1} - v_tθt=θt−1−vt。NAG则修改为:
-
预更新(试探):先计算一个临时点 θ′=θt−1−γvt−1\theta' = \theta_{t-1} - \gamma v_{t-1}θ′=θt−1−γvt−1。这实际上是利用上一次的速度γvt−1\gamma v_{t-1}γvt−1,先走一小步(相当于“预计自己要往哪去”)。
-
梯度计算:计算在这个临时点的梯度 ∇J(θ′)\nabla J(\theta')∇J(θ′)。
-
最终更新:用这个梯度来更新速度和位置:
vt=γvt−1+η∇J(θ′) v_t = \gamma v_{t-1} + \eta \nabla J(\theta') vt=γvt−1+η∇J(θ′)
θt=θt−1−vt \theta_t = \theta_{t-1} - v_t θt=θt−1−vt
用公式可直接写为:
{vt=γvt−1+η∇θJ(θt−1−γvt−1)θt=θt−1−vt \begin{cases} v_t = \gamma v_{t-1} + \eta \nabla_{\theta} J(\theta_{t-1} - \gamma v_{t-1}) \\ \theta_t = \theta_{t-1} - v_t \end{cases} {vt=γvt−1+η∇θJ(θt−1−γvt−1)θt=θt−1−vt
对比动量法,唯一的区别是在计算新的vtv_tvt时,梯度不是在θt−1\theta_{t-1}θt−1处计算,而是在**“提前迈出动量步”的点 θt−1−γvt−1\theta_{t-1} - \gamma v_{t-1}θt−1−γvt−1 计算。这样一来,当我们真正更新参数时,使用的是对未来位置**的梯度信息,相当于提前感知了前方地形。
几何解释:NAG可以理解为:先顺着当前动量方向看看,会到哪个位置;如果发现在那个位置梯度方向有所变化,我们就及时调整。因此NAG不会像纯动量那样等冲过头后再纠正,而是提前纠偏,减小了滞后性。如图4所示:

图4:Nesterov加速梯度(NAG)的示意向量分解。动量法中,先计算当前位置梯度(小蓝箭头),再累积形成更新(大蓝箭头)。而NAG则提前一步:先沿旧动量方向走到预估位置(棕色箭头),然后计算该点的梯度(红箭头),再将其作为校正加回,得到最终更新(绿箭头)。可以看到,NAG的绿色最终更新向量较动量法的蓝色更新有所修正,避免了过快冲向错误方向,从而提高了响应速度和收敛稳定性。
图4中,各颜色箭头含义如下:棕色箭头表示依据过去动量预移动;红色箭头是预移动后的位置的梯度;绿色箭头则是实际应用的NAG更新(合成了棕色和红色校正)。相比之下,动量法直接使用蓝色箭头(以当前梯度为基的小球加速跳跃)。NAG通过红箭头的存在,让小球有所“预判”,因而绿色箭头的方向更加朝向最终谷底。
优点:Nesterov加速梯度相对于标准动量法的优点主要在于更快的响应和更少的超调:
- 在梯度方向改变时(比如即将上坡),NAG由于提早看到了梯度,会提前减速或转向,从而不至于像动量那样冲过头再折返。这通常使训练更平稳,损失下降更快。
- NAG在一些情况下收敛更快。理论上,在凸函数优化中,Nesterov方法达到了更优的收敛上界(梯度法O(1/t)O(1/t)O(1/t)对比NAG的O(1/t2)O(1/t^2)O(1/t2)加速收敛),在深度学习的非凸场景中也经常观察到NAG优于普通动量的效果。
缺点:NAG缺点是:
- 实现稍复杂:需要两次梯度计算(先计算预估点梯度,再更新),不过在现代框架中这点开销可以忽略不计或者通过等价变形合并。
- 调参:NAG和动量法一样需要调节γ\gammaγ和学习率η\etaη。总体而言,NAG通常可以使用与动量法相同的超参数,但在某些任务中需要略微调整。
- 收益视任务而定:虽然理论上NAG有优势,但并不是在所有任务上都显著胜过普通动量。有些情况下两者效果差不多。
应用场景:NAG已被广泛应用于深度学习优化,很多深度学习框架(如TensorFlow的MomentumOptimizer、PyTorch的SGD优化器选项)直接提供了Nesterov选项。NAG对那些容易发生动量过冲的情况特别有用,比如训练某些复杂网络(RNN/LSTM等)时帮助稳定收敛。许多竞赛和论文也报告使用Nesterov能得到略好的收敛效果。
代表案例:NAG在2013年被Sutskever等人引入神经网络训练,引发关注。他们在训练循环神经网络(RNN)时发现,NAG相较普通动量取得了明显更好的收敛和性能。此后NAG成为许多优化器默认的选择之一。例如,在一些计算机视觉模型和GAN的训练中,研究者偏好Nesterov动量来获得更稳定快速的训练。
现在,我们已经了解了利用历史梯度信息加速收敛的Momentum和NAG方法。接下来,我们将转向另一类重要的优化思想:自适应学习率。这些算法能够针对每个参数的情况调节学习率大小,从而减少人工调参的工作,并更有效地处理不同特征尺度的问题。
4. 自适应学习率优化器
正如前文提到的,选择和调度学习率是一件令人生畏却重要的任务。如果有一种算法,能自动根据梯度信息调整每个参数的学习率,那训练将更加省心。自适应学习率优化器(Adaptive Learning Rate Methods)正是为此而生。它们根据以往梯度的大小和分布,对每一个参数赋予不同的有效步长:对变化剧烈或不常见的参数用小步或大步,从而提升训练效率和效果。下面我们介绍几种具有里程碑意义的自适应优化算法:AdaGrad、RMSProp和Adam(以及简要提及一些变体)。
4.1 AdaGrad优化器
深度学习中第一个被广泛采用的自适应学习率方法是AdaGrad(Adaptive Gradient)。AdaGrad由Duchi等人在2011年提出。它的出发点很直接:让每个参数都有自己独立的学习率,并由该参数过去的梯度大小来决定这个学习率的调整。
算法推导:在标准的梯度下降中,所有参数共享同一个学习率η\etaη。AdaGrad则为每个参数θi\theta_iθi引入一个不同的学习率调整因子。具体做法是对每个参数累加历史梯度的平方,然后用它的平方根来缩放学习率。其单参数更新公式为:
θt+1,i=θt,i−ηGt,ii+ϵ gt,i \theta_{t+1,i} = \theta_{t,i} - \frac{\eta}{\sqrt{G_{t,ii} + \epsilon}} \, g_{t,i} θt+1,i=θt,i−Gt,ii+ϵηgt,i
这里,gt,i=∇θiJ(θt)g_{t,i} = \nabla_{\theta_i} J(\theta_t)gt,i=∇θiJ(θt)是当前步梯度中第iii个参数的偏导数;Gt,iiG_{t,ii}Gt,ii表示一个累积和:“到第ttt步时,第iii个参数过去所有梯度平方之和”。换言之:
Gt,ii=∑k=1tgk,i2 G_{t,ii} = \sum_{k=1}^{t} g_{k,i}^2 Gt,ii=k=1∑tgk,i2
ϵ\epsilonϵ是一个小的平滑项,防止分母为0(通常取10−810^{-8}10−8左右)。
上式可以向量化写为:
θt+1=θt−ηGt+ϵ⊙gt \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{G_t + \epsilon}} \odot g_t θt+1=θt−Gt+ϵη⊙gt
其中GtG_tGt是一个对角矩阵,对角线Gt,iiG_{t,ii}Gt,ii如上,⊙\odot⊙表示逐元素(Hadamard)乘积。
效果解释:由于Gt,iiG_{t,ii}Gt,ii累积了第iii参数至今的梯度平方和,可以理解为“这个参数经历的变化幅度”的量度。如果某个参数在训练过程中梯度一直很大,那么Gt,iiG_{t,ii}Gt,ii会快速增大,导致1Gt,ii\frac{1}{\sqrt{G_{t,ii}}}Gt,ii1变得很小,也就是自动降低了该参数的学习率。反之,如果某参数的梯度一直很小,Gt,iiG_{t,ii}Gt,ii增长缓慢,1Gt,ii\frac{1}{\sqrt{G_{t,ii}}}Gt,ii1相对较大,该参数就会保持较大的更新步幅。这样,实现了频繁更新的参数学得保守,罕见更新的参数学得激进。
一个经典应用情景是稀疏特征:比如在自然语言处理中,某些生僻单词对应的权重梯度很少非零,AdaGrad会让这些权重拥有相对较大的有效学习率,从而在有限的几次更新中学到有用的值。相反,对于那些非常常见的特征,AdaGrad会逐渐调低它们的学习率,避免了过大的波动。
优点:
- 无需手调学习率:AdaGrad的一个重要优点是在很多任务中可以使用固定的全局学习率(如0.01),而让算法自身去调整各参数的步长。在它提出之后,很多场合下研究者直接用了推荐默认值且取得不错效果,减少了调参的负担。
- 对稀疏数据友好:正如上面所说,AdaGrad在处理高维稀疏数据(例如文本或推荐系统中的特征向量非常稀疏)时表现出色。Google的大规模训练实验发现AdaGrad极大地提高了深度网络训练的鲁棒性,例如成功训练模型去识别YouTube视频中的猫(这是深度学习早期著名的“谷歌猫”实验);另外,Pennington等人在训练词向量GloVe时也用AdaGrad,因为不常出现的单词需要更大步长来学习。
缺点:
- 学习率单调下降:AdaGrad最主要的问题在于Gt,iiG_{t,ii}Gt,ii是不断累加永不减少的。随着训练进行,每个Gt,iiG_{t,ii}Gt,ii只会变大不会变小,这意味着有效学习率ηGt,ii\frac{\eta}{\sqrt{G_{t,ii}}}Gt,iiη会单调衰减。到后期,步长可能变得非常小,小到参数几乎不再更新。换句话说,AdaGrad有“学习率耗尽”的问题:一开始学得飞快,但长时间跑下去可能提前停止学习。这对凸优化问题不是大问题(反正找到最优就停下来),但对深度网络这种需要更长训练的非凸问题就不够灵活。
- 不适用于非平稳目标:如果损失表面特性在训练过程中发生变化(如训练不同阶段梯度幅度分布变化很大),AdaGrad无法“遗忘”早期的梯度历史。它欠缺一种机制来区分“陈旧”的信息,从而在后期及时调整策略。
基于上述弱点,后续出现了多种AdaGrad的改进版,下面我们将介绍其中两个:RMSProp和Adadelta,以及进一步结合动量思想的Adam优化器。
4.2 RMSProp优化器
RMSProp是由Hinton等人在深度学习实践中提出的一个非正式算法,最早在2012年Hinton的神经网络课程lecture中出现。RMSProp的目标是解决AdaGrad学习率递减过快的问题。它的核心思想是:不要一直积累所有历史梯度,而是只保留一个近期的衰减平均。
可以将RMSProp看作是对AdaGrad累积方式的修改——AdaGrad是无衰减地累积平方梯度,而RMSProp引入了**指数衰减移动平均(EMA)**机制。具体来说,RMSProp维护一个变量E[g2]tE[g^2]_tE[g2]t,每一步按如下规则更新:
E[g2]t=ρ E[g2]t−1+(1−ρ) gt2 E[g^2]_t = \rho \, E[g^2]_{t-1} + (1-\rho) \, g_t^2 E[g2]t=ρE[g2]t−1+(1−ρ)gt2
这里ρ\rhoρ是衰减因子,类似前面的γ\gammaγ,通常取0.9左右(即保留90%的旧信息,加10%的新梯度平方)。这个公式实际上就是对梯度平方做指数加权平均,让久远之前的梯度贡献指数级衰减,近期梯度占主要影响。
然后,RMSProp使用这个E[g2]tE[g^2]_tE[g2]t来调整学习率:
θt+1=θt−ηE[g2]t+ϵ gt \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{E[g^2]_t + \epsilon}} \, g_t θt+1=θt−E[g2]t+ϵηgt
可以看出,和AdaGrad唯一不同的是用E[g2]tE[g^2]_tE[g2]t取代了累积和GtG_tGt。由于E[g2]tE[g^2]_tE[g2]t是有“记忆衰减”的,不会无限制增长,因此有效学习率η/E[g2]t\eta/\sqrt{E[g^2]_t}η/E[g2]t不会一味缩小到零,而是在一个稳定值附近调整。这解决了AdaGrad学习率过早过度缩小的问题。
与Adadelta的关系:值得一提的是,RMSProp其实等价于AdaDelta优化器的一个部分。AdaDelta是Zeiler在2012年提出的改进AdaGrad的方法,它不仅对梯度平方采用了滑动平均(与RMSProp相同),还引入了对参数更新量本身的滑动平均用于无学习率更新。而RMSProp可以看作AdaDelta只做了一半:即只管梯度的均方根(RMS)调整,仍保留一个全局学习率η\etaη。实际上,Hinton在讲义中提出RMSProp时就提到了AdaDelta,并指出两者在梯度均方处理上本质相同。
RMSProp优缺点:
- 优点:相比AdaGrad,RMSProp通过遗忘旧梯度,能够更长时间地保持较大的有效学习率,从而适用于长程训练的非凸问题。它计算高效,公式简单,而且没有引入额外可调参数(衰减率通常推荐0.9或0.99)。实践证明RMSProp对许多深度学习问题(尤其是RNN训练)非常有效,被广泛采用。
- 缺点:需要设置衰减系数ρ\rhoρ,尽管0.9/0.99通常都能用,但不同问题可能有略差别。另外,像AdaGrad一样,RMSProp也只有一阶动量(梯度的平方平均),没有利用梯度的累积方向信息(那是Momentum类方法的强项)。不过在下一个要介绍的Adam里,将会结合两方面的优点。
应用场景:RMSProp常被用来训练循环神经网络(RNN、LSTM)等,因为这些网络梯度变化剧烈且训练较长,AdaGrad不太适合而RMSProp表现良好。另外,在强化学习中的某些策略优化也经常选RMSProp作为默认优化器。
代表案例:Hinton等人在多层神经网络、受限玻尔兹曼机的训练中验证了RMSProp的效果;许多深度学习库(如TensorFlow的默认RNN优化器)都内置了RMSProp。虽然近年来Adam更流行,但RMSProp依然在一些特定场景被采用,例如Google的免费课程和教材often将RMSProp作为SGD的升级方案教授。
4.3 Adam优化器
Adam(Adaptive Moment Estimation)可以说是当今深度学习领域最普及的优化算法之一。2014年由Kingma和Ba提出的Adam方法,将Momentum和RMSProp两种思想巧妙结合,既利用了一阶动量(累计的梯度均值),又利用了二阶动量(梯度平方的均值),实现了自适应学习率调整。可以理解为:Adam在每次参数更新时,同时参考了“最近梯度的方向趋势”和“最近梯度的方差大小”,从而既有加速又有自适应步长。
算法公式:Adam的更新规则由以下几步组成:
{gt=∇θL(θt−1)(当前梯度)mt=β1mt−1+(1−β1)gt(一阶矩估计)vt=β2vt−1+(1−β2)gt2(二阶矩估计)m^t=mt1−β1t,v^t=vt1−β2t(偏差校正)θt=θt−1−αtm^tv^t+ϵ(参数更新) \begin{cases} g_t = \nabla_{\theta} L(\theta_{t-1}) & (\text{当前梯度})\\ m_t = \beta_1 m_{t-1} + (1-\beta_1) g_t & (\text{一阶矩估计})\\ v_t = \beta_2 v_{t-1} + (1-\beta_2) g_t^2 & (\text{二阶矩估计})\\ \hat{m}_t = \frac{m_t}{1-\beta_1^t},\quad \hat{v}_t = \frac{v_t}{1-\beta_2^t} & (\text{偏差校正})\\ \theta_t = \theta_{t-1} - \alpha_t \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} & (\text{参数更新}) \end{cases} ⎩⎨⎧gt=∇θL(θt−1)mt=β1mt−1+(1−β1)gtvt=β2vt−1+(1−β2)gt2m^t=1−β1tmt,v^t=1−β2tvtθt=θt−1−αtv^t+ϵm^t(当前梯度)(一阶矩估计)(二阶矩估计)(偏差校正)(参数更新)
让我们逐行解释:
- 第一行是当前梯度gtg_tgt;
- 第二行更新mtm_tmt,这是梯度的一阶移动平均(类似动量),β1\beta_1β1一般取0.9左右;
- 第三行更新vtv_tvt,是梯度平方的移动平均(类似RMSProp的E[g2]E[g^2]E[g2]),β2\beta_2β2一般取0.999;
- 第四行m^t,v^t\hat{m}_t,\hat{v}_tm^t,v^t是对mt,vtm_t, v_tmt,vt做偏差校正。因为初始时m0,v0m_0, v_0m0,v0都为0,直接用上述递推算出的mt,vtm_t, v_tmt,vt会偏向0,需要除以(1−β1t)(1-\beta_1^t)(1−β1t)等因子校正这种初始化偏差。
- 最后一行是用校正后的一阶矩除以二阶矩的平方根来更新参数,并乘以学习率αt\alpha_tαt(这里写αt\alpha_tαt表示Adam中可以对学习率也每步变化,但通常α\alphaα是固定或用调度)。注意ϵ\epsilonϵ小常数确保数值稳定。
可以看到,如果去掉偏差校正和一阶动量项,只有vtv_tvt那一项,那么θ\thetaθ的更新就变成了类似RMSProp;如果只有mtm_tmt项没有vtv_tvt项,又接近带偏差校正的动量。Adam融合了两者,并通过m^tv^t\frac{\hat{m}_t}{\sqrt{\hat{v}_t}}v^tm^t的形式,使得每个参数都有自己适应的步长(由v^t\hat{v}_tv^t决定),同时保留了累积梯度方向的信息(m^t\hat{m}_tm^t)。
Adam名称中的“Adaptive Moment Estimation”正反映了它对梯度的 动量(momentum,一阶矩)和RMS(二阶矩) 进行估计并自适应调整更新幅度的特点。
优点:
- 基本无需调参即可工作:Adam提供了一套默认超参数(β1=0.9,β2=0.999,ϵ=10−8\beta_1=0.9, \beta_2=0.999, \epsilon=10^{-8}β1=0.9,β2=0.999,ϵ=10−8),在各种任务上都表现良好。大多数情况下,使用默认参数的Adam就能取得不错的结果。相比之下,SGD需要费心调学习率和动量。
- 快速收敛:Adam在许多任务上都有快速下降损失的效果,尤其是在训练开始阶段非常明显。它结合了动量加速和自适应学习率,对不同规模的梯度都能高效更新。
- 鲁棒性:因为有自适应机制,Adam对梯度尺度的变化、自变量的缩放不那么敏感。这使它成为一个通用默认选择——很多开源模型直接用Adam就能成功训练,而不需要太精细的调优。
- 处理稀疏梯度:Adam继承了AdaGrad类方法处理稀疏梯度的能力,对于NLP等领域的高维稀疏特征依然有效,同时动量成分带来了稳定性。
缺点:
- 过拟合倾向:有实证表明,在一些计算机视觉任务上,Adam虽然前期收敛快,但最终模型的泛化性能有时不如SGD。这是因为Adam对噪声变化适应快,可能走入“浅的谷底”就停止了,而SGD的震荡反而可能跨过浅谷找到更佳的谷底。因此,有些论文会在训练后期切换回SGD微调模型以取得更好泛化。
- 对超参数仍然有一定敏感性:虽然Adam的默认参数通常有效,但在一些任务上调整β1,β2\beta_1, \beta_2β1,β2或学习率仍可能提升效果。例如,Transformer等模型常用β2=0.98\beta_2=0.98β2=0.98等设置。错误地设置学习率仍然会导致Adam发散或震荡(尽管一般它比SGD更宽容)。
- 实现稍复杂:与简单SGD相比,Adam需要维护和更新额外的mtm_tmt和vtv_tvt两个同维度的状态变量,占用两倍内存。这对超大模型训练是个负担。不过这问题有后继的AdaFactor来解决(见后续)。
应用场景:Adam几乎可以用于任何深度学习任务。特别是在自然语言处理、强化学习等梯度稀疏或噪声较大的环境,Adam是默认选择。在计算机视觉中,很多时候后期微调会改用SGD提高精度,但在预训练或初始训练阶段Adam仍然常用。总之,Adam作为“开箱即用”的优化器,已经成为深度学习工作中的常备工具。
代表案例:自提出以来,Adam几乎在所有主流深度学习模型训练中出现过。比如2018年的BERT和GPT等大模型预训练,都使用了Adam优化(具体是Adam的变体AdamW,剥离权重衰减项的版本)。在生成模型如GAN的训练中,也常常优先尝试Adam。可以说Adam在深度学习兴起的2015-2020年间扮演了关键角色。直到今天,大部分Transformer架构模型的默认优化器依然是Adam或AdamW。Adam的普及也催生了若干改进版本,例如添加正则项的AdamW、解决Adam局部最优问题的AMSGrad、融合Nesterov动量的Nadam等,但总体框架都与Adam类似,在此不再展开。
在讨论完Adam之后,我们已经覆盖了深度学习中常用的一阶优化方法。从基础的SGD到Momentum、AdaGrad、RMSProp再到Adam,它们极大地推动了神经网络训练的效率和效果。然而,随着深度学习模型规模变得越来越庞大(参数上亿甚至千亿),以及训练方式在分布式、大批量上不断演进,传统优化器也遇到了新挑战。下一节中,我们将讨论近年来为大模型训练设计的优化算法,包括为降低内存占用的AdaFactor,利用二阶信息的Shampoo,以及由自动化算法发现的新优化器Lion等。
5. 大模型训练的优化器
近年来,深度学习模型参数规模呈爆炸式增长,从几百万参数的模型发展到百亿、千亿参数的“大模型”(如GPT-3等)。训练如此庞大的模型,对优化器提出了一些新的要求和挑战:
- 内存占用:Adam等优化器需要维护与模型参数等大小的状态(例如mmm和vvv两个矩向量,各一份模型大小)。当模型参数上百亿时,这些状态会占用极其巨大的内存(显存),甚至超过硬件承受范围。
- 训练速度:大模型通常需要分布式训练,加大了批量大小。为了充分利用多卡并行,经常使用成千上万的数据作为一个mini-batch。这会导致原有优化器(如Adam)在超大批量下表现不佳,需要新的优化策略来保持收敛速度和泛化性能。
- 数值稳定和泛化:大模型的损失表面可能更加复杂,传统优化器的鲁棒性需要提升。例如,大批量训练往往容易陷入“尖锐的谷底”导致泛化变差,需要优化器进行特殊处理来规避。
针对这些问题,研究者提出了若干新的优化器或优化器改进。在本节,我们介绍三类具有代表性的大模型优化方法:
- LAMB(Layer-wise Adaptive Moments optimizer for Batch training):专门为超大批量分布式训练设计,在BERT等模型上成功实现了数万batch的高效训练。
- AdaFactor:谷歌提出的降低Adam内存开销的优化器,通过分解二阶矩估计,大幅减少状态占用,使训练百亿参数模型成为可能。
- Shampoo:Google Brain提出的利用二阶近似(近似Hessian信息)来加速收敛的优化器,在一些大型模型上迭代更快。不过由于计算开销大,Shampoo也发展出了若干高效变种。
- Lion:2023年由谷歌通过自动化算法发现的新型优化器,特点是只保留动量、使用符号函数更新,每次更新大小统一,号称在一些大模型任务上超过Adam性能。
我们依次介绍这些方法的原理、优缺点和应用实例。
5.1 大模型训练面临的优化难题
(在介绍具体优化器前,先进一步解释以上挑战,并提到一些通用策略或改进思路。)
内存与通信瓶颈:假设一个模型有NNN个参数,Adam需要维护大小为NNN的mmm和vvv,合计3N3N3N的变量。而当N=1011N=10^{11}N=1011量级时,哪怕用16字节(双精度)存储,一个状态变量就达1.6TB,这是完全无法在GPU/TPU上存储的。这就需要优化器想办法减少状态大小。一种思路是舍弃或压缩部分状态:比如AdaFactor就是通过不明存一整个vvv矩阵,而是用其行列分解近似,从NNN级存储降到N\sqrt{N}N级存储。另一种思路是量化:用低精度(如8位、4位)存储状态,这方面最新有“4-bit Adam/4-bit Shampoo”等研究,但这里不展开。
大批量训练的收敛:当batch非常大时,梯度噪声小,训练可以使用较大步长,但也更容易过拟合或卡在平坦区域。一些传统优化器在超大batch下会失效,例如AdamW被发现无法在batch=16K以上继续有效提高BERT精度。为此,有优化器如LAMB、LARS(主要针对CNN)等,通过分层自适应调节学习率,确保每一层的更新相对于参数大小保持一致,从而在大批量下稳定训练。
泛化与稳定性:大模型容易过拟合,因此正则化和泛化能力是关注重点。优化器层面一个常用措施是权重衰减(weight decay)。Adam通常结合AdamW来直接对参数施加L2正则。另外,有研究提出,像Lion这种仅符号更新、更新幅度统一的策略,能使优化过程在损失景观上“滑行”而不是紧贴狭窄曲率轨迹,从而找到更平坦的最优点,理论上有利于泛化。
下面我们分别介绍几种具体的大模型优化算法。
5.2 LAMB优化器(Layer-wise Adaptive Moments for Batch Training)
背景:2019年,为了在谷歌云TPU上快速训练BERT模型,You等人提出了LAMB优化器。LAMB的主要贡献是在非常大的batch size下(可至数万)依然保持良好收敛速度和模型精度。传统的Adam在batch增大时往往需要缩小学习率以维持稳定,这使得并行效率降低。而LAMB则能够在超大batch下使用较大学习率且不损失模型精度,从而实现例如“BERT在76分钟训练完成”这样的成果。
关键思想:LAMB可以看作是AdamW的扩展,其核心在于分层自适应学习率。直观来说,LAMB在计算出Adam风格的梯度更新后,会对每一层的更新向量进行长度规范化和缩放。其更新步骤:
- 先像Adam一样计算梯度一阶动量mmm和二阶动量vvv,得到原始更新ΔθAdam\Delta\theta_{\text{Adam}}ΔθAdam。
- 对每一层的Δθ\Delta\thetaΔθ,计算其欧氏范数∣Δθ∣|\Delta\theta|∣Δθ∣,同时计算该层参数θ\thetaθ本身的范数∣θ∣|\theta|∣θ∣。
- 计算一个信赖系数(trust ratio):r=∣θ∣∣Δθ∣r = \frac{|\theta|}{|\Delta\theta|}r=∣Δθ∣∣θ∣(有时会限定在不超过某一阈值)。
- 将该层的实际更新设置为:ΔθLAMB=r⋅ΔθAdam\Delta\theta_{\text{LAMB}} = r \cdot \Delta\theta_{\text{Adam}}ΔθLAMB=r⋅ΔθAdam,然后再应用学习率等。
这样,每一层参数的更新方向跟Adam相同,但更新步长被调整:如果某层参数的相对变化过大(∣Δθ∣|\Delta\theta|∣Δθ∣远大于∣θ∣|\theta|∣θ∣),则r<1r<1r<1会缩小该层更新,避免过大的权重改动;反之如果∣Δθ∣|\Delta\theta|∣Δθ∣很小,相对变化量不足,则r>1r>1r>1会放大步长,充分利用大batch梯度提供的可靠信号。
这个策略确保了每层参数的更新比例大致相当,不会因为梯度总体缩放而导致某些层学得过慢或过快。大batch时梯度近似全局最优方向,但由于缺乏噪声正则,容易一步迈太远踩过头,LAMB的信赖系数正好抑制了这一点又不会完全停下。
优点:
- 支持超大批量训练:LAMB的提出正是为了解决大batch下Adam失效的问题。实验证明,在BERT预训练中,当batch增至32k以上时,普通AdamW难以达到目标精度,而LAMB可以。这使得可以利用更多硬件并行,以近线性速度提升完成训练的效率。
- 自动调整不同层步长:深度网络的不同层对学习率敏感度不同(如靠近输入层的梯度往往较小)。LAMB对层归一化使得各层都有合适的更新尺度,不需要人为对不同层设定学习率系数。
- 与AdamW兼容:LAMB仍继承了AdamW对一、二阶矩的估计和权重衰减,好处仍在,并不影响其对收敛和正则化的优势。
缺点:
- 额外的计算:范数和比值的计算在大模型分布式环境下会引入一些通信开销(需要全局归一化每层)。不过,相比总体训练开销,这部分可以接受。
- 不一定适用小批量:在正常或小batch情形下,LAMB的优势不明显,甚至可能稍逊于Adam,因为它的设计初衷就是在大批量场景。
- 实现复杂:需要对每层参数向量进行操作,相比逐元素的Adam要复杂。但现代框架已有支持。
应用场景:LAMB主要用在超大规模分布式训练中。如前述,BERT大型模型在TPU Pod上以batch=32768训练时使用LAMB成功在短时间收敛。在需要缩短大模型训练时间、充分利用硬件并行度的任务中(如GPT等预训练)也可以考虑LAMB。NVIDIA等公司在一些指南中也推荐在相应场景下尝试LAMB或类似的LARS/LAMB方案。
代表案例:You等人的论文《Large Batch Optimization for Deep Learning: Training BERT in 76 minutes》详细展示了使用LAMB以64 TPU同时训练BERT的成果:最终在SQuAD数据集上F1达到91.46,与小批量长时间训练结果相当,而用时仅100分钟不到。这证明了LAMB在保证泛化的前提下实现了大幅加速。此后,LAMB被用于各种需要大批量训练的情形,也有研究对比了LAMB与LARS等方法在ImageNet上训练ResNet的表现。总的来说,LAMB为大模型大批量训练提供了一种实用可行的优化策略。
5.3 AdaFactor优化器
随着Transformer等模型参数激增,AdaFactor在2018年由Shazeer等人提出。AdaFactor的名字意为“Adaptive learning rates with sublinear memory cost”,突出其亚线性内存占用特性。它的目标是以近似不增加额外内存的方式,实现类似Adam的自适应优化效果。
Adam的内存问题在于mmm和vvv两个状态矩阵都与参数相同大小。AdaFactor通过以下两步减小内存:
- 去掉动量项mmm:作者观察到,在CV等任务上,动量SGD效果虽好,但在NLP任务中自适应学习率更重要,而不用动量影响不大。因此AdaFactor干脆不维护一阶矩mmm,只使用类似vvv的二阶矩统计。这立刻把状态变量从2个降为1个,内存减半。
- 分解二阶矩vvv:这是AdaFactor的核心创新。对于一个权重矩阵Θ\ThetaΘ(尺寸m×nm \times nm×n),Adam会为其维护一个同尺寸的vvv矩阵。如果m,nm,nm,n都很大,这个矩阵本身就很庞大。AdaFactor假设,我们不需要每个元素都有独立的二阶估计,可以近似地将vvv矩阵拆解成行向量和列向量的乘积。具体做法如下:
AdaFactor将vvv的近似记为v^i,j≈ai⋅bj\hat{v}_{i,j} \approx a_i \cdot b_jv^i,j≈ai⋅bj,其中aia_iai是第iii行的因子,bjb_jbj是第jjj列的因子。他们取k=1k=1k=1的极端低秩分解,也就是用一对向量外积来近似整个矩阵。那么如何求这两个向量?论文中非常巧妙地选择了广义KL散度(也称III散度)作为度量,并推导出闭式解。结果就是:
ai=∑jcij,bj=∑icij∑i,jcij a_i = \sum_j c_{ij}, \qquad b_j = \frac{\sum_i c_{ij}}{\sum_{i,j} c_{ij}} ai=j∑cij,bj=∑i,jcij∑icij
其中C=[cij]C = [c_{ij}]C=[cij]是我们想逼近的矩阵(对应这里vvv矩阵)。换言之,aia_iai取vvv矩阵第iii行的和,bjb_jbj取vvv矩阵第jjj列的和再除以矩阵所有元素和。这个结果直观解释就是:aaa是行和向量,bbb是列和向量的归一化。通过这个技巧,我们只需存储aaa和bbb两个大小为mmm和nnn的向量,就能近似表示原本m×nm\times nm×n大小的vvv矩阵,大幅降低了内存占用。
有了这个低秩近似,AdaFactor的更新步骤如下(针对矩阵状参数的情况):
- 计算当前梯度gi,j;tg_{i,j;t}gi,j;t;
- 更新行梯度二阶矩:v(r)∗i;t=β^∗2,t,v(r)∗i;t−1+(1−β^∗2,t)∑j(gi,j;t2+ϵ1)v^{(r)}*{i;t} = \hat{\beta}*{2,t} , v^{(r)}*{i;t-1} + (1-\hat{\beta}*{2,t}) \sum_j (g_{i,j;t}^2 + \epsilon_1)v(r)∗i;t=β^∗2,t,v(r)∗i;t−1+(1−β^∗2,t)∑j(gi,j;t2+ϵ1)(这里β^2,t\hat{\beta}_{2,t}β^2,t是随时间变化的衰减因子,后面解释);
- 更新列梯度二阶矩:v(c)∗j;t=β^∗2,t,v(c)∗j;t−1+(1−β^∗2,t)∑i(gi,j;t2+ϵ1)v^{(c)}*{j;t} = \hat{\beta}*{2,t} , v^{(c)}*{j;t-1} + (1-\hat{\beta}*{2,t}) \sum_i (g_{i,j;t}^2 + \epsilon_1)v(c)∗j;t=β^∗2,t,v(c)∗j;t−1+(1−β^∗2,t)∑i(gi,j;t2+ϵ1);
- 由行列估计构造二阶矩近似:v^∗i,j;t=v(r)∗i;t,v(c)∗j;t∑jv(c)∗j;t\hat{v}*{i,j;t} = \frac{v^{(r)}*{i;t} , v^{(c)}*{j;t}}{\sum_j v^{(c)}*{j;t}}v^∗i,j;t=∑jv(c)∗j;tv(r)∗i;t,v(c)∗j;t;
- 计算标准化梯度:ut=gtv^tu_t = \frac{g_t}{\sqrt{\hat{v}_t}}ut=v^tgt;
- 自适应层级缩放(类似LAMB思想):u^∗t=utmax(1,;RMS(ut)/d)×max(ϵ2,;RMS(θ∗t−1))\hat{u}*t = \frac{u_t}{\max(1,;\mathrm{RMS}(u_t)/d)} \times \max(\epsilon_2,; \mathrm{RMS}(\theta*{t-1}))u^∗t=max(1,;RMS(ut)/d)ut×max(ϵ2,;RMS(θ∗t−1))。这里ddd是常数(默认1),RMS(x)\mathrm{RMS}(x)RMS(x)表示xxx向量各元素平方平均的平方根。这一步确保更新u^t\hat{u}_tu^t的范数与参数θ\thetaθ自身的范数相适应——如果梯度更新相对过大,就进行截断归一化,同时保证至少有一个ϵ2\epsilon_2ϵ2下限或者按参数模长定标。这与前述LAMB对每层更新归一化的思路类似。
- 最后参数更新:θt=θt−1−αtu^t\theta_t = \theta_{t-1} - \alpha_t \hat{u}_tθt=θt−1−αtu^t。
由于没有mmm,AdaFactor只存储两个vvv向量(行和列)以及少量标量,内存需求从O(mn)O(mn)O(mn)降到了O(m+n)O(m+n)O(m+n),对于大型矩阵参数(如词嵌入矩阵,mmm是词表大小,nnn是嵌入维度)来说,这是一种巨大的节省。
进一步改进:上式中β^∗2,t\hat{\beta}*{2,t}β^∗2,t不是常数,而是随时间衰减的。AdaFactor选择了β^∗2,t=1−t−c\hat{\beta}*{2,t} = 1 - t^{-c}β^∗2,t=1−t−c的形式,默认c=0.8c=0.8c=0.8。这样在初期ttt小时β^2,t\hat{\beta}_{2,t}β^2,t较小,增加梯度历史权重;后期趋近1又保留RMSprop的长久记忆效果。这一技巧据论文称有助于不同训练阶段稳定更新。
此外,他们还借鉴LAMB,在最终更新前按参数模长调整了更新模长(层自适应)。这些都使AdaFactor在大模型上效果更出色。
优点:
- 超省内存:这是AdaFactor最大卖点。例如,在一个需要12GB显存用Adam的模型上,用AdaFactor可能只需6GB不到就能跑。这允许我们训练更大的模型或在相同硬件上使用更大batch。
- 自适应学习率:尽管省去了mmm,AdaFactor保留了RMSProp式的自适应步长特性,而且从实践看效果良好。作者声称AdaFactor不仅节省内存,还针对性地解决了Adam的一些缺陷。
- 灵活性:AdaFactor既可以用于纯矩阵参数,也能兼容向量参数(对向量参数,算法会退化为类似RMSProp的更新)。同时,它支持不提供全局学习率时自动用min(10−2,1/t)\min(10^{-2}, 1/\sqrt{t})min(10−2,1/t)这样的默认策略。
缺点:
- 略损精度:用低秩近似毕竟是一种折衷,AdaFactor在某些任务上需要精心调试学习率等,才能达到或超过Adam的效果。特别是在较小规模或下游微调任务上,AdaFactor有时表现不如Adam,需要更多尝试。
- 大batch需求:AdaFactor论文建议在batch size较大时使用。因为低秩近似带来一定误差,如果batch本身小又嘈杂,误差加剧可能影响收敛。预训练一般batch大,因此问题不大;微调时batch常小,则需要注意。
- 实现复杂:AdaFactor公式繁多(如上列六步),理解和实现都比Adam困难。不过幸好已有开源实现且集成到TensorFlow等框架中。
应用场景:AdaFactor被用于超大模型的预训练,典型案例是谷歌的T5模型(110亿参数)。在如此规模下,AdaFactor节约的内存是训练能否进行的关键。此外,Transformer-XL等模型的训练中也出现过AdaFactor的身影。当研究人员受限于GPU显存无法用Adam训练大模型时,AdaFactor提供了一个有吸引力的替代方案。对于一般下游任务,AdaFactor也可一试,但需注意调参。
代表案例:如上所述,Google的T5语言模型预训练使用了AdaFactor优化器,使其在TPU上以相对有限的硬件完成了百亿参数的训练。很多开源NLP框架(如Transformers库)在提供T5等预训练模型时,也将AdaFactor作为推荐的微调优化器之一。此外,在学术分析中,AdaFactor针对于Adam的内存和收敛问题的剖析被认为相当经典,值得优化领域深入研究。
5.4 Shampoo优化器
在优化算法的光谱上,SGD和Adam等属于一阶方法(只利用梯度本身),而另一端是二阶方法,典型如牛顿法利用Hessian矩阵(二阶导数)来预调梯度方向和尺度,具有理论上的快速收敛性。然而,直接用Hessian矩阵在深度学习中不可行:参数维度巨大,Hessian是维度平方级别,不论计算还是存储都极其困难。
Shampoo(来自“Second-order preconditioned stochastic optimization”之意)是Google Brain的研究尝试,用一种近似二阶信息的方法改进优化速度。它由Gupta等人在2018年提出,之后又有改进版本。Shampoo的核心是利用参数张量的Kronecker分解近似Hessian的逆。听起来复杂,我们尽量通俗解释:
假设我们的参数是一个矩阵W∈Rm×nW \in \mathbb{R}^{m \times n}W∈Rm×n。Shampoo为这个参数维护两个预条件矩阵:L∈Rm×mL \in \mathbb{R}^{m \times m}L∈Rm×m和R∈Rn×nR \in \mathbb{R}^{n \times n}R∈Rn×n。每次迭代,Shampoo累积梯度信息来更新它们:
Lt=Lt−1+GtGtT,Rt=Rt−1+GtTGt L_t = L_{t-1} + G_t G_t^T, \qquad R_t = R_{t-1} + G_t^T G_t Lt=Lt−1+GtGtT,Rt=Rt−1+GtTGt
其中GtG_tGt是当前梯度矩阵。可以看出,LLL累积的是梯度在行方向上的协方差,RRR累积的是梯度在列方向上的协方差。然后,Shampoo的参数更新使用这两个矩阵的逆平方根(或某个幂):
Wt+1=Wt−η Lt−1/4 Gt Rt−1/4 W_{t+1} = W_t - \eta \, L_t^{-1/4} \, G_t \, R_t^{-1/4} Wt+1=Wt−ηLt−1/4GtRt−1/4
这个看似奇怪的公式实际上在做一件事情:用L−1/4L^{-1/4}L−1/4和R−1/4R^{-1/4}R−1/4一起充当Hessian的逆的近似,对梯度GtG_tGt进行双边缩放。直觉上,LLL包含了各行梯度变化的信息,RRR包含了各列梯度变化的信息,综合起来,L−1/2GR−1/2L^{-1/2} G R^{-1/2}L−1/2GR−1/2类似于用(GGT)−1/2(G G^T)^{-1/2}(GGT)−1/2预处理梯度,只不过Shampoo用Kronecker积的性质把后者拆成两部分算了(从而降低计算复杂度)。
这样做的效果是:每个参数元素θij\theta_{ij}θij的更新,不再仅由它自己的梯度决定,而是参考了跟它同一行、同一列的其他参数梯度情况。某种程度上,这近似考虑了Hessian矩阵的结构(Hessian涉及每对参数偏导的二阶关系)。
优点:
- 更快的收敛:引入二阶信息后,优化步骤在条件数不良的情况下会显著加快。简单说,如果损失面的峡谷特别狭长,SGD沿着谷底走很慢,而Shampoo通过预处理,会拉伸谷底,使其对算法来说更接近平坦,从而更快推进。
- 自动调参:二阶方法的好处之一是对学习率不那么敏感,因为预处理本身在调整步长尺度。Shampoo虽然还是要η\etaη,但鲁棒性比SGD/Adam高一些。在一些实验中Shampoo能用较少的尝试得到不错的结果。
- 理论保障:论文对Shampoo给出了收敛的理论分析,在凸情况下证明了和全Hessian预条件方法同阶的遗憾(bound)。这说明这种Kronecker近似在理论上并不过分损害效果。
缺点:
- 计算和存储开销:LLL是m×mm \times mm×m矩阵,RRR是n×nn \times nn×n矩阵。如果m,nm,nm,n都很大,它们仍然可能难以计算和存储。Shampoo针对这些矩阵需要计算矩阵1/41/41/4次方(本质上通过特征值分解实现)。为减小开销,实践中常隔多步才更新一次预条件矩阵的逆根,或者对大于一定尺寸的层采用分块处理等。即使这样,Shampoo相对Adam仍是更重的算法。
- 实现复杂:涉及线性代数运算(特征分解、Kronecker积)的实现,要高效并行并不容易。Google在分布式环境下实现了Shampoo,并在2023年开源了更优化的版本,但普适性还不如Adam那样开箱即用。
- 内存依然高:Shampoo减小了状态存储相对于直接Hessian的方法,但L,RL,RL,R矩阵总数之和仍比vvv向量大不少。尤其对卷积层的4D张量参数,需要对每个维度都维护预条件矩阵,状态很多。为此最近有工作将Shampoo的预条件矩阵进行量化(如4-bit)以降低内存。
改进:针对以上缺陷,Shampoo生态出现了不少改进:
- 分布式Shampoo:将预条件矩阵分片放到不同设备,并不每步更新所有特征值分解,以减小通信和计算压力。
- 4-bit Shampoo:正如提到的,用低精度存储预条件矩阵并保持性能。
- 与Adam结合的SOAP优化器:最近Vyas等提出SOAP,把Adam的momentum引入到Shampoo的预条件矩阵特征空间中,从而少算一些特征向量更新但保留Adam的一阶矩跟踪,取得了更好的性能。
- S+ (SPlus):2025年的研究,通过对Shampoo更新加入符号归一化、按层宽度缩放、滑动平均平滑等,进一步提高了大步长下的稳定性。
这些改进使Shampoo逐渐接近实用化,在一些大模型如30亿参数的Transformer上已经展示出比Adam更快的收敛且更短的训练墙时。
应用场景:Shampoo目前主要在研究和工业实验中用于大型模型的预训练或者需要极快收敛的场景。如果计算资源充裕、并且模型训练耗时很长,用Shampoo类方法可能节省总时间(虽然单步贵但收敛步数少)。例如在Google内部,Shampoo及其变种已用于一些大规模Transformer的预训练,取得比Adam更少迭代达到同等损失的效果。未来,如果计算开销进一步降低,Shampoo有望推广到更广泛的模型训练中。
代表案例:Shampoo论文报告在ResNet-50训练ImageNet上收敛更快。在更新的研究中,SOAP优化器使用Shampoo思想在1024卡大batch的语言模型上达到了迭代数和时间上都优于AdamW的效果。另外,低比特Shampoo让以前不敢想的预条件矩阵规模成为可能(7倍状态压缩),允许在更大模型上应用。有实验表明,用Shampoo变种训练GPT-3规模的模型,可以在更少的epoch内达到同等甚至更好的验证集困惑度。尽管Shampoo目前还不是主流优化器,但它代表了对更高效优化的探索方向。
5.5 Lion优化器
最后介绍一种颇为新颖的优化器Lion(EvoLved Sign Momentum),它并非由人工手工设计,而是通过自动化搜索发现的。2023年,Google Brain团队Chen等人将优化器看作一个可以搜索的程序,通过强化学习和进化算法,在一个由基本算子组成的巨大空间里筛选出了效果出众的算法——他们将其命名为Lion。Lion名字中的字母源自Learned sign momentum(进化得到的符号动量)。
Lion优化器有以下显著特征:
-
仅保留动量的一阶历史,没有二阶矩估计,因此状态开销跟Momentum类似,只需要一个动量向量(相比Adam省了一半内存)。
-
更新时只用动量的符号:Lion的更新步长对每个参数在某一步不是依赖梯度大小,而是采用sign\mathrm{sign}sign函数。具体来说,Lion算法可描述为:
mt=β1mt−1+(1−β1)gt m_t = \beta_1 m_{t-1} + (1-\beta_1) g_t mt=β1mt−1+(1−β1)gt
update=sign(mt)(逐元素取符号,+1或-1) \text{update} = \mathrm{sign}(m_t) \quad (\text{逐元素取符号,+1或-1}) update=sign(mt)(逐元素取符号,+1或-1)
θt=θt−1−η⋅update \theta_t = \theta_{t-1} - \eta \cdot \text{update} θt=θt−1−η⋅update
这里β1\beta_1β1相当于动量因子,Lion还使用了一个β2\beta_2β2(默认为0.99)对动量进行更长历史的平滑,不过实质上可以视作两级动量平衡。Lion更新每个参数时,只关心当前累积梯度的方向,而忽略其具体大小,所有有梯度的参数的更新幅度一致为η\etaη,没有梯度的则不更新。
-
较小的学习率需求:因为Lion每一步更新的向量范数通常比Adam类更大(很多维度都用固定步长而不是按梯度幅度缩放),因此需要使用比Adam更小的学习率。推荐值通常是Adam学习率的1/3到1/10。相应地,如果有权重衰减,衰减系数要按同样比例放大以达到等效正则。
直观理解:Lion为何有效?研究者分析说,Lion更新由于使用符号,增强了噪声鲁棒性,使得训练过程在损失表面更平滑的区域收敛,这往往带来更好的泛化。可以想象,在谷底附近,梯度很小但符号可能仍有用,Lion不会因为梯度幅度变小就停止更新(像Adam可能η/v\eta/\sqrt{v}η/v变得很小),它依然在按照符号慢慢推进,这或许帮助逃离鞍点和平坦区域。
同时,Lion的两个动量常数β1,β2\beta_1,\beta_2β1,β2让它兼顾长短期梯度趋势:β2=0.99\beta_2=0.99β2=0.99保持一个更长的历史(更平稳的动量),β1=0.9\beta_1=0.9β1=0.9给予当前梯度更多权重用于符号更新。这种双动量设计据说让Lion既能记住较长的梯度方向又对当前梯度变化敏感。
优点:
- 内存高效:和Momentum一样的开销,比Adam减少一半状态。对大模型有意义。
- 强大的实证效果:Lion在论文中表现惊艳,在多个任务上超越Adam:在ViT图像分类预训练上提升Top-1精度2个百分点;在图文对比学习(CLIP)上零样本准确率提高2%;在扩散模型训练上得到更好FID且计算减少2.3倍。这些结果表明Lion在视觉和生成模型方面都很有效。同时Lion也被用于Google Ads的CTR预估模型上线,证明了工业可用性。
- 实现简单:Lion的更新法则出奇简洁,只是符号操作和加减,非常容易实现和并行。而且没有二阶计算,计算量与SGD接近。
缺点:
- 需调整学习率:如前所述,Lion通常要用比Adam小得多的学习率,否则步子太大容易发散。对于习惯了Adam默认η=10−3\eta=10^{-3}η=10−3的人来说,要切换Lion并找合适η\etaη需要一些摸索。
- 有限理论分析:Lion是通过自动发现的,缺乏成熟的理论支撑。目前对其收敛性、适用范围等还在研究,属于经验驱动的算法。
- 并非全方位碾压:Lion在很多视觉任务赢了Adam,但也有一些场景提升不显著甚至略差。论文也指出了Lion的改进有限的情形,比如对小batch或使用强数据增广时,Lion相对优势减弱。因此它并非毫无缺点的万能优化器。
应用场景:Lion目前看起来对计算机视觉任务尤其有效,如ViT、Diffusion等模型训练,以及大批量情况下有优势。在自然语言处理任务上,Lion据论文显示性能与Adam相当,优势不大;在强化学习中尚未见明确结果。鉴于Lion是新算法,今后可能会有更多实验和改进。如果要尝试Lion,建议在图像、跨模态模型训练中测试,它可能带来更高的收敛速度和精度。
代表案例:论文已经提到多项。值得再次强调的是Stable Diffusion模型的训练中,一些开源爱好者也验证了Lion的效果——Lion被社区用于微调扩散模型,报告比AdamW得到更好的生成质量。Lion的发现也激发了对自动发现优化器的兴趣,但目前Lion本身已经足够简单实用,许多近期的项目开始将Lion纳入选项。
6. 总结与展望
从最基础的梯度下降到复杂的大模型优化器,我们走过了机器学习优化算法的发展历程。在这条路径上,每一种算法都针对当时训练深度模型所遇到的瓶颈提出了解决方案:
- **梯度下降(SGD)**奠定了基石,但存在学习率和收敛稳定性难题。
- Momentum动量法赋予优化以惯性,大大改善了在狭窄峡谷区域的震荡问题和收敛速度。
- Nesterov加速梯度则让动量更聪明,增加了预判能力,从而进一步提升了优化效率和稳健性。
- AdaGrad开创了自适应学习率,通过累积梯度历史自动调整步长,对稀疏数据效果突出。
- RMSProp用滑动平均克服了AdaGrad学习率过快衰减的问题,成为深度学习中一度流行的优化器,并为后续算法打下基础。
- Adam融会了动量和自适应的精华,几乎成为深度学习优化的默认选择,在各种任务上表现稳定高效。
- AdaFactor、Shampoo和Lion等新算法则聚焦当代大模型的挑战:AdaFactor解决内存瓶颈、Shampoo探索更高阶的加速、Lion通过AutoML提供了全新思路。它们分别在极大参数规模、极大批量并行、自动优化器设计上取得了突破,为今后训练更庞大更复杂的模型铺平了道路。
可以看到,优化算法的发展与深度学习本身的发展息息相关:模型越来越深、数据越来越大,优化算法也在不断演进以适应新的需求。对于高中生读者来说,不需要记住所有公式,但希望通过这些算法的介绍,你能体会到:
- 优化算法在机器学习中扮演着重要角色,是模型能否高效学到好结果的关键因素。
- 每个算法都有其出发点和适用情景,没有万能的方案。实际工作中,选择优化器常需考虑数据特点、模型结构和硬件条件。
- 数学推导虽有难度,但抓住核心思想(比如“累积惯性”“调整步长”“使用二阶信息”“取符号”等)就能理解算法如何改善优化过程。
- 直观类比(球下山、峡谷振荡)能帮助我们将抽象的数学概念形象化,这是学习过程中很有用的方法。
展望未来:随着机器学习模型向着更大、更复杂发展,优化算法也会继续创新。例如:
- 结合二阶信息但计算高效的优化器可能会越来越多,缩短训练时间。
- 针对分布式训练的不同时延情况,或异构硬件的优化算法也会出现(让不同设备以不同步调更新等)。
- AutoML可能发现更多像Lion一样奇特但有效的新算法,也许有一天优化器将不再由人设计,而是机器自动找出最适合当前任务的规则。
- 更加智能的学习率调度、与最优化理论更紧密结合的算法也在研究中,比如直接优化泛化误差的二阶方法等。
无论如何,掌握经典的优化算法思想,将为你进一步学习人工智能领域打下基础。在实际应用中,调试和改进优化器仍是一门艺术,需要理论和实践并重。希望这份报告既帮助你理清了从SGD到Adam再到新型优化器的发展脉络,又激发你对机器学习优化技术的兴趣。未来,你们这一代或许会参与发明新的优化算法,来应对AI不断提出的新挑战!
参考文献:
- Sebastian Ruder. An overview of gradient descent optimization algorithms. 2016. 等。
- Duchi et al. Adaptive Subgradient Methods for Online Learning and Stochastic Optimization (AdaGrad论文). 2011.
- Tieleman & Hinton. Lecture 6e rmsprop: Divide the gradient by a running average of its recent magnitude. 2012. (RMSProp最早出处)。
- Kingma & Ba. Adam: A Method for Stochastic Optimization. ICLR 2015. (Adam论文)。
- Loshchilov & Hutter. Decoupled Weight Decay Regularization (AdamW论文). ICLR 2019.
- You et al. Large Batch Optimization for Deep Learning: Training BERT in 76 minutes. ICLR 2020. (LAMB论文)。
- Shazeer & Stern. Adafactor: Adaptive Learning Rates with Sublinear Memory Cost. ICML 2018. 。
- Gupta et al. Shampoo: Preconditioned Stochastic Tensor Optimization. ICML 2018. 。
- Chen et al. Symbolic Discovery of Optimization Algorithms (Lion论文). ICLR 2023. 。
- 其他引用内容均在文中以【†】形式标注出处。
更多推荐
所有评论(0)