问题描述
最近,当我在PyTorch中使用BN时,我有几个问题。
- 基于PyTorch中的BN2d文档,进行推断(评估)时,它将自动使用BN层的均值和方差(训练时的运行估计)。但是,我的第一个问题是,当我们在训练后保存模型时,它是否包含运行均值和方差?我本来以为模型只会保存可学习的参数。但是,运行中的均值和方差不是真的可以学习吗?
- 默认情况下,当我们在PyTorch中使用eval()时,BN层将使用特定变量的运行平均值和方差(也许是训练的结果),对吗?但是不计算小批量的均值和方差吗? (因为我看到一些答案提到,当以1大小的批次进行推理时,BN的性能较差。但是它应使用训练的运行平均值和方差,为什么测试的批次大小会产生影响?
- 第三个问题有点类似于第二个问题。 BN会在推理时执行相同的操作。例如,当我迭代测试集两次时。结果的表现会有所不同吗? (也许更直接的问题是,推断时均值和方差会改变吗?)
- 我还想知道是否可以使用小批量均值和方差或运行均值和方差进行推断。如果仅将BN层设置为训练,则其可学习参数也会更新。但是也许我只是希望他们获得新的均值和方差。有没有办法做到这一点?
- 最后一个问题与第四个问题有关。那么,使用所有测试数据的均值和方差,或一批测试数据来计算均值和方差是否公平?我的意思是,这里公平地使用测试集的某些属性是否不恰当?
期待您的回答。我是一种新鸟,愿意与您学习和讨论!
提前谢谢!
解决方法
我从高年级同学那里得到了答案,我认为这对其他人很有用。 (如果您有不同意见,请随时发表评论)
-
当我们保存整个模型时,它将包含BN层的运行均值和方差。这两个参数不是可学习的(不是在向后过程中更新,而是在向前过程中更新)
-
如果使用.eval(),则BN层将自动使用该层中存储的运行均值和方差,并且不会在正向过程中再次更新。这意味着在推理时,BN层会使用训练过程中计算出的移动平均值和方差。
-
是的,如果仅使用.eval(),则BN层将始终使用相同的均值和方差。
-
可以根据测试集计算运行平均值和方差。只需将BN层设置为train()模式即可。这不会影响BN层的可学习参数。因为在推理时,我们只有一个正向过程(更新均值和方差),而没有一个反向过程。也许我们必须在评估或推断期开始时重新设置均值和方差,以使均值和方差与训练过程完全无关。
-
有些技巧。我听说有些GAN论文对BN层采用了这种策略。