Dropout:推理要关掉
Dropout 训练时随机丢弃激活、推理时必须 eval 关闭——train mode 部署会让输出随机抖动,和 BatchNorm 一样要 model.eval()。

1. 部署输出随机抖,常是 Dropout 没关
分类服务同一输入连续两次推理结果不同——查代码发现 export 前忘了 model.eval(),Dropout 仍在 train mode 随机 zero 神经元。和 BatchNorm 一样,Dropout 的行为由 train/eval 模式决定;部署必须 eval,否则输出是随机的。
2. 训练时做什么
nn.Dropout(p=0.5) 训练时以概率 将激活置零,其余激活按 scale(inverted dropout,PyTorch 默认)——保证 train 和 eval 期望一致。推理时 model.eval() 关闭 Dropout,所有激活保留,不再 scale。
class MLP(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(256, 128)
self.drop = nn.Dropout(0.5)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
return self.fc2(self.drop(F.relu(self.fc1(x))))
model.train() # Dropout 生效
model.eval() # Dropout 关闭Transformer 里 attention dropout、FFN dropout 同理——eval 时全部关闭。torch.no_grad() 只关梯度,不切换 Dropout;必须显式 model.eval()。
3. p 的选择与位置
是 MLP 常见默认;CNN 全连接层前常用 0.5;Transformer FFN 常用 0.1–0.2。过大 欠拟合;过小正则弱。Dropout 放在全连接层前、embedding 后;卷积层用 Dropout2d 对 spatial 维度 drop。
小数据过拟合可增大 ;大数据或已有强正则可减小或不用 Dropout。BatchNorm 与 Dropout 同层顺序有争议——实践中 BN 在前 Dropout 在后较常见。
4. 导出与 TorchScript/ONNX
torch.jit.trace 或 ONNX export 时必须在 eval mode 下 trace,否则 graph 可能固化 train 行为或 export 后行为不一致。CI 加测试:同一 input 连续 forward 两次,output 应 identical(eval mode 下)。
model.train() accidentally 在 validation loop 里也会打开 Dropout——val metric 会带噪声,且与 deploy 不一致。val 和 test 循环开头写 model.eval(),train 循环写 model.train()。
5. 与 MC Dropout 的区分
Monte Carlo Dropout 故意在推理时保持 Dropout 开,多次 forward 估 uncertainty——这是有意的 eval-time dropout,与部署 bug 不同。生产 serving 默认仍应 eval 关 Dropout;uncertainty 需求单独设计 inference 路径。
6. 案例:验证集指标虚高
某模型验证准确率比测试高两个点——发现验证循环里误调 model.train(),Dropout 随机性污染 val。改 eval 后 val 与 test 对齐。train/eval 切换是 metric 可信的前提。
7. 验收
- 部署前
model.eval();同一 input 多次 inference 结果一致。 - val/test loop 不用 train mode。
- export(ONNX/TorchScript)在 eval 下完成。
- CI 含 eval mode 确定性测试。
- 文档写明 inference 必须 eval,与 BN 一并检查。
8. 落地与衔接
推理服务启动脚本在加载权重后强制切换到评估模式,并在健康检查里对固定输入连跑两次断言输出一致。导出中间表示或部署格式时必须在评估模式下追踪,与 eager 模式数值对比。验证循环模板默认评估模式,训练循环开头再切回训练模式,避免复制粘贴漏切换。文档把随机失活与批归一化并列为部署必查项,新人清单勾选后再上线。代码审查时专门看一眼验证循环是否误开训练模式。
9. 案例复盘
某分类服务客户报同一图片两次结果不同,追踪发现封装里只包了无梯度未切评估模式。修改后输出稳定,持续集成新增评估模式确定性测试防回归。另一次验证集虚高两点的根因是验证循环误开训练模式,随机失活污染指标。现在指标脚本与推理服务共用同一评估封装,训练与评估切换不再靠记忆。该问题在多个项目重复出现,已写入常见故障手册。
Dropout 是训练正则,不是推理特性。忘了 eval,模型在部署里仍是「随机」的——这是最常见也最容易修的部署 bug 之一。把 eval 确定性与 BN 检查绑在同一 preflight,比单独文档提醒更不容易漏。发版前用固定输入做两次推理对比,应成为标准冒烟步骤。验证与推理共用评估封装后,训练循环仍须在每轮开头显式切回训练模式。服务监控可加入固定探针请求比对输出哈希,发现非确定性立即告警并回滚。
相关
也可以看看
- ·4 分钟阅读
标签平滑
Label smoothing 把 one-hot 变成 soft target,减轻 overconfident logits——有时改善校准和泛化,过大 smoothing 会 hurt top-1 acc。
- ·16 分钟阅读
KV cache 分页与前缀复用:吞吐上去后正确性怎么验
沿 block table、前缀哈希与抢占回收拆开缓存一致性风险,说明错页复用为何表现为「偶发胡话」;用确定性前缀集、强制抢占和逐 token 对照验收。
- ·18 分钟阅读
混合精度下的梯度累积:loss 缩放、裁剪与 step 顺序
沿 autocast、GradScaler、unscale_、裁剪与 optimizer.step 的数据流说明静默错误;区分 micro-batch 平均与求和,并用等价性测试验收。
johan's blog