核心要点

  • 先做 sanity check:拿几十条样本让模型过拟合,过不去说明代码/数据有 bug,过得去再上全量

  • 学习率:太大 loss 震荡或不降,太小几乎不动,先做 LR range 扫一遍量级

  • 查数据与标签:标签是否错位/类别映射错、归一化是否漏做、输入是否全为 0 或常数

  • 梯度是否真的回传:requires_grad、是否误用 detach()、loss 是否接在计算图上、参数是否在更新

标准回答

先复现并做 sanity check,再分层定位(独占一行)

不要一上来调超参。先固定随机种子、拿一个极小子集(几十条)训练,看模型能否过拟合到接近 0 loss:能,说明训练链路通,问题在数据规模/泛化;不能,说明数据或代码有硬 bug。

数据层

检查标签是否错位或类别映射错误、输入归一化/标准化是否遗漏、是否有大量脏数据或常数特征、是否 shuffle,以及 DataLoader 取出的 batch 是否符合预期(打印一个 batch)。

代码层

确认 loss 函数实现与用法正确(如分类用 CrossEntropy 时别重复 softmax)、梯度是否回传:检查 requires_grad、有没有误用 detach()、optimizer.zero_grad()/loss.backward()/optimizer.step() 顺序是否齐全、参数前后是否真的变化。

模型层

排查学习率量级(最常见,先扫 1e-2~1e-5)、初始化与激活是否导致饱和/死神经元、是否梯度消失(看各层梯度范数)、归一化层(BatchNorm/LayerNorm)是否设置正确。优化器与调度器配置也一并核对。

常见误区

⚠️ 常见踩坑

一上来就盲调超参或换模型,却不先用小批数据复现确认「能不能过拟合」;以及只盯 loss 数值,不打印一个 batch、不看梯度范数,错过标签错乱或梯度未回传这类硬 bug。

追问

追问 1小批数据能过拟合、但全量训练 loss 还是不降,可能是什么?

说明链路没问题,瓶颈在规模与优化:学习率对全量不合适(常需更大 batch 配合 warmup/调度)、数据噪声或标签质量差、任务对当前模型容量太难、或正则/数据增强过强压住了收敛。先降增强、调 LR 与 warmup 再观察

追问 2怎么快速判断梯度到底有没有回传?

在 backward 后遍历参数打印 param.grad 是否为 None 或全 0,并比较一步更新前后参数值是否改变;也可打印各层梯度范数,若某层之后梯度恒为 0,多半是该处被 detach 或 requires_grad=False 截断了计算图。

延伸学习

与本题相关的知识库文章、术语、工具与行业资讯。