资讯动态

batch size决定优化器选型:从Adam到SGD的实操逻辑与配置

发布时间:2026/10/17 18:04:25 来源:尧图企业网站定制
开头先聊一个我经常在社区里看到的问题“哪个优化器最好”刚入行那会儿我也到处翻榜单、跑对比实验总想找到一个对所有模型都灵的答案。后来模型训得多了我发现这个问题本身就不成立。真正决定优化器选型的往往是一个被你忽略的变量——batch size。同一个任务batch size 从 16 换到 256SGD 和 Adam 的表现可能完全对调。这篇文章我就从 batch size 这个“第一变量”出发把优化器选型背后的逻辑、实操参数和常见坑一次说清楚适合正在调模型、想搞懂优化器本质的工程师和数据科学同学。1. 为什么说 batch size 才是决定优化器的“第一问变量”1.1 梯度噪声batch size 直接影响优化器看到的“路况”深度学习的每一步训练都要靠当前 batch 的梯度来近似整个训练集上的真实梯度。这个近似过程天然有噪声而噪声的尺度大致和 batch size 的平方根成反比。batch size 越小每个 batch 之间的梯度方向越抖就像你在山路上打着远光灯开车只能看清前面一小段方向稍微偏一点就可能被带进沟里。batch size 越大梯度方向越平滑像白天开着车灯看清整条公路路况完全不一样。这个差异直接影响优化器的“走法”。SGD 类的优化器只看当前梯度方向更新量就是学习率乘以梯度对梯度噪声非常敏感。小 batch 下如果学习率调不好loss 曲线会像心电图一样剧烈跳动甚至根本收敛不下去。Adam 这类自适应优化器则会对每个维度的梯度幅度做归一化相当于给每一步更新套了一层“变速器”即使梯度方向抖它也能按参数尺度调整步长所以小 batch 下容错率高很多。我自己的感受是很多“优化器对比”文章翻车就是因为大家默认用一个固定的 batch size 跑所有实验。batch size 一换梯度噪声的统计特性就变了优化器的相对优劣自然也会变。这个前提不统一所有对比结论都没有意义。1.2 学习率缩放与训练动态的连锁反应batch size 变了不只是噪声变了整个训练动态都跟着变。一个经典做法是线性缩放规则batch size 翻倍学习率也大致翻倍这样才能让每个 epoch 里参数更新的“总幅度”保持相近。但这条规则在 SGD 和 Adam 上的适用程度完全不同。SGD 的更新量正比于梯度本身学习率翻倍直接等效于梯度放大两倍线性缩放很自然。Adam 的更新量里学习率是被二阶矩归一化后使用的学习率翻倍并不等于梯度翻倍的效果因为分母的均方根统计量也参与计算。换句话说你在小 batch 下调好的 Adam 学习率直接搬到 4 倍 batch size 上既不能照抄原来的值也不能简单翻倍得重新试。所以“先问 batch size”不是一句口号而是因为 batch size 通过两条路径影响优化器选择一是梯度噪声水平二是学习率与更新步长的匹配逻辑。这两条路径共同决定了哪个优化器在你的场景下更省心。1.3 泛化性能的隐藏杠杆还有一个更隐蔽的因素优化器和 batch size 的组合会影响模型最终泛化能力而不只是训练速度。大 batch size 的梯度更准确每个 step 对训练集的拟合效率更高但经验上大 batch 训练出的模型在验证集上的表现经常比不上小 batch。原因有很多说法主流解释是大 batch 倾向于收敛到损失面中“尖锐”的极小值而小 batch 因为梯度噪声大反而像在探索更宽更平的谷底泛化更稳。这个现象在优化器选择上也有体现。SGD 配合大 batch 时常用的做法是加大 weight decay、加学习率 warmup把模型推向更平缓的区域。Adam 在小 batch 下天然对噪声有鲁棒性但如果你的 batch size 本身不够大它的自适应步长又可能在后期让参数在极小值附近来回震荡泛化能力受到限制。也就是说batch size 和优化器是“合伙”决定训练轨迹的。只看优化器榜单不看 batch size等于只看菜谱却不看灶台的火力。2. batch size 落进哪个区间就该选哪类优化器2.1 小 batch2~16Adam 系是压倒性主力小 batch 场景最典型的是显存受限、只能一次性喂很少样本的视觉模型或者某些超大 embedding 模型。2~16 个样本的梯度噪声非常大方向信息基本被噪声淹没这时候 SGD 类优化器基本没法用学习率必须压得极低收敛速度慢到你怀疑人生。Adam 类优化器尤其是 AdamW在小 batch 下优势非常明显。它用一阶矩估计动量、二阶矩估计梯度尺度再对所有参数做归一化更新相当于给每个参数单独配了一个自适应学习率。即使某个 batch 的梯度在个别维度上异常大或异常小更新步长也不会被带飞。我的经验值是在 batch size 16 以下直接选 AdamW初始学习率放在 1e-4 到 3e-4 之间weight decay 按任务设 0.01 到 0.05大多数情况下都能比较稳地跑起来。如果你在小 batch 下偏要用 SGD那就得做好学习率网格搜索的准备比如从 1e-4 往下调好几个量级还得靠耐心。2.2 中 batch32~128AdamW、RMSProp、SGD 都能跑分任务看32 到 128 是最常见的炼丹区间也是优化器选择最纠结的区间。这个 batch size 下梯度噪声已经明显下降SGD 加动量开始有生存空间但 Adam 的稳定性依然诱人。到底选谁我的经验是看任务类型。如果做 NLP 里的 Transformer 类模型比如各项语言模型标配就是 AdamW理由有两个一是这类模型参数尺度差异极大embedding 层和 attention 层梯度的量级完全不一样归一化更新很必要二是行业内大量预训练和微调实践都建立在 AdamW 上数值表现更稳定。如果做计算机视觉的分类检测任务SGD 加 Momentum 也经常在中 batch 区间表现很好甚至泛化效果更优但它的学习率和 momentum 参数需要仔细调。我通常的中 batch 策略是先跑几个 step 对比 AdamW 和 SGDMomentum 的 loss 下降速度看哪个在不动学习率的情况下更稳。两个都能收敛的情况下优先选训练起来更稳的那个因为省下来的是你的调参时间。2.3 大 batch256 以上SGD 加 Momentum 强势回归batch size 超过 256 以后梯度方向已经很可靠了Adam 的“自适应步长”反而变成一种限制。它会把不同参数的梯度都归一化到差不多的量级相当于丢掉了梯度大小的信息在大 batch 这种梯度质量很高的场景下有点杀鸡用牛刀。SGD 加 Momentum 此时表现得往往更直接梯度准确步长由学习率和动量共同控制更新方向更干净配合合适的 learning rate schedule泛化性能通常更好。我印象很深的一次实践是一个视觉模型从 batch size 64 切到 512AdamW 怎么调 weight decay 和 warmup验证集分数都上不去换成 SGD Momentum、配 cosine 学习率衰减几个 epoch 之后效果就明显改善。大 batch 下如果显存不够很多人会选择梯度累积来“模拟”大 batch这也是常规操作。但要注意梯度累积只是累加梯度不会改变每个 step 的噪声分布和真正的大 batch 还是不完全等价。优化器选型逻辑依然要按你“实际参与更新计算的 batch size”来。下面是我按 batch size 区间整理的一份速查表纯经验值参数仍需按任务微调batch size 区间首选优化器备选优化器初始学习率参考典型场景2~16Adam / AdamW无勉强可选 AdaFactor1e-4 ~ 3e-4超大模型微调、显存受限实验32~128AdamWSGDMomentum、RMSProp1e-4 ~ 1e-3中规模视觉分类、NLP 微调256~1024SGDMomentumAdamW需多调 weight decay0.1 ~ 0.3配合 schedule大规模视觉训练、图像分类1024SGDMomentum 或 Layer-wise Adaptive 类方法不建议直接用 Adam0.1 以上 warmup大规模分布式训练、巨型 batch3. 常用优化器的机制差异为什么没有一个“全能的 Adam”3.1 从随机梯度下降到自适应矩估计很多同学对优化器的理解停留在“SGD 是古董Adam 是神器”这个层面但实际不是这样。SGD 的更新公式最简单就是沿着当前 batch 的负梯度方向走一步你可以把它想象成瞎子下山全靠脚下试探。Momentum 是给 SGD 加了一个“惯性”既保留历史梯度方向又能抵消一部分噪声带来的抖动在小 batch 和大 batch 下都比纯 SGD 稳。RMSProp 的核心是给每个参数维护一个梯度平方的滑动平均然后用它去缩放当前梯度相当于对不同方向的踏出距离做归一化。Adam 在 RMSProp 的基础上又加了动量同时维护一阶矩估计和二阶矩估计再在更新步长里做偏差修正所以收敛速度在很多任务上非常快。但要注意Adam 的“自适应”是抽象出来的特性它非常依赖一阶矩和二阶矩的初始估计。训练刚开始时矩估计样本少偏差大所以需要 bias correction 机制来修正这也是为什么 Adam 的公式比 SGD 复杂一截。生活化地理解Adam 就像一个刚入职的导航员起步阶段需要校准手势确定了参照系之后才开始高效指路。3.2 二阶矩归一化的隐形成本Adam 能成为默认选择最大的贡献是解决了“学习率怎么调”的痛点但它的代价被很多人忽视了。二阶矩归一化让每个参数的更新步长和梯度大小脱钩带来一个副作用大梯度方向的信息被压制了。在梯度本身很可靠的大 batch 场景这种压制会让参数往最优点的推进变慢甚至让优化过程错过一些真正重要的大梯度方向。另一个常见问题是Adam 在训练后期容易在极小值附近震荡因为更新步长只由学习率乘以矩估计的比值决定而矩估计在后期趋于稳定不会像 SGD 那样随着梯度收敛自然变小。这也是为什么很多炼丹老手常说Adam 前期好使后期看着 loss 降不动换成 SGD 微调反而能再榨出几个点的效果。我不是说 Adam 不好而是说它适合它擅长的问题在 batch size、任务类型、训练阶段都明确后才能判断它是不是最优解。所谓“最好”的优化器只存在于特定前置条件下。3.3 新优化器层出不穷但底层逻辑还是那两种近些年不断有新的优化器被提出比如各种自适应变体、带重启的变体、分层学习率方案。看着眼花缭乱但底层绝大多数还是沿着两条路线一条是从 SGD 出发加动量、加调度另一条是从 RMSProp/Adam 出发做矩估计、做修正、做解耦。它们的差异点基本集中在“如何利用历史梯度信息”和“如何调整每个参数的步长”这两个维度而这恰恰是 batch size 敏感的内容。所以我的选型观很朴素新优化器先看它讨论的预设条件是什么比如论文里的 batch size 是多大、任务是什么、有没有在大 batch 上验证过。如果预设条件和你的场景不一致榜单上的漂亮结果对你没有参考意义。这比追着最新优化器跑要靠谱得多。4. 实操配置从 batch size 出发的完整参数清单4.1 用 batch size 推算初始学习率参数配置里最容易被 batch size 影响的就是学习率。对于 SGD 加 Momentum线性缩放规则是一个不错的起点。基准场景我常用 batch size 128学习率 0.1如果你的 batch size 是 512就初步换算为 0.4。但我不建议一步到位最好先按这个规则算一个上限再用小几个批次的实际 loss 曲线验证一次run 三五十个 steps看 loss 是否稳定下降、有没有剧烈震荡再一点点把学习率调到位。对于 Adam 系线性缩放规则不严格适用。因为更新量经过二阶矩归一化后学习率的物理含义变成了“每步更新占参数尺度的比例”而不是单纯的梯度放大倍数。我的经验是batch size 从 64 增到 256 时Adam 学习率最多提升一倍就可以不要按照 SGD 的线性规则去翻倍。否则容易出现一开始 loss 像坐过山车后面怎么拉都拉不回来的情况。4.2 Momentum、weight decay 与 schedule 的配套调整优化器本身只是骨架配套参数才是血肉。SGD 加 Momentum 场景下momentum 固定在 0.9 是标准选择但大 batch 时要配合 warmup。warmup 的作用是让一开始统计信息还不准的 BN 层或矩估计先“热身”一两个 epoch避免前几步就冲到损失面的高风险区。我的做法是前 5 个 epoch 线性增长学习率之后切换 cosine 衰减这个组合在视觉任务上实测很稳。weight decay 的设置也和 batch size 有关系。大 batch 训练出的模型容易走向尖锐极小值我通常会把 weight decay 从默认的 1e-4 往上调比如 5e-4 或 1e-3相当于给参数上了更重的正则化约束帮助模型落到平缓区域。小 batch 下 weight decay 不建议开大因为梯度噪声本身就是天然正则化weight decay 再大会让模型欠拟合。下面是一份我常用的优化器配置模板PyTorch 风格可以当作起点改# 小 batch / 中 batch默认先试 AdamW optimizer torch.optim.AdamW( model.parameters(), lr1e-4, # batch_size 16 时用 1e-4~3e-4 betas(0.9, 0.999), eps1e-8, weight_decay0.01 ) # 大 batch / 训练后期微调用 SGD Momentum optimizer torch.optim.SGD( model.parameters(), lr0.1, # batch_size 256 时的起点按 linear scaling 调整 momentum0.9, weight_decay5e-4, nesterovTrue )4.3 工程环境下的配套注意点除优化器参数batch size 还会影响 BN 层和分布式训练配置。如果你用大 batch比如单卡只能 support 64但想凑 512可以用梯度累积凑数具体做法是每 8 个 step 更新一次参数等效于 batch size 512。注意此时 learning rate schedule 要基于实际更新次数来算不能按总样本数算否则 warmup 和 cosine 衰减的节奏会错位。另一种方案是用同步 BN尤其在分割、检测这类对 batch 统计量敏感的任务里。小 batch 下 BN 的均值和方差噪声大得吓人一个简单替换是用 GroupNorm 或 LayerNorm 代替 BN能明显缓解不稳定的问题。优化器这边不需要额外改动但模型前向统计特性变了loss 曲线的表现也会随 batch size 一起改变。踩过这个坑之后我都建议先确认模型里的归一化层类型再决定优化器怎么调两个配置是一套组合拳。5. 常见问题与排查技巧实录5.1 换了 batch size 之后 loss 直接爆炸这是最典型的问题。很多同学 copy 一份原来的训练脚本只改了 batch size其他不动然后发现 loss 要么飞上天要么 NaN。原因基本都在学习率没有配套调整batch size 变大有效梯度累积更平滑原来的学习率直接套过来更新步长相对变大就会震荡batch size 变小梯度噪声更烈原来的学习率又显得太大也容易炸。排查步骤我是这么做的先把学习率降到原来的十分之一跑 50 个 steps看 loss 是否稳住。如果稳住了再按线性缩放规则或经验值逐步回调。千万不要一上来就网格搜索先用小范围 run 几个步骤成本低得多。另外顺手检查一下 loss 是不是出现了 NaN如果有优先检查输入数据和混合精度设置很多时候和优化器关系不大。5.2 大 batch 训不动loss 降不下去大 batch 下遇到瓶颈很多人第一反应是优化器不够好换了新优化器也一样其实可能是“优化器正则化学习率调度”组合没到位。我遇到过的情况是训练集 loss 降得很好验证集分上不去这是典型的尖锐极小值问题另一种是训练集 loss 都降不下去这时候要考虑是不是 warmup 不够、学习率太低或者 BN 统计量在大 batch 下漂移。我的建议顺序是先把 weight decay 调大一个量级然后把学习率 schedule 换成 warmupcosine最后再考虑优化器切换。这一步做了很多实际问题已经解决了。如果还不行再换成 SGD 加 Momentum注意 momentum 保持 0.9 不变只动 lr。有一些任务确实 Adam 怎么调都上不去但这不一定代表 SGD 更好可能是你 Adam 的 weight decay 和 warmup 没配对。5.3 小 batch 精度震荡验证集上下乱跳小 batch 最常见的表现是loss 曲线能降到区域但精度一直在震荡不收敛。这时候我把优化器从 SGD 换成 Adam常常立刻奏效如果已经在用 Adam就下调学习率并考虑增加学习率 warmup 的步数给模型足够的“定方向”时间。另外小 batch 下的 BN 也是震荡来源可以试试把 BN 换成 GroupNorm或增大 batch 到 32 以上后用同步 BN。还有一个容易被忽略的细节数据加载顺序的 shuffle 策略。batch size 很小时如果数据 not shuffled 得足够随机相邻 batch 的分布偏差会被放大叠加梯度噪声训练曲线就会明显抖动。我建议小 batch 场景刻意开启完整的 shuffle并设置好随机种子否则你会误以为是优化器的问题白调好几天。下面把常见问题整理成速查表方便你直接对着排查现象首要怀疑点快速处置增大 batch 后 loss 爆炸学习率未按缩放调整学习率降为原值 1/10先跑稳再回调减小 batch 后不收敛、震荡噪声变大、BN 统计量抖动换 AdamW、降 lr、检查 BN/GN大 batch 验证集分数低尖锐极小值、正则不足加大 weight decay、开 warmupcosineloss 曲线稳定但训练集 loss 高位不动warmup 不足或 lr 太低适当提高 lr 上限延长 warmup精度震荡且方向随机shuffle 不充分或噪声过大修数据加载保证 shuffle 完整、种子固定任何优化器都跑不动先查数据输入和数值稳定性检查 NaN、Inf、归一化层、混合精度配置我自己踩坑最多的地方是在这里一开始总想着对比优化器的“榜单”后来发现榜单上的实验条件和我手头的任务完全不是一回事。先明确 batch size再选优化器这句话听起来朴素但确实是不少调参问题的解药。如果只能留一个建议那就是改 batch size 的时候永远记得把优化器配置和训练节奏一起复核一遍不要只动一个变量。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑