AI概念与词典

梯度下降是什么?公式、学习率、批量差异与排错实验

用可复算线性回归例子解释梯度下降,区分损失、反向传播、优化器、Batch/SGD/mini-batch,给出学习率实验台账及不收敛、发散和NaN排错矩阵。

梯度下降从计算损失、求梯度、乘学习率到更新参数并重新评估的闭环
本页目录
  1. 梯度下降的公式怎么读
  2. 损失、梯度、反向传播和优化器怎样分工?
  3. 一个可复算的线性回归例子
  4. Batch、SGD 与 mini-batch 有什么区别
  5. epoch、batch、step 和梯度累积怎么换算?
  6. 学习率为什么最容易出问题
  7. 怎样设计一组不会互相污染的学习率实验?
  8. 训练前怎样验证梯度实现没有错?
  9. 训练不收敛时怎么排查
  10. 训练曲线应该同时记录哪些信号?
  11. 怎样保存一个可以恢复和复核的训练运行?
  12. 训练什么时候应该停止?
  13. 常见误区
  14. 沿负梯度一定能找到全局最小值吗?
  15. 损失每一步都必须下降吗?
  16. Adam 取代梯度下降了吗?
  17. 最小 PyTorch 训练循环
  18. 资料来源与复核范围

一句话定义:梯度下降(Gradient Descent)是一类迭代优化方法:先计算目标函数对参数的梯度,再沿负梯度方向更新参数,希望逐步降低损失。它回答的是“参数下一步往哪里、走多远”,不是一个保证所有模型都找到全局最优解的魔法公式。

梯度下降从损失函数、梯度、学习率到参数更新和重新计算损失的闭环
每一步都由方向(梯度)和步长(学习率)共同决定;更新后必须重新计算损失。图:兰塞 AI 原创。

梯度下降的公式怎么读

设模型参数为 θ,损失函数为 J(θ),学习率为 η,那么一次最基本的更新可以写成:

θ_next = θ_current − η × ∇J(θ_current)

  • θ:模型要学习的参数,例如线性回归的权重和偏置。
  • J(θ):衡量预测与目标差异的损失函数;损失的定义必须与任务目标和输出形式匹配。
  • ∇J(θ):损失对各参数的偏导数组成的向量,指向局部增长最快的方向。
  • η:学习率,控制更新幅度;它是训练前设定的超参数,不是模型自动学出的权重。

负号表示朝局部下降方向移动。多层神经网络通常通过反向传播高效计算梯度,再由优化器更新参数。反向传播负责“算梯度”,梯度下降及其变体负责“用梯度改参数”,两者不是同一个概念。

损失、梯度、反向传播和优化器怎样分工?

概念 回答的问题 产生什么 常见误解
模型前向计算 给定输入和参数,预测是什么 预测值与中间激活 前向完成不代表参数已经学习
损失函数 预测与目标差多少 通常是可求导的标量 损失值不是梯度,也不等于业务指标
反向传播/自动微分 损失对每个参数怎样变化 参数梯度 只计算梯度,不自动保证更新正确
优化器 怎样结合梯度、动量和状态更新参数 新参数和优化器状态 Adam、AdamW 仍然使用梯度
学习率日程 不同训练阶段走多大一步 每一步实际学习率 配置初始值不等于全程恒定

PyTorch 的Autograd 文档说明 backward() 会把梯度累积到参数的 .grad清零梯度教程因此强调在新的累积阶段重置梯度。若忘记清零,你得到的不是当前 batch 独立梯度,而是未明确设计的多次累积。

一个可复算的线性回归例子

假设模型只有一个参数 w,预测为 ŷ = w × x。训练样本是 x=2、真实值 y=6,损失取平方误差 J(w)=(2w−6)²。当 w=1 时,损失为 16;损失对 w 的导数是 4(2w−6),此时梯度为 −16。

若学习率 η=0.05,则下一步 w = 1 − 0.05×(−16) = 1.8。新损失变为 (3.6−6)²=5.76,确实下降了。这个例子只说明当前一步有效;真实训练仍要持续监控验证集、数值稳定性和停止条件。

代入值 结果 检查
预测 1×2 2 比真实值 6 小
初始损失 (2−6)² 16 平方误差非负
梯度 4(2×1−6) −16 负梯度意味着增大 w 可下降
更新 1−0.05×(−16) 1.8 负负得正,w 增大
更新后损失 (2×1.8−6)² 5.76 低于 16,本步通过

还可以用中心差分做数值梯度检查:选择很小的 ε,比较 [J(w+ε)−J(w−ε)]/(2ε) 与解析/自动微分梯度。两者在合理误差内一致,只说明局部求导实现可信;不能证明数据、损失定义或整个训练流程正确。

Batch、SGD 与 mini-batch 有什么区别

方式 一次更新使用的数据 主要特点 常见适用场景
全批量梯度下降 整个训练集 方向较稳定,但单步成本高 小数据集、凸优化教学
随机梯度下降(严格定义) 1 个样本 更新频繁、噪声大 在线学习或概念说明
小批量 SGD 一小批样本 吞吐、显存与梯度噪声的折中 现代深度学习训练

日常工程交流里的“SGD”有时泛指小批量随机梯度训练,也可能特指某个优化器实现,阅读文档时要确认语境。Google 的机器学习课程明确区分 full batch、单样本 SGD 与 mini-batch;PyTorch 的 torch.optim.SGD 还可配置 momentum、weight decay 和 Nesterov。需要比较 SGD、AdamW、Muon 和权重衰减时,可继续阅读已完成编辑复核的深度学习优化器选择与调参指南

批量大小也不是越大越好。增大批量通常能降低单次梯度估计的随机波动并提高硬件利用率,但会占用更多显存,而且每个 epoch 的参数更新次数会减少。改变批量大小后,学习率、训练步数和评估频率都可能需要重新设定。因此,比较两个实验时应报告实际更新步数,而不能只比较 epoch 数或墙钟时间。

epoch、batch、step 和梯度累积怎么换算?

batch 是一次前向/反向所处理的一组样本;step 通常指优化器实际执行一次参数更新;epoch 表示训练流程大致遍历一遍数据集。若数据集有 N 个样本、每个 batch 有 B 个样本且不丢弃尾批,那么每个 epoch 约有 ceil(N/B) 个 batch,但实际更新次数还会受到分布式并行、梯度累积和跳过异常 batch 的影响。

梯度累积 K 个 micro-batch 后才调用一次 optimizer.step() 时,有效 batch 大致是“单卡 micro-batch × 累积步数 × 数据并行进程数”,但前提是损失缩放方式正确。此时日志里的“iteration”可能按 micro-batch 增长,而参数只每 K 次更新一次;如果把二者混为一谈,学习率日程、warmup 和评估点都会错位。

  • 比较收敛:至少同时报告看过的样本数、参数更新步数和最终验证指标。
  • 比较速度:区分每秒样本、每秒更新、首轮编译开销和端到端墙钟时间。
  • 比较显存:记录 micro-batch、累积步数、激活检查点和混合精度,而不是只写“batch=128”。
  • 比较学习率:说明它按每次参数更新还是按每个 epoch 调整,并保存实际学习率曲线。

所以“训练了 10 个 epoch”并不足以复现实验。两次运行即使 epoch 相同,只要数据过滤、batch、累积或分布式规模不同,参数实际更新次数和看到的样本顺序就可能完全不同。交接记录应同时保存数据样本数、有效 batch、总更新步数、评估间隔和最后一个实际学习率,不能只留一张损失曲线截图作为证据链。

学习率为什么最容易出问题

学习率太小,参数每次只移动一点,训练损失下降缓慢;学习率太大,更新可能跨过低损失区域,在两侧振荡甚至让损失快速增大。Google 的交互练习展示了同一问题在不同学习率下出现缓慢收敛、合理收敛和发散,说明不存在对所有数据与模型都通用的固定值。

更可靠的做法是同时记录训练损失、验证损失、梯度范数和学习率,并把首次试验当成可比较基线。学习率调度、warmup、梯度裁剪或换用带动量/自适应方法都可能有帮助,但它们不能替代数据检查。需要继续补齐术语关系,可从AI 概念专题进入已复核页面;准备把训练步骤落成完整实践时,可转到AI 教程专题

怎样设计一组不会互相污染的学习率实验?

固定数据版本、划分、预处理、模型初始化、损失、批量和更新步数,只改变学习率。每个候选至少运行多个随机种子,并保留失败运行;若同时改了模型、批量和优化器,即使结果改善也不能归因于学习率。

梯度下降实验固定数据模型损失随机性和预算只改变一个变量并记录完整日志
可复现结论需要固定条件、单一变量、相同预算和完整日志,而不是只截图最好的一条曲线。图:兰塞 AI 原创。
阶段 固定项 本轮变量 必须记录
小数据过拟合 极小样本、模型、损失 先不做大范围调参 能否把训练损失压到预期范围
学习率扫描 批量、初始化种子、更新步数 例如按 10 倍数量级比较 训练/验证损失、梯度范数、NaN
局部细化 候选区间和全部数据流程 更密的学习率点 多个种子的中位数与最差运行
批量对照 数据样本预算与评估点 批量大小 实际更新步数、吞吐、峰值显存
最终复现 冻结配置与代码版本 只换随机种子 均值、离散度、检查点和环境

训练前怎样验证梯度实现没有错?

正式扫学习率之前,先做一个成本很低的“梯度正确性最小实验”。它的目的不是证明模型有效,而是把数据管线、计算图、求导和参数更新分层验证。若最小实验都失败,继续增加训练轮数、换优化器或扩大数据只会让问题更难定位。

最小检查 具体做法 通过信号 仍不能证明什么
有限差分梯度检查 在小尺寸、双精度、确定性输入上,用中心差分与自动微分梯度比较 误差落在为该函数设定的容差内 不能证明损失定义符合业务目标
单 batch 过拟合 关闭强数据增强,只反复训练一个很小 batch 训练损失能明显下降,参数确实变化 不能证明泛化,也不能证明完整数据无错
参数差分 step() 前后记录每层参数更新范数 应训练参数发生有限、非零更新 不能证明更新方向长期有效
计算图连通性 检查关键参数梯度是 None、全零、有限值还是异常大 预期参数有梯度,冻结参数没有梯度 不能把“有梯度”等同于“梯度正确”
训练/评估模式 明确调用 train()eval(),单独检查 Dropout、BatchNorm 同一模式下结果符合预期并可解释 不能消除所有随机性和设备差异

PyTorch 的官方 torch.autograd.gradcheck 文档说明,该工具通过小的有限差分变化比较数值梯度与解析梯度;默认设计面向双精度输入,对精度较低或不可微点附近的结果需要谨慎解释。工程上应先把自定义算子缩成小输入再检查,避免直接在完整模型上运行后把内存或速度问题误判成求导错误。

如果梯度为 None,优先检查参数是否参与了当前损失、是否被 detach()no_grad()、标量转换或跨库操作切断;如果梯度始终为零,再检查激活饱和、掩码、标签和损失缩放。若参数有梯度但更新后完全不变,要确认该参数确实交给优化器、没有在更新后重新载入旧检查点,也没有因数值精度让极小更新被舍入。

这组检查适合纳入项目上线前的自动化门禁。可结合AI 项目从立项到上线的验证清单记录责任人、输入版本与停止条件;需要选择调试、追踪或训练辅助工具时,可从AI 工具专题进入经过复核的工具页。工具能缩短定位路径,但不能替代对损失函数和数据语义的人工审查。

梯度下降训练异常排查树,按损失不变、振荡发散、训练下降验证变差和出现 NaN 分流
先看观测信号,再决定调学习率、查数据还是处理数值问题;不要一上来同时换模型和优化器。图:兰塞 AI 原创。

训练不收敛时怎么排查

  1. 先验证实现。用极小数据集测试模型能否过拟合;检查损失是否真的依赖待训练参数,zero_grad / backward / step 顺序是否正确。
  2. 看数值而非只看曲线。记录梯度范数、参数范数、是否出现 NaN/Inf,以及混合精度缩放是否溢出。
  3. 检查数据尺度。特征量纲差异、异常值、标签错误和不合理的归一化都可能让优化困难。
  4. 做学习率对照。在其他条件不变时试一组数量级不同的学习率,不要一次同时改批量大小、模型和优化器。
  5. 区分优化失败与泛化失败。训练损失不降偏向优化问题;训练损失降、验证损失升更像过拟合或数据分布问题。
现象 优先检查 最小实验 不要直接下结论
损失完全不变 参数是否在优化器中、梯度是否为 None/零、图是否断开 打印单层参数更新前后差值 不一定是学习率太小
损失振荡或爆炸 学习率、输入尺度、异常样本、梯度范数 降低学习率 10 倍并固定同一 batch 裁剪能止血但可能掩盖根因
出现 NaN/Inf 除零、log/sqrt 定义域、混合精度、极端 logits 关闭混合精度并启用异常定位 不能只把 NaN 替换为零
训练降、验证升 数据泄漏、过拟合、分布差异、评估模式 冻结模型检查验证管线 这通常不是“梯度不下降”
换 batch 后结论反转 更新步数、学习率和归一化统计 按相同样本预算和更新预算分别比较 epoch 相同不等于训练预算相同

PyTorch 提供异常检测帮助定位产生 NaN 或反向错误的操作,也提供 clip_grad_norm_限制梯度总范数。前者用于找错,后者是控制手段;任何一个都不能证明数据和目标函数正确。

训练曲线应该同时记录哪些信号?

只看最后一个训练损失,无法区分“优化有效但过拟合”“日志口径改变”“学习率日程错位”与“计算图已经断开”。更稳妥的做法是让每次参数更新都有同一组可关联的信号,并把训练、验证和系统性能分开。横轴至少保留参数更新步数;如果同时展示 epoch 或墙钟时间,也要能追溯每个点实际看过多少样本或 token。

信号 主要回答的问题 异常例子 下一步验证
训练损失与分项损失 当前目标是否在优化 总损失下降但关键分项不动 检查权重、掩码与分母口径
固定验证集指标 改进是否迁移到未训练样本 训练持续改善、验证持续恶化 查过拟合、泄漏和分布差异
梯度范数 反向信号是否消失、爆炸或断开 长期为零、突然变为 Inf 定位到层与算子,复查输入尺度
参数更新范数/参数范数 优化器是否真正改变模型 有梯度却没有可见更新 查学习率、精度、冻结与优化器参数组
实际学习率 调度器是否按预期前进 warmup 提前结束或恢复后跳变 核对按 micro-batch 还是 update 计步
数据与样本计数 不同运行预算是否可比 epoch 相同但有效样本数不同 查过滤、尾批、重复采样和分布式 sampler
吞吐、显存和溢出 训练是否受系统或混合精度影响 跳过更新、吞吐突降、显存锯齿 查 loss scaler、数据加载和检查点写入

观察到损失下降并不等于模型已经具备可靠能力。公开结论时,应把原子主张与对应实验、数据版本和限制关联起来,可参考AI 结论的证据核验流程;训练数据、检查点和日志还可能包含个人信息、商业数据或恶意载荷,访问控制与留存边界可结合AI 安全与提示注入防护指南制定。内链只承担延伸阅读,不能替代本页对梯度下降本身的完整解释。

怎样保存一个可以恢复和复核的训练运行?

“固定随机种子”只是复现的起点,不是保证。一次可交接的运行至少要保存:数据集版本或不可逆摘要、训练/验证划分规则、代码提交标识、完整配置、模型权重、优化器状态、学习率调度器状态、混合精度缩放器状态、当前更新步数,以及框架、驱动和硬件信息。若使用分布式采样、动态批处理或在线数据,还要记录进程数、sampler 状态、丢弃尾批规则和已消费数据位置。

恢复检查点后先做“连续性测试”:用保存前后的相邻批次检查实际学习率、更新步数和损失是否连续;确认没有把调度器多走一步、没有只恢复模型却丢失动量,也没有从头打乱数据造成样本重复。对于很长的训练,建议定期保留独立的可恢复点,同时对文件生成摘要并做一次真实恢复演练。只证明检查点文件能够读取,不等于训练能从正确状态继续。

批量大小发生变化时,不要机械套用“学习率按批量线性放大”。这种经验关系依赖模型、优化器、归一化、训练阶段和数据分布;正确做法是重新设定对照实验,并同时比较样本预算与更新预算。对自适应优化器,还要关注一阶、二阶矩等状态是否与新配置兼容。任何自动调参系统都应保留搜索空间、终止条件、失败运行和选择规则,避免只留下胜出结果形成幸存者偏差。

最终报告应区分三种结论:实现结论(梯度与更新链路可工作)、优化结论(在给定预算下目标下降)、泛化结论(在独立评估集和既定指标上有效)。三者需要不同证据,不能用一条漂亮的训练曲线互相替代。若模型用于高风险场景,还要另做稳健性、安全和人工审批测试;梯度下降收敛从来不是上线许可。

训练什么时候应该停止?

停止训练不能只依赖“训练损失看起来不再下降”。先确定真正用于选择检查点的验证指标、评估间隔和允许的训练预算,再设置可审计的停止规则。例如,在固定验证集上连续若干次评估没有超过既定最小改进量时停止,同时保存表现最好的检查点,而不是默认使用最后一步。等待次数过短会把小批量噪声误判成平台期,过长则可能浪费算力或加剧过拟合。

验证集必须与训练集隔离,且不能在频繁试验中被反复“调到失去独立性”。如果团队根据同一个验证集不断修改特征、模型和超参数,这个验证集也会逐渐参与决策;最终结论应留给未参与选择的测试集或独立回放数据。数据按时间变化的任务还要使用时间切分,并记录评估窗口,否则随机划分可能把未来信息泄漏到训练阶段。

达到预算上限、出现持续 NaN、梯度或参数范数越过安全阈值、验证指标明显恶化、数据管线版本变化,都可以成为停止条件。停止后不要只保留“最好分数”:还要保存触发原因、最佳步数、最后步数、全部候选的选择规则和失败运行。若训练是在抢占式算力上进行,定期检查点与正常早停应使用不同状态标识,避免把实例中断误写成算法收敛。

比较两种方案时,最好预先声明主指标和预算口径。一个方案用更多 token、更长墙钟时间或更密集评估得到更好结果,并不能自动说明优化器更优。至少分别给出相同样本预算、相同更新预算或相同算力预算下的结果,并说明选择哪个口径服务于实际目标。对外发布“提升百分比”时还应提供基线、样本量、波动范围和复现实验;没有这些条件,只能称为当前运行的观察,不能包装成普遍规律。

早停本身也是超参数。若不同候选使用不同等待次数、评估频率或最佳检查点选择方式,比较就不再公平。实验台账应记录这些规则,并把“因预算结束”“因指标平台结束”“因异常中止”分开统计;失败运行不能从汇总中静默删除,也不应事后改写主要指标。

常见误区

沿负梯度一定能找到全局最小值吗?

不能。对凸目标可讨论更强的收敛性质;深度网络通常是非凸问题,还会受到初始化、鞍点、平坦区域、数据噪声和数值精度影响。负梯度只给出当前位置的局部下降方向。

损失每一步都必须下降吗?

小批量训练的单步损失可能因采样噪声上升。应观察固定口径下的移动平均、完整评估集指标和较长时间窗口,而不是看到一次回升就断言失败。

Adam 取代梯度下降了吗?

没有。Adam、SGD with momentum 等优化器仍利用梯度,只是改变了如何缩放、平滑或累计更新。PyTorch 的优化器目录同时列出 SGD、Adam、AdamW、RMSprop 等不同算法;比较方法时还要控制学习率日程、权重衰减、批量大小和训练预算。

最小 PyTorch 训练循环

optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
for x, y in loader:
    optimizer.zero_grad(set_to_none=True)
    prediction = model(x)
    loss = loss_fn(prediction, y)
    loss.backward()
    optimizer.step()

这段代码只展示更新顺序,不代表 lr=0.01momentum=0.9 适合你的任务。set_to_none=True 与把梯度清零在行为和性能上可能有细节差异,使用前应核对当前框架文档。正式实验还应固定随机种子、保存配置与检查点,并同时报告训练和验证指标。TensorFlow 用户可对照其基础训练循环理解同一组“求梯度—应用梯度—重新评估”步骤。

资料来源与复核范围

定义与基础流程依据 Google 的梯度下降课程;学习率和批量差异参考超参数说明交互实验;神经网络中的梯度问题参考反向传播模块;代码接口、动量语义和数值梯度检查分别以PyTorch SGD 文档gradcheck 文档为准。跨框架检查梯度断开问题可参考 TensorFlow 的自动微分指南。资料复核日期:2026 年 7 月 19 日。

编辑说明:本文于 2026 年 7 月 19 日完成发布前严格 A 级复核,删除旧稿中“必然找到谷底”“批量梯度保证全局最优”等超出适用条件的表述,并将无法渲染的 Markdown 数学公式改为网页可读形式;本次补充概念分工、可复算单步台账、批量方式对照、学习率实验、梯度正确性检查、训练信号矩阵、检查点恢复合同、异常排查、三张原创图和可运行的最小更新循环,同时撤下指向未完成编辑认证旧词典页的推荐链接。正式发布后仍需通过桌面端、移动端和慢速网络验收,才获得最终 A 级认证。发现公式、代码或链接错误,可通过关于我们与编辑规范提交纠错。