关于常见错误的 Karpathy 推文的解释。#5:“在使用 BatchNorm 时,您没有对 Linear/Conv2d 层使用bias=False”

数据挖掘 神经网络 偏见 批量标准化
2022-03-08 23:16:56

我最近发现了 Andrej Karpathy 的这条推特帖子。他在其中陈述了神经网络开发过程中的一些常见错误。

  1. 您没有尝试首先过度拟合单个批次。
  2. 您忘记为网络切换训练/评估模式。
  3. 您在 .backward() 之前忘记了 .zero_grad() (inpytorch)。
  4. 您将 softmaxed 输出传递给期望原始 logits 的损失。
  5. 在使用 BatchNorm 时,您没有对 Linear/Conv2d 层使用bias=False,或者相反忘记将其包含在输出层中。这不会让你默默地失败,但它们是虚假参数
  6. 认为 view() 和 permute() 是同一件事(& 错误地使用 view)

我对第五条评论的解释或动机特别感兴趣考虑到我有一个类似的网络,更是如此

self.conv0_e1 = nn.Conv2d(f_in, f_ot, kernel_size=3, stride=1, padding=1)
self.conv1_e1 = nn.Conv2d(f_ot, f_ot, kernel_size=3, stride=1, padding=1)
self.norm_e1 = nn.BatchNorm2d(num_features=f_ot, eps=0.001, momentum=0.01)
self.actv_e1 = nn.ReLU()
self.pool_e1 = nn.MaxPool2d(kernel_size=2, stride=2)

构造函数中torch.Conv2d隐含的地方。bias=True

我将如何实现上面代码示例中的第五点?不过,根据这一点的第二句话,这似乎并不重要?...

1个回答

喜欢这个问题。首先,请注意您引用的推文中所说的最后一句话:“这不会让您默默失败,但它们是虚假参数。” 基本上,这是一种数学上的狡辩,但是

要查看此处发生的情况,请考虑 BatchNorm2d 层与 Conv2d 中发生的情况(引用 PyTorch 文档):

BatchNorm2dy=xE[x]Var[x]+ϵγ+β

转换 2dout(Ni,Coutj)=bias(Coutj)+k=0Cin1weight(Coutj,k)input(Ni,k)

这两种操作在通道维度上都有一个附加偏差。这两种偏见要么是多余的,要么是相互冲突的。如果它们是多余的,则您的模型正在执行额外的、不必要的计算。当它们发生冲突时,一些参数变得无用,例如在我们momentum=0为 BatchNorm2d 设置的情况下,前面的 Conv2d 层将有一组没有有用梯度的可训练参数。

您可以使用Conv2d(..., bias=False, ...). 同样,这不太可能对大多数网络产生重大影响,但它可能会有所帮助并且很高兴知道。

后续编辑:

这是相关的原因是 BatchNorm2d 层是线性操作。多个线性操作总是可以组合成一个。所以使用 Conv2d -> BatchNorm2d,Conv2d 中的偏差是多余的。

但是,只要你有激活函数,Conv2d 层就不是线性的,所以有两个 conv 层,Conv2d -> Conv2d,你就不会遇到这个问题。

所以只有在 batchnorm 之前的最后一层才是重要的。(也就是说,我确实见过一些例子,从业者只是关闭了 conv 层的所有偏差,这似乎并没有造成任何损害。)