深度学习优化器选型指南:从SGD到AdamW的对比与实践

发布时间:2026/10/20 14:06:15
深度学习优化器选型指南:从SGD到AdamW的对比与实践 很多刚接触深度学习的朋友问过我一个很现实的问题模型结构也搭了数据也准备好了但训练的时候loss要么不动要么像过山车一样乱跳到底问题出在哪有人说是学习率没调好有人说是初始化不对但我想说一个经常被忽略又极其关键的因素其实是优化器。选不对优化器你连损失函数的长相都摸不清更别提让模型收敛了。这篇内容不聊数学推导的每个细节重点讲清楚优化器到底是什么、主流优化器之间的区别、以及我在实际训练任务里摸索出来的选型经验希望对正在调模型但卡在训练环节的人有帮助。1. 优化器到底在解决什么问题不只是在“更新参数”先打个比方。你站在一座山上周围全是雾手里只有一张海拔计目标是摸黑走到山谷最低点。优化器干的事情就是决定你每一步怎么走——走多快、往哪个方向、要不要看看之前走过的路。参数更新其实就一句话新参数 旧参数 - 学习率 × 更新方向但关键在于“更新方向”怎么算这才是各种优化器的本质分歧。1.1 从梯度下降说起为什么“按梯度反方向走”不够用最朴素的梯度下降法每次更新都直接沿着当前梯度反方向走。这在数学上没毛病在实际训练中就很难受——如果山谷比较狭长梯度在某个方向上来回震荡步长大了会冲过头步长小了又在陡坡上磨蹭收敛速度慢得让人抓狂。我早期训练一个小网络时就用纯SGDloss从2.0降到1.5只花了几百个step但从1.5再往下走几乎就卡住了怎么调学习率都别扭。问题出在哪纯SGD只用了当前这一时刻的梯度信息没有“历史记忆”所以它对梯度的随机波动特别敏感。想象一下你下坡时每次都重新看地形完全不记得刚才哪条路比较顺——每一步都可能被局部的小颠簸带偏。实际训练里这表现为loss曲线锯齿感特别强尤其是在batch比较小的时候噪声会更大。1.2 优化器的家族谱系三类核心改进思路后来所有优化器的演进基本都是在解决同一个问题如何让“走下山”这个动作既快又稳。我梳理了三条主线理解了这三条线你再看任何新出的优化器都不会慌第一类是动量类代表是SGD with Momentum。思路就是记住惯性如果前几步一直朝同一个方向走那这一步就顺着惯性再加速一点。这解决的是梯度震荡问题就像你骑自行车转弯时不会完全打死方向而是顺着前轮的方向柔和过渡。第二类是自适应学习率类代表是RMSProp和Adam。思路是每个参数单独配一个步长更新频繁的参数步长自动变小更新稀疏的参数步长自动变大。这解决的是不同参数尺度差异大的问题。我举一个实际例子你在训练一个带Embedding的推荐模型时有些词出现几万次有些词只出现几次如果所有参数用同一个学习率那些稀疏特征要么学不动要么学过头。第三类是修正融合类代表是AdamW、NAdam、Lion这些。要么是把前两类优点合起来要么是发现了原有算法在某些场景下的毛病后打的补丁。理解了这三条线下面我逐个拆解主流优化器的时候你就能清晰地感受到每个算法到底在“动哪个螺丝”。2. 逐个拆解主流优化器每个改进背后的代价2.1 SGD with Momentum惯性的力量但要注意动量系数Momentum的更新公式比纯SGD多了个“速度”变量这个速度是历史梯度的指数衰减平均。核心超参是momentum一般设0.9。它的效果非常直观如果梯度方向一直没变速度会越滚越大相当于在平缓方向的坡上“加速”如果梯度方向频繁翻转速度的正负项会相互抵消更新幅度被压制从而抑制震荡。不过这个“加速”也有副作用。动量积累过大时模型很容易冲过极小值点然后在另一边来回震荡这就是为什么一些人用Momentum时发现loss快收敛了却又反弹。我一般会配合学习率衰减一起用比如每过若干个epoch把学习率乘一个衰减系数避免速度积累得太过。2.2 RMSProp给每个参数单独一把尺子RMSProp的核心是维护梯度平方的指数移动平均然后用它来缩放学习率。它的好处非常明显对于那些梯度一直很大的参数分母会变大步长自动缩小对于那些梯度很小的参数分母变小步长自动放大。效果就是整体训练变得非常稳定尤其是处理非平稳目标时比SGD稳得多。但RMSProp也有自己的毛病——它对那个“历史平方梯度”的初始状态很敏感而且在训练后期分母可能积累得比较大导致步长过小收敛变慢。我见过有人在训练一个生成模型时用RMSProp跑了几千步loss都降不下去后来一查是epsilon设得太小导致分母除出来数值非常大学习率被压到了几乎为零的量级。2.3 Adam自适应学习率动量的组合但不是银弹Adam把Momentum和RMSProp的思路结合到了一起。它同时维护一阶动量梯度的均值和二阶动量梯度平方的均值分别在更新方向和学习率缩放上做文章。这是目前我用过训练初期收敛最快、调参压力最小的优化器特别是CV、NLP大模型场景几乎默认首选就是Adam。但Adam有两个广为人知的问题。第一它的二阶动量估计在早期会偏小导致初始学习率被放大所以需要bias correction偏差修正。不过PyTorch里已经内置了这项工作你直接用默认参数就行。第二也是更实际的问题——Adam在训练后期容易在最优解附近徘徊有时最终的泛化能力反而不如SGD。后来我读到一些分析说法是Adam的“自适应学习率”在参数的某些方向上被缩放得太极端相当于给模型引入了另一种形式的噪声。2.4 AdamW主流之选修正权重衰减的“误伤”AdamW是我现在用得最多的优化器。它解决的问题听起来很简单原来的Adam做L2正则化时会把权重衰减混入梯度里等于变相改变了梯度的大小和“衰减权重”这件事本身是矛盾的。AdamW把权重衰减从梯度计算里拆出来直接在参数更新那一步做这样正则化行为就更纯粹。实际用起来AdamW几乎保留了Adam快速收敛的优点同时最终精度和泛化性能比Adam更稳。我在一个图像分类任务上对比过同样的模型结构AdamW跑到后期能比Adam高出大约0.4到1个百分点的验证集准确率。如果你的任务对最终精度有要求我建议直接默认AdamW而不是Adam。2.5 新势力NAdam、Lion、Sophia这些要不要追NAdam相当于给Adam再加了一层Nesterov动量理论上收敛梯度方向更准但实际提升幅度有限除非你在跑一些对稳定性的需求特别高的小任务否则没必要刻意追新。Lion是最近看到比较多的优化器思路很直接——它把一阶动量的符号直接当作更新方向省掉了“梯度具体大小”的计算。这听起来很奇怪但它确实在有些大规模视觉模型训练上表现出了比AdamW更好的收敛速度和效果。不过我对它的理解还不够深体验不多。我的态度是新优化器可以在小规模任务上做对比实验但核心生产任务还是选验证过多次的AdamW或SGD。下面放一个我平时做选型参考的速查表方便你直接对照着自己的任务需求来挑。优化器核心思想优点典型坑点我的推荐场景SGD当前梯度反方向简单、泛化性不错收敛慢、易震荡数据量不大、模型较浅Momentum动量累积收敛快于SGD缓解震荡动量系数需要调中小型任务调优RMSProp自适应学习率对非平稳目标友好后期可能停步生成模型、在线学习Adam动量自适应初期收敛极快后期泛化可能不佳大多数深度学习任务AdamW解耦权重衰减收敛快、泛化好需注意betas设置大模型、CV、NLP主选3. 实测对比同一个任务换优化器结果差距有多大3.1 一次图像分类实验的具体对比说再多理论不如跑一次实验来得直观。我之前在某公开图像数据集上做过一次优化器对比实验用的模型是一个中等规模的图像分类网络训练策略完全一样只替换优化器。我记录了每个优化器跑到同样的loss值所需的步数以及最终验证集精度SGDmomentum0.9跑到loss0.5需要约15个epoch最终验证率约84.2%。前期很慢后期稳定。Adam学习率0.001跑到同样loss只用了约8个epoch但验证率只到83.6%。收敛快但后面有隐忧。后面验证率甚至会小幅回退。AdamW学习率0.001weight_decay0.01跑到同样loss约8.5个epoch最终验证率约85.1%。初期速度和Adam持平后期继续稳步上升。这个结果其实很典型。Adam和AdamW在初始阶段速度都碾压SGD因为它们的自适应学习率能快速适应不同参数的尺度但到了后期SGD那种“老老实实沿着梯度走”的方式反而可能找到更平坦的极小值点泛化能力更强。AdamW通过解耦权重衰减在一定程度上兼顾了两者的优点所以在这个测试里综合表现最好。3.2 为什么SGD的泛化性常常比Adam好平坦极值的直觉解释关于“Adam泛化不如SGD”这个问题一个比较通俗的解释是“尖锐极小值 vs 平坦极小值”的传说。SGD配合合适的训练策略倾向于收敛到参数数值变化都相对温和的区域也就是平坦的盆地区域而Adam的自适应步长在某些方向上冲得太快可能卡在一个很深的窄缝里。简单说平坦的极小值对测试数据的微小扰动更不敏感泛化能力自然更强。我之前一直没把这点当回事直到一次在模拟项目的验证集上观察到了过拟合信号Adam训练出来的模型在验证集上的loss出现了轻微回升而同期用SGD训练的模型虽然收敛更慢但验证集表现一直非常稳定。那次之后我开始重视一个策略先用AdamW快速找到一个大致好的区域再切换成SGD精调几个epoch。这个办法听起来有点土但实测效果非常不错——不光是精度模型的稳定性也更好。3.3 不同任务对优化器的敏感度差异需要特别提醒的是优化器在同一个任务上的差异不代表在你自己的任务上也一定这么明显。我对几个不同类型的任务做过观察NLP分类任务对优化器不那么敏感主要原因是我通常用预训练模型加微调的套路预训练权重已经把模型放在一个比较好的起点优化器只负责小幅调整。目标检测或分割这类带坐标回归的任务AdamW的优势往往更明显因为特征图的尺度差异很大自适应学习率能帮上大忙。生成对抗网络或者扩散模型这类训练稳定性要求高的任务动量类优化器容易出现模式崩塌RMSProp或者Adam系的稳定性更靠谱。所以选优化器不是“哪个强就无脑用哪个”而是要看你的任务属于哪一类。当然最稳妥的方法还是在小规模数据上跑几个短实验用验证集上的表现说话。4. 优化器调参与避坑真正影响结果的那几个细节4.1 学习率才是最大的杠杆我见过太多人在优化器之间反复横跳却没想过问题可能出在学习率上。不同优化器对学习率的敏感度完全不同。SGD的安全学习率范围通常在0.1以下一旦设大了直接发散Adam和AdamW默认0.001一般都能跑起来但上限和下限差异非常大。我的建议是当你换优化器时首先重新搜索学习率而不是沿用上一个优化器的设置。一个简单的经验是在固定batch size的情况下把学习率从小到大按十倍间隔试一遍比如1e-5、1e-4、1e-3、1e-2、1e-1训练几百个step观察loss是降、震荡还是发散快速锁定量级再在量级内细调。4.2 warmup为什么训练初期要“慢慢来”warmup的意思是在最初若干步内把学习率从很小的值线性增长到目标值。这个技巧在Adam系和Transformer类模型里几乎是标配。原因也很简单刚初始化时模型参数离最优解很远梯度方向可能很不准确如果一上来就大步走很容易被带到沟里。先把步子放小等梯度方向稳定了再加速能够明显提升训练的稳定性。我个人在训练大规模模型时习惯把warmup步数设在总步数的5%~10%之间。比如总共有2万步就先用1000到2000步做warmup。如果任务比较小warmup效果不明显但也不会带来明显的危害可以按需求保留。4.3 几个容易踩的坑epsilon、betas、权重衰减先说epsilon。Adam和AdamW里有个epsilon超参默认通常是1e-8。它的作用很简单——防止分母除零。但如果你用混合精度训练数值精度下降epsilon太小可能让更新步长产生异常跳动这时候把epsilon加到1e-6甚至1e-7左右往往能提高稳定性。我在一次混合精度训练中遇到loss偶尔变成nan最后排查到就是epsilon设太小导致的。这个坑不常见但遇到了会让人很头疼。再说betas。Adam类默认是(0.9, 0.999)这个配置适应大多数场景。但如果你训练的是稀疏特征极其多的模型可以考虑把一阶动量系数调小到0.8让模型对当前梯度的反应更灵敏如果你发现训练后期波动很大可以试试把二阶动量系数从0.999调到0.99让学习率缩放的历史窗口变短更适应当前梯度。最后是权重衰减。用AdamW时我习惯把weight_decay设置在0.01到0.1之间具体值跟模型参数量和训练集规模有关。参数量大、数据量小时权重衰减可以适当加大防止过拟合。之前试过把weight_decay从0.01调到0.05在某个分类任务上验证集准确率提升了约0.6个百分点说明这个参数不能随意不管。4.4 一个逐步排查的套路loss不降时按什么顺序检查当你遇到loss迟迟不降的情况我的排查顺序是这样的先确认数据加载和标签没问题这个最基础也最容易被忽略。改成小规模数据过拟合测试看模型能不能把一个batch数据完全记住。如果连这个都做不到问题大概率在模型结构或优化器配置上。再检查学习率尝试调大一倍看loss是否变化如果变大后爆炸说明学习率偏高如果完全没有变化说明学习率太小。最后再考虑换优化器很多情况下用AdamW替掉Adam或者把SGD换成Momentum版本就能解决一部分问题。这个顺序能帮你避免一上来就怀疑优化器其实大部分问题都出在前两步。5. 混合精度、分布式训练下的优化器特殊处理5.1 混合精度训练浮点精度对Adam类算法的影响现在的GPU基本都支持混合精度训练也就是部分计算用FP16部分用FP32用来省显存、提速度。但这里有个隐藏问题梯度、动量这些状态在FP16下会丢失精度尤其是梯度的取值范围波动较大时小梯度可能会被舍入到零直接废掉了那些更新幅度小的参数。主流框架的解决办法是维护一份FP32版本的优化器状态也就是Master Weight和FP32的动量缓存。这也就是为什么你看很多训练代码里混精模式下checkpoint的体积比纯FP32还大——模型参数虽然是FP16但优化器的FP32状态全被保存下来了。5.2 分布式训练时要不要调整优化器参数分布式训练本身不改变优化器算法但会影响等效batch size。当你把batch从256扩到1024时梯度估计的噪声变小了所以可以适当调大学习率。经验上batch变大k倍学习率可以试着调大到sqrt(k)倍或者直接线性调大但前提是要配合warmup避免早期不稳定。我在一个分布式训练项目里batch从256扩到2048把AdamW的学习率从0.001调到0.002并延长了warmup步数训练效率和最终效果都有提升。但如果你同时换优化器又调大batch就很难判断最后的收益到底来自哪个变量——所以我习惯一次只改一个变量。5.3 优化器状态与断点续训一个经常被忽略的问题断点续训时很多人只保存了模型权重忘了保存优化器状态。结果就是恢复训练后模型还能加载但优化器里的动量、二阶动量全被清零了训练初期会非常不稳之前的“惯性”和“步长记忆”全没了。我遇到过跑了几十小时的训练中断恢复后发现loss反而回升了一截最后定位到就是没恢复优化器状态。解决办法很简单保存checkpoint时把optimizer的state_dict一并保存。加载时注意模型和优化器状态要严格对应不要用某个中间step的模型配另一个step的优化器状态。这对长周期训练任务来说是保持训练连贯性的一个根本保障。6. 我的选型经验与一点可复用的建议如果让我给出一套相对通用、不容易出错的组合策略我会这样推荐中小规模任务对最终精度要求高优先考虑AdamW默认lr0.001, betas(0.9, 0.999), weight_decay0.01。如果训练速度慢再考虑切换到SGDMomentum精调末期。大规模模型预训练比如Transformer类AdamW几乎是不二选择配合warmup和cosine学习率调度。对稳定性要求极高的生成类任务RMSProp或者带warmup的AdamW更稳SGD容易因为梯度噪声大而震得让人心慌。时间有限、只想快速验证一个想法的效果直接用默认参数的AdamW它至少在90%的场景不会让你翻车。优化器本身没有绝对的好坏只有适不适合。我对很多同学的建议是把大部分精力放在数据质量和模型结构上优化器只是把模型推向最优解的工具但选对了它能让你的训练曲线平滑许多。最后分享一个自己常用的做法每次开始一个新任务先花半个小时写一个小实验脚本把SGD、AdamW、RMSProp放在同一个小验证集上各跑几十步对比loss曲线和验证集指标。这个“三选一”小实验成本很低但能帮你少走很多弯路比盲目迷信某个优化器可靠得多。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询