桌上 先让它学会 目录

第 4 节 · 约 30 分钟

循环只有三拍。曲线告诉你第几拍坏了。

zero_grad、backward、step。少一拍,线上会给你三种常见样子。

先讲

PyTorch 默认把梯度累加。一个 mini-batch 用完,下一步若不清零,新梯度会叠在旧的上面,步子越走越怪。典型一拍:opt.zero_grad(set_to_none=True),算损失,loss.backward(),opt.step()。backward 只填 .grad,不改参数。step 才按学习率去减。

学习率 0.1 在上一节那个五参数例子里,损失从 0.211 降到 0.108。换成 10,一步就可能越过谷底。换成 1e-8,五十步看起来像一条平线。交叉熵第一步常在 log K 附近:十类约 2.3。这个参考只适用于预测概率接近均匀的情形。初始损失异常低时,先检查目标、预测和数据是否泄漏;NaN要定位首个非有限值。不能只看一个数就指定根因。

先过拟合一个小集合。拿 8 到 32 个样本、关掉随机增强、把模型开得略大,故意让它把这一小撮记住。训练损失应能降到接近 0。这一步过不了:标签和 logits 对错轴、学习率炸了、忘了 model.train()。先修管道,再谈泛化。管道通了,再打开验证集。测试集仍封着。

训练降、验证降:还在学。训练降、验证升:记住训练样本了,停早、加数据、加一点权重衰减。两条都平:可能学习率极小、没有调用step、没有反向,或图被断开。分别测梯度范数和参数差,才能区分。忘记zero_grad直接导致累加,可能改变或破坏训练曲线,不能由平线断定。过拟合那条,验证最低点出现在 step 420,就把那份权重存成 checkpoint。再训到 2000,训练 0.02、验证 0.41,对外报 0.02 没有意义。

训练可shuffle;验证需要固定数据和确定变换、eval模式及按样本正确聚合。完整验证指标通常不依赖排列;固定顺序便于复现,但不是可比较的必要条件。少了 zero_grad,步子会越走越大,训练损失可能假下降。少了 backward,参数不动,两条平。少了 step,梯度填了,权重还是旧的,看起来也像卡住。先印几个 batch 的 loss 原始值。权重衰减 1e-4 往往够用;一下子加到 0.1,两条会一起抬高。第 1 节那张卡里,测试集还封着。这里用验证来决定何时停。

例:同一份五参数网络,三条日志
  1. lr=0.1,train 0.211→0.108,val 同步下降:还在学
  2. train 继续降到 0.02,val 从 0.18 升到 0.41:过拟合,停在 val 最低点
  3. 五十步两条都几乎不动:先区分极小LR、没有backward、没有step;检查grad_norm与parameter_delta
三种样子不要混着叫。学习率太大通常两条一起炸,和卡住不同。

你来做

实线训练,虚线验证。草图只描述症状,不能唯一指定根因。完成识别后,进入真实CPU训练与故障诊断,比较梯度范数和参数变化。

train↓ val↓
train↓ val↑
两条都平

你已做概念预习。下一步要真正训练、保存并恢复:运行25参数MLP实验。草图判断与本地笔记不代表训练已完成。