我测试了两种模式的 BatchNorm 层的梯度:model.train() 和 model.eval()。
我构建了一个简单的 CNN 网络 并在 model.train() 模式和 model.eval() 模式下将相同的输入 X 输入到网络中。 我知道 BatchNorm 层的 model.train() 和 model.eval() 的区别。我已将 model.eval() 模式下 Batchnorm 层的平均值和 var 替换为 model.train() 模式下的值。因此两种模式的输出和参数都是相同的。
但是,当我计算每个参数的梯度时,我发现BatchNorm层之前的层的梯度不同,尽管它们的参数和损失是相同的。
我认为这是因为 model.train() 和 model.eval() 处 BatchNorm 层反向传播的差异,但我不明白它的细节。有谁知道吗
当模式为.train()时,batchnorm层计算输入的批量均值和方差,并用它来标准化输入。该均值和方差还用于更新移动平均均值和方差。
当模式为.eval()时,batchnorm层不计算输入的均值和方差,而是在训练阶段使用预先计算的移动平均均值和方差。
这样,当批次中的其他样本发生变化时,您在测试期间对单个图像的预测不会发生变化。
https://pytorch.org/docs/stable/_modules/torch/nn/modules/batchnorm.html#BatchNorm2d
在上面的代码中,运行均值和运行方差是在训练阶段计算的批量归一化层的输入特征图的移动平均均值和方差。