首页 › S 模型训练 › S7 问题排查 › 01

S7-01 · 不收敛排查清单:带三个埋雷 bug 的调试实验

实战阶段约 180 分钟阶段:S7 问题排查

阶段:S7-问题排查 | 预计耗时:90 分钟 | 前置:S6 全部验收通过 代码:我把埋了雷的 s7_bug_hunt.py 交给你——你只拿症状清单,自己当侦探 答案在本文件最底部(做完再看,提前看=白做)

学习目标

  1. 掌握系统性排查顺序,改掉"到处乱试"的本能
  2. 在真实代码上诊断并修复 3 个典型训练 bug——每个都是工业界高频真实事故
  3. 学会写"症状→假设→验证→修复"四段式调试记录

核心知识

排查清单(按此顺序查,每步一个假设)

序 查什么 怎么验证 典型病
1 症状分类 loss 不降?还是降了 test 不行?还是 NaN? 三类病入口不同
2 数据与标签 打印一个 batch 的 x 形状/范围、y 取值 标签错位、预处理不一致
3 损失函数与输出 类别数对不对?dtype 对不对? CE 要 long 标签
4 学习率 1e-3 起步;震荡=太大,不动=太小 数量级错误
5 梯度流 打印 w.grad 是不是 None / 是否累加 忘 zero_grad、忘 requires_grad
6 train/eval 模式 有 Dropout/BN 时忘了 eval()? test 分数异常低

三个埋雷症状(脚本一次跑完,三种症状同时出现)

  • 症状 A(2026-11-11 实测):loss 下降明显变慢、卡在高位(epoch2 仍 0.87),test 仅 67%——同配置正常应 85%+
  • 症状 B(实测):train loss 正常下降(1.61→0.70),test 准确率却只有 42%
  • 症状 C(实测):loss 失控爆炸——epoch1 平均 28400,test 12.8% ≈ 瞎猜水平(10 类随机 = 10%)

实验任务

任务 1:跑雷区脚本(5 分钟)

.venv/Scripts/python.exe s7_bug_hunt.py

(文件我已放在 model-learn/,内容故意不逐行讲——调试的第一课就是自己读别人的代码。)

任务 2:按清单排查,逐雷修复(60 分钟)

对每个症状写四段式记录(直接填在观察记录表或本阶段新笔记里): 1. 症状:什么现象(抄关键输出) 2. 假设:我猜是哪一雷、为什么(引用排查清单的序号) 3. 验证:加了什么打印/改了什么,看到了什么 4. 修复:改动是哪一行,修完后数字变成多少

任务 3:复盘(15 分钟)

三个 bug 修完,回答:① 哪个雷最隐蔽,为什么?② 如果只有"test 分数低"这一个症状,你会先怀疑什么?③ 这三个雷分别对应排查清单的第几步?


⚠️ 答案区(做完任务 1-3 再看)

点开查看三个雷的答案 1. **症状 A(loss 卡住震荡)**:训练循环里**漏了 `opt.zero_grad()`**——梯度逐批累加,等效于步长越来越大(你在 S1-03 任务 2 亲手制造过一次) 2. **症状 B(test 烂)**:train 用 `ToTensor()`,test 却多加了 `Normalize(0.5, 0.5)`——**训练/推理预处理不一致**,模型看到的是两种分布 3. **症状 C(爆炸)**:`lr=10`——步子太大直接飞出。本机实测(Adam、2000 样本)loss 冲到 2.8 万、test 12.8%≈瞎猜;**没出 NaN 是 Adam 的自适应尺度兜了一下底**,换 SGD 或更大 lr 会直接 NaN(S1 改动实验 3 的极端版)

验收标准

衔接下一阶段

会主动排雷 → S7-02 常见报错手册:被动遇到报错时也不怕。

小测验(3 题)

答完立即判分,错题给解析;得分存本地。实验与实操题不上网测:回对话找老师验收。