尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

深度学习优化器全解析:SGD、Adam、AdamW选型与调参实践

发布时间:2026/9/29 16:57:15

资讯中心
01
ARTICLE

深度学习优化器全解析:SGD、Adam、AdamW选型与调参实践

深度学习优化器全解析:SGD、Adam、AdamW选型与调参实践
搞深度学习这几年有个东西几乎天天见但很多人一直把它当黑盒用那就是优化器optimizer。模型搭好了、数据准备好了、loss函数写完了真正决定模型能不能收敛、收敛多快、收敛到什么精度的很大程度就是优化器选型和参数设置。Model-Optimizer这个名字听起来像个工具库拆开看其实就是在解决一件事怎么让模型参数沿着正确的方向、用合适的步长一步步走到损失函数的低点。这篇东西我不打算讲教科书式的推导就按我实际训练模型的经验把优化器的原理、主流方案的取舍、参数怎么设、踩过的坑完整捋一遍。不管你是刚入门的新手还是已经跑过不少实验的老手这篇文章都能给你一些可以直接抄作业的配置也能帮你建立一套自己的调优思路。优化器虽然只是一行代码的事但背后牵扯到收敛速度、泛化能力、训练稳定性甚至直接影响你显卡燃烧的时长值得花时间搞清楚。1. 优化器是干什么的一个被低估的训练引擎1.1 从梯度下降到参数更新优化器的本质我们在训练神经网络时实际上是在做一个超级大的参数寻优问题。模型拥有几百万到几千亿不等的参数每个参数都对应一个数值这些数值组合起来决定了模型的行为。损失函数衡量的是当前参数组合下模型的预测和真实标签之间的差距训练的目标就是找到一组参数让这个差距最小。最简单的想法是沿着梯度的反方向更新参数这就是经典的梯度下降。步长由学习率控制公式写成theta theta - lr * grad这里lr是学习率grad是损失函数对参数的梯度。这套朴素逻辑在浅层模型上够用但在深层神经网络里很快露馅梯度的大小在不同层、不同参数之间差异极大有的地方梯度大得像瀑布有的地方小得像滴水。而且损失曲面往往不是平滑的碗状而是沟壑纵横的复杂地形有的方向陡峭得离谱有的方向平坦得吓人。如果只用单一全局学习率去更新所有参数结果不是震荡发散就是蜗牛爬行。优化器的价值就在于它针对这些复杂情况设计了一整套参数更新策略有的通过动量来平滑更新方向有的通过历史梯度信息为每个参数自适应调整学习率有的结合了方差校正和权重衰减机制。可以说优化器把“往哪走”和“走多远”这两个问题从朴素的一步棋发展成了一整套战术体系。1.2 为什么同一个模型不同的优化器效果差这么多一个非常常见的现象是同一个模型结构、同一份数据、同一个loss把SGD换成Adam效果完全不一样。这不是玄学而是因为不同优化器对梯度信息的利用方式根本不同。SGDMomentum依赖的是梯度的一阶矩也就是历史梯度的指数移动平均它的行为很依赖学习率设置收敛路径相对平滑最终到达的极小值点往往泛化性更好。而Adam除了维护一阶矩还维护了梯度的二阶矩能感知每个参数的历史梯度方差从而给每个参数独立地缩放学习率。这带来的直接好处是Adam对初始学习率的敏感度低很多默认的1e-3在绝大多数任务上都能跑起来非常适合早期快速探索。但Adam也有自己的问题二阶矩估计在训练早期偏差较大可能导致前几步更新异常训练后期不停积累的二阶矩会让有效步长越来越小导致收敛不够彻底。很多大规模视觉模型最终选择SGD或AdamW不是因为Adam不好而是因为不同的优化器对应着不同的最优点偏好。后面我在第5节会用一个实际的对比实验展示这一点。2. 主流优化器横向对比选型就是训练策略的一半2.1 经典SGD与动量机制SGD随机梯度下降在深度学习中的地位依然不可撼动尤其在大规模视觉模型的训练中它仍然是最值得信赖的选择之一。纯SGD收敛慢且容易陷入局部震荡所以在实际工程中几乎总是配合动量使用公式核心是维护一个速度变量velocity momentum * velocity lr * grad theta theta - velocity动量机制解决的核心问题是当梯度方向在相邻step内频繁变化时直接按当前梯度更新会导致路径锯齿状震荡。累积历史方向的速度变量能让更新方向更平滑并且在进入平坦区域时保持惯性冲过局部障碍。视觉Transformer和大规模分类模型很多依然沿用SGDMomentum配合Warmup和Cosine退火能达到非常好的收敛精度。SGD的另一个显著特征是它对新任务、小数据的适应力相对一般需要人来精心调节学习率、动量和正则化。当前大模型年代SGD在Transformer类结构上表现不如AdamW高效于是更多出现在中小规模CNN任务和部分强化学习场景中。它的核心使用技巧在于不要盲目用小学习率也不要一开始就用大学习率warmup阶段特别重要。2.2 Adam家族与自适应学习率Adam是目前应用范围最广的优化器几乎覆盖了文本、语音、图像生成、推荐系统等所有任务。它的核心思路是为一阶矩和二阶矩各维护一份指数移动平均m beta1 * m (1 - beta1) * grad v beta2 * v (1 - beta2) * grad^2 m_hat m / (1 - beta1^t) v_hat v / (1 - beta2^t) theta theta - lr * m_hat / (sqrt(v_hat) epsilon)beta1控制动量的衰减常规取0.9beta2控制梯度平方移动平均的衰减常规取0.999。epsilon是为了防止分母除零通常在1e-8量级。这套机制的妙处在于当某个参数持续收到较大的梯度时它的二阶矩会变大从而自动降低该参数的学习率当某个参数梯度很小时二阶矩也小学习率会相对放大。这正好解决了深度学习里不同参数更新尺度差异巨大的痛点。我用一个生活化类比来解释SGD像是一个按固定身高差迈步的人无论面前的路是平地还是悬崖都按同一个规则去迈腿。Adam则像是一个会根据路面起伏自行调整步伐的徒步者遇到陡坡自动缩小步子遇到缓坡自动加快节奏因此在未知地形上总能更快前进。但自适应步伐也会带来一个隐患在接近目标点时它仍然会因为历史方差较大而不肯缩小步幅导致最后难以精确落在最优点附近这就是Adam后期收敛不彻底的主要原因。2.3 新势力AdamW、LAMB与调度器协同AdamW是现在大模型训练的事实标准。它和Adam的核心区别在于权重衰减的处理方式Adam把L2正则的梯度直接加到总梯度中而AdamW将权重衰减从梯度计算中解耦在参数更新时单独做一次缩小。别小看这个改动很多实验证明AdamW在BERT、GPT等Transformer结构上的收敛效果和泛化性能都优于传统Adam尤其是配合较大的学习率和大batch训练时。LAMB是为大规模分布式训练设计的优化器在Adam的基础上增加了layer-wise自适应的学习率缩放。它解决的问题是在batch size几千甚至几万时直接套用Adam会导致部分层更新步长过大训练不稳定。LAMB逐层计算归一化因子让不同层的更新幅度保持一致。想跑超大批量预训练任务LAMB基本是绕不开的选择。从工程角度看优化器还需要与lr scheduler协同设计。比如Linear Warmup配合Cosine Annealing在前几步用很小的学习率防止早期梯度噪声过大后期缓慢降低学习率帮助模型收敛到更优的局部极小值。优化器与调度器的关系就像发动机和油门优化器决定动力特性调度器决定什么时候给油、给多大油。任何一方设置不当都会让整个训练过程白费。3. 实操配置手把手调好你的优化器3.1 学习率与初始化最重要的两个旋钮学习率可能是整个训练配置里影响最大的超参数。设置过大loss直接发散到NaN设置过小loss下降慢到让人怀疑人生。常见的初始学习率经验值如下表优化器类型常见初始学习率备注SGDMomentum0.01 ~ 0.1视觉CNN任务常用0.01配合warmupAdam1e-3 ~ 3e-4默认1e-3大多数任务可用小batch可适当减小AdamW1e-4 ~ 3e-4大模型预训练常用1e-4微调常用2e-5 ~ 5e-5LAMB1e-3 ~ 1e-2大批量场景需配合层间缩放使用我实测下来Adam/AdamW在Transformer类模型上微调阶段用3e-5左右比较稳妥而预训练阶段可以放到1e-4甚至更高。SGD在ImageNet级别的CNN分类任务上0.1配合warmup和cosine退火是最常见的基础配置但batch size变化时需要同步调整学习率。一个广泛使用的经验法则是batch size翻倍学习率大致也要跟着调整线性缩放或开方缩放均可但都必须配合warmup逐步过渡。优化器初始化也有讲究。Adam和AdamW的前几步更新受偏差校正影响较大如果训练步数很少或者学习率太大早期损失可能出现异常跳跃。我在实际项目中遇到过多次这种抖动后来统一在开始训练的前几百步使用warmup基本就消除了这类问题。特别提醒加载预训练权重继续训练时优化器状态动量、二阶矩等通常不会被恢复所以“加载权重后效果不如之前”不要总觉得是数据或模型的问题优化器state丢失也是一个重要变量。3.2 权重衰减与正则化别把优化器当摆设权重衰减是优化器配置里最容易被忽略但效果很稳定的一个参数。它的作用是让模型参数在每次更新时都朝着零的方向稍微收缩一点等价于L2正则化能有效抑制过大的权重值从而提升泛化能力。Adam和AdamW虽然都支持weight_decay参数但实现方式有本质区别这个差异在长时间训练、大规模模型上会被放大得非常明显。我在一次BERT下游任务微调中做过对比同样的数据和配置使用Adam时weight_decay从0.01调到0.1效果不升反降而切换为AdamW后weight_decay设为0.1时效果反而更好。原因是Adam把权重衰减和梯度混在一起后二阶矩会干扰衰减的力度导致正则效果不稳定。AdamW解耦之后weight_decay的幅度可以独立调节这个参数的作用就变得可预期了。实际配置中Transformer模型一般把weight_decay设置在0.01到0.1之间CNN模型通常设置在1e-4到5e-4量级具体需要结合模型规模和正则需求调整。要注意的一点是weight_decay不是越大越好过大参数被压得太小模型的表达能力会被削弱甚至出现欠拟合现象。它的作用更像是一个安全带防止模型跑到过拟合的悬崖边但安全带绑得太紧也会影响行动自由。3.3 学习率调度的配合策略优化器本身管的是参数怎么更新学习率调度器管的是学习率怎么变化。两者必须配合使用才有好的效果。我常用的几种调度策略包括StepLR每隔固定epoch将学习率乘以一个衰减系数比如每30个epoch乘以0.1。这个策略简单直接适合任务比较稳定、收敛节奏明确的场景。早年CV任务非常依赖StepLR现在我用得少了一些因为decay的节点选择比较费人工。CosineAnnealingLR按照余弦曲线把学习率从初始值逐渐降到接近零。这个策略在视觉Transformer和大模型训练中特别受欢迎因为它天然包含了“前期快速探索、后期精细收敛”的节奏几乎不需要手动选择衰减节点。实际训练中我会配一个warmup阶段前几百步从接近零的学习率线性升到目标值之后进入余弦退火阶段。LinearWarmup加LinearDecay在大规模预训练任务里非常常见。学习率先线性升到峰值再线性降到接近零。这个策略的好处是节奏容易控制也方便和分布式训练、梯度裁剪一起配合。调度策略的选择和优化器类型没有强绑定关系但存在一些常见组合倾向性。SGD、大批量训练更适合带warmup的调度策略因为SGD对前期学习率误差的容忍度较低Adam类优化器配合warmup时可以明显改善早期loss波动问题。我的原则是训练步数短、任务规模小时直接固定学习率训练步数中等时用Cosine或者Step大规模预训练或者Fine-tune时用Warmup加Decay的组合。4. 常见问题与排查训练不收敛时先别慌4.1 loss震荡不下降的排查清单训练过程中最让人头疼的就是loss曲线像心电图上下来回跳怎么等都不下降。这种情况我在实际项目中碰到过很多次排查的顺序基本是固定的。首先确认优化器配置是否正确。很多人直接从别的代码仓库复制optimizer参数却不知道那个仓库训练的是不同模型、不同数据集学习率和weight_decay根本不匹配。我见过最经典的一个问题是从ImageNet分类仓库拷贝SGD配置去训练一个全新的目标检测任务结果学习率高了整个数量级loss直接飞上太空。遇到训练不稳定第一步永远是把学习率降一个数量级试一下排除基础配置问题。其次检查数据管道。如果数据预处理出错导致标签错乱或者输入数据尺度异常任何优化器都救不回来。我曾经用Adam训练一个回归模型时一直出现loss抖动排查很久才发现是训练集里混入了传感器故障数据个别样本的label是正常值的几千倍。第三是模型自身结构的问题。梯度消失或者爆炸会导致优化器收到的梯度信号失真这时候优化器调参效果有限需要重点检查网络结构、激活函数和初始化方式。残差连接、BatchNorm/LayerNorm、合理的初始化策略都是解决这类问题的关键手段。如果loss还是抖动可以使用梯度裁剪限制更新步长这也是大模型训练中常用的防爆措施。4.2 收敛太慢与过拟合并存的处理模型的loss下降速度没达到预期时先检查学习率是否偏低再检查优化器选型是否匹配任务。比如小数据集上的Transformer微调用SGD可能几十个epoch都看不到明显进展换AdamW结合3e-5学习率基本几个epoch就能见效。如果优化器配置没问题却仍然收敛极慢可能是梯度信息本身不够有效这时需要从模型结构、数据增强、训练目标多个层面去优化。另一种更隐蔽的情况是训练集loss不断下降但验证集loss不降反升也就是过拟合。这时优化器方面的应对手段主要有两个方向一是增加weight_decay二是配合early stopping选择最优模型。很多文献里推荐做大模型任务的时候多关注验证集指标而非训练集loss就是这个道理。我自己的经验是过拟合严重的时候优先调整weight_decay而不是盲目加数据增强因为数据增强改的是数据分布可能影响下游任务效果而weight_decay只约束模型复杂度一般不会改变任务语义。从工程角度看还有一个容易忽略的点optimizer的构建应该在加载模型之后并且使用模型参数作为构建输入。否则模型结构变了optimizer的参数量对不上加载checkpoint时会出现无法匹配的state_dict错误。很多人踩过这个坑后就开始在每个训练脚本里写断言确保优化器参数数量和模型参数数量一致这确实是一个值得养成的好习惯。4.3 混合精度与大规模并行下的优化器注意事项现代训练基本离不开混合精度和分布式训练这两者对优化器有额外要求。混合精度训练时模型参数和优化器状态通常以FP32存储而前向和反向计算用FP16或BF16完成如果在优化器这一步没有保留FP32的master copy梯度缩放过小或者出现溢出参数更新就会出错。实际表现是loss在某个step突然变为NaN且无法自动恢复。分布式训练中常用的优化器封装包括ZeroRedundancyOptimizer和DeepSpeed的ZeRO系列它们会把优化器状态分片切分到不同GPU上减少显存占用。使用这些方案时要注意learning rate可能需要配合梯度累积步数调整因为梯度累积相当于增大了有效batch size学习率不调整可能造成训练不稳定。我在多机多卡训练时习惯将batch size、学习率和warmup步数一起调整保持了训练节奏的稳定。还有一个实操细节是设置grad_clip。梯度裁剪是一个防爆手段不是解决所有问题的万能钥匙。我把grad_clip当作训练稳定的辅助工具一般设为1.0左右配合AdamW使用在大模型微调和预训练中既能防止单步异常爆炸又不影响正常的收敛速度。如果发现即使设置了grad_clip仍然loss飞升这时要检查的就不是优化器而是前向计算里的数值稳定性了。5. 实战复盘完整对比SGD与AdamW的一次训练记录5.1 实验设定与训练细节当初在开发一套基于视觉Transformer的图像分类模型时我正好对优化器选型做了一次比较完整的对比实验。模型参数量约8600万数据集是自建的大规模商品图像集训练集约120万张验证集约5万张类别数640类。硬件环境是8张A100总batch设成1024训练总步数规划为60个epoch。A组用SGDMomentum初始学习率0.1momentum 0.9weight_decay 1e-4warmup 5个epoch后采用cosine退火B组用AdamW初始学习率2e-3weight_decay 0.05同样的warmup和cosine策略C组用LAMB初始学习率6e-3weight_decay 0.01。三组都使用相同的数据增强、模型结构和损失函数唯一变量就是优化器及配套的超参数设置。为保证公平性三组都使用同样的随机种子和checkpoint保存逻辑从零开始训练。训练日志记录显示前三轮epoch中C组收敛最快B组紧随其后A组最慢这个阶段的结果基本符合预期。但到了第30个epoch之后A组的学习率随cosine退火逐渐降低验证集准确率开始稳步超越B组和C组。最终在60个epoch结束时A组top-1准确率为83.7%B组为83.1%C组为82.9%。训练前期表现最平淡的SGD反而是最终精度最高的方案。5.2 实战复盘带给我的选型心得这次实验给我最大的启发是优化器的选择不能只看训练初期的表现必须综合考量总训练时长、资源成本和目标精度。在资源充足、训练轮次多的情况下SGD依然有竞争力在训练资源有限、需要在尽量少的step里达到不错效果时AdamW是更稳妥的选择。如果任务是大batch超大模型预训练LAMB几乎是必选项因为它能把大批量和稳定收敛兼得。实际场景中我会遵循以下选型思路小模型小数据试错期直接用Adam或AdamW快速迭代中大型视觉模型有足够训练预算SGDMomentum可以冲最好精度尤其是CNN结构Transformer结构、需要微调的任务用AdamW配合适当weight_decay大规模预训练或者batch大得离谱时LAMB是优先方案。选型建议整理到一个小的参考表格中任务场景优先优化器核心理由快速验证/小模型Adam/AdamW对超参数不敏感上手快视觉CNN最终精调SGDMomentum泛化性好可冲更高精度Transformer预训练/微调AdamW与权重衰减解耦适配自注意力结构超大batch分布式训练LAMB层间学习率归一化训练稳定这套经验之后基本成了我的训练标配参考。每次开始一个新项目我先根据任务类型选定优化器再根据batch size和训练步数设定学习率和调度策略。不盲从不迷信用实验数据说话这样训练出来的模型在各种任务中都比较扎实。5.3 踩过的坑与优化器调试清单复盘这些训练实验时我整理了一份优化器调试清单每一步都是从真实问题中提炼出来的。第一个坑是warmup步数设置不合理。warmup太短模型预热不足初始阶段loss会跳动warmup太长训练总步数只有一两千步时大部分时间浪费在了低学习率阶段收敛效率极差。一般warmup设为总步数的5%到10%大规模预训练可以适当延长但要结合总步数做估算。第二个坑是batch size改动了却没有同步调整学习率和weight_decay。batch size从256升到1024时梯度噪声变小可以考虑调高学习率但weight_decay的相对强度也发生了变化代价是需要重新测试。我通常把优化器配置和训练配置解耦统一在配置文件中用常量定义每次改动都留下记录方便回溯。第三个容易被忽略的问题是优化器state dict与模型checkpoint的保存逻辑。保存时如果只保存model权重而不保存optimizer的state恢复训练时就只能重新从头warmup前面几十个step的学习率节奏全部打乱如果这时还是低学习率阶段甚至会直接导致loss异常。所以checkpoint必须同时保存model、optimizer、scheduler和当前step数这一点无论用什么优化器都一样重要。从我做的这些实验来看没有哪个优化器在所有场景下都能保证最佳效果。与其花大量精力追捧所谓的“最强优化器”不如花一些时间理解不同类型优化器的内在逻辑然后针对自己的模型和数据特点做合理选择。我做训练配置时最重视的始终是这四件事优化器类型、学习率、weight_decay、调度器策略。把它们组合好再加上正确保存和读取checkpoint的能力训练基本不会出太大的问题。最后分享一个小习惯准备一个训练日志看板把优化器、学习率、warmup、weight_decay、batch size、梯度裁剪这些变量全部记录下来。每次实验之前先对照看板检查一遍配置。这个习惯帮我避免了很多次因为复制旧配置忘记修改而导致的无效训练也让我在排查问题时能准确回溯每一个影响训练结果的变量。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。