如何自己在Pytorch中实现Batchnorm2d?

时间:2020-10-15 03:13:33

标签: pytorch batch-normalization

我正在尝试通过以下方式实现Batchnorm2d()层:

BrokenPipeError: [Errno 32] Broken pipe


During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File "/Users/person/opt/anaconda3/lib/python3.8/site-packages/matplotlib/animation.py", line 1152, in save
writer.grab_frame(**savefig_kwargs)

  File "/Users/person/opt/anaconda3/lib/python3.8/contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)

  File "/Users/person/opt/anaconda3/lib/python3.8/site-packages/matplotlib/animation.py", line 232, in saving
self.finish()

  File "/Users/person/opt/anaconda3/lib/python3.8/site-packages/matplotlib/animation.py", line 368, in finish
self.cleanup()

  File "/Users/person/opt/anaconda3/lib/python3.8/site-packages/matplotlib/animation.py", line 411, in cleanup
raise subprocess.CalledProcessError(

CalledProcessError: Command '['ffmpeg', '-f', 'rawvideo', '-vcodec', 'rawvideo', '-s', '1600x1302', '-pix_fmt', 'rgba', '-r', '10', '-loglevel', 'error', '-i', 'pipe:', '-vcodec', 'h264', '-pix_fmt', 'yuv420p', '-b', '8000k', '-vcodec', 'libx264', '-y', 'test_text.mp4']' died with <Signals.SIGABRT: 6>.

但是经过培训和测试后,我发现使用图层的结果与使用ffmpeg的结果是无法比拟的。一定有问题,我想问题与ffmpeg中的参数初始化有关吗?我这样做是因为我不知道如何知道class BatchNorm2d(nn.Module): def __init__(self, num_features): super(BatchNorm2d, self).__init__() self.num_features = num_features device = torch.device("cuda" if torch.cuda.is_available() else "cpu") self.eps = 1e-5 self.momentum = 0.1 self.first_run = True def forward(self, input): # input: [batch_size, num_feature_map, height, width] device = input.device if self.training: mean = torch.mean(input, dim=0, keepdim=True).to(device) # [1, num_feature, height, width] var = torch.var(input, dim=0, unbiased=False, keepdim=True).to(device) # [1, num_feature, height, width] if self.first_run: self.weight = Parameter(torch.randn(input.shape, dtype=torch.float32, device=device), requires_grad=True) self.bias = Parameter(torch.randn(input.shape, dtype=torch.float32, device=device), requires_grad=True) self.register_buffer('running_mean', torch.zeros(input.shape).to(input.device)) self.register_buffer('running_var', torch.ones(input.shape).to(input.device)) self.first_run = False self.running_mean = (1 - self.momentum) * self.running_mean + self.momentum * mean self.running_var = (1 - self.momentum) * self.running_var + self.momentum * var bn_init = (input - mean) / torch.sqrt(var + self.eps) else: bn_init = (input - self.running_mean) / torch.sqrt(self.running_var + self.eps) return self.weight * bn_init + self.bias 中输入的形状,也许有更好的方法。我不知道如何解决,请帮忙。谢谢!

2 个答案:

答案 0 :(得分:2)

只要有人偶然发现, 您实际上不必像上面那样在模型中设置“设备”。在模型之外,你可以做

device = torch.device('cuda:0') 模型 = 模型.to(设备)

不确定这是否比手动设置模块内的权重和偏置设备更好,但我认为绝对更标准

答案 1 :(得分:0)

HERE得到答案!\
因此weight(bias)的形状是(1,num_features,1,1),而不是(1,num_features,width,height)。