Dropout 改变了什么?

所有问题的根源在于,由于 Dropout 的存在,模型在训练测试阶段看到的隐藏层激活值分布是不一致的。

它虽然不会改变期望和方差,但是会导致激活值的方差在训练时被显著增大。 期望虽然没变,但方差却发生了剧烈的变化。

这个结果清晰地告诉我们,在训练阶段,只要 Dropout 概率 p>0,激活值的方差就会被显著放大。而在测试阶段,Dropout 会被关闭,所有神经元都被激活,此时方差为零。这便引出了所有问题的根源:训练与测试阶段,模型内部数据分布的不一致性

这种训练-测试分布的不匹配 对不同任务的影响是不同的。

为什么回归任务对此更敏感?

  • 回归任务的输出是“绝对值”:回归模型的输出层通常是一个(或多个)线性神经元,它直接输出一个精确的数值。当它的输入特征(来自前一层)的统计分布(特别是方差)在测试时发生系统性偏移,其输出结果也会跟着产生一个系统性的偏移。比如,模型可能会持续性地预测偏高或偏低。

  • 分类任务的输出是“相对值”:分类模型的输出层通常是 Softmax 或 Sigmoid。它们更关心各个类别得分(logits)之间的相对大小关系。即使输入的方差有变化,导致所有 logits 同等地缩放,Softmax 的输出(概率最大的类别)很可能保持不变。因此,分类任务对这种分布偏移有更强的鲁棒性。

当 Dropout 遇见 BatchNorm

  1. 标准顺序:通常 Dropout 会放在 BatchNorm 之前。
  2. 训练时:Dropout 增大了激活值的方差。BatchNorm 在计算批次统计量时,会据此计算出一个偏大的运行方差 (running variance) 并存储下来。
  3. 测试时:Dropout 关闭,激活值方差恢复正常(变小)。然而,BatchNorm 此时会用那个在训练时学到的、偏大的运行方差来归一化“正常”的数据。
  4. 后果:这导致测试数据的尺度被错误地变换了,给后续的网络层带来了巨大的、非预期的分布变化,对需要精确数值的回归任务来说负面影响比较大。

小结

在回归任务中,应该优先考虑其他正则化方法,如 L2正则化 、增加高质量的训练数据或使用更简单的模型结构,如果必须同时使用 Dropout 和 BatchNorm,应该将 Dropout 放在 BatchNorm 之后,比如: Linear/Conv -> BatchNorm -> Activation -> Dropout

reference