在Pytorch中计算3D CNN的填充



我目前正在尝试将3D CNN应用于一组尺寸为193 x 229 x 193的图像,并希望通过每个卷积层保持相同的图像尺寸(类似于tensorflow的padding=SAME)。我知道填充可以按如下方式计算:

S=Stride
P=Padding
W=Width
K=Kernal size
P = ((S-1)*W-S+K)/2

生成第一层的padding为1:

P = ((1-1)*193-1+3)/2
P= 1.0

虽然我也得到1.0的结果,为每一个后续层。有人有什么建议吗?对不起,这里的初学者!

可再生的例子:

import torch
import torch.nn as nn
x = torch.randn(1, 1, 193, 229, 193)
padding = ((1-1)*96-1+3)/2
print(padding)
x = nn.Conv3d(in_channels=1, out_channels=8, kernel_size=3, padding=1)(x)
print("shape after conv1: " + str(x.shape))
x = nn.Conv3d(in_channels=8, out_channels=8, kernel_size=3,padding=1)(x)
x = nn.BatchNorm3d(8)(x) 
print("shape after conv2 + batch norm: " + str(x.shape))
x = nn.ReLU()(x)
print("shape after reLU:" + str(x.shape))
x = nn.MaxPool3d(kernel_size=2, stride=2)(x)
print("shape after max pool" + str(x.shape))
x = nn.Conv3d(in_channels=8, out_channels=16, kernel_size=3,padding=1)(x)
print("shape after conv3: " + str(x.shape))
x = nn.Conv3d(in_channels=16, out_channels=16, kernel_size=3,padding=1)(x)
print("shape after conv4: " + str(x.shape))
当前输出:

shape after conv1: torch.Size([1, 8, 193, 229, 193])
shape after conv2 + batch norm: torch.Size([1, 8, 193, 229, 193])
shape after reLU:torch.Size([1, 8, 193, 229, 193])
shape after max pooltorch.Size([1, 8, 96, 114, 96])
shape after conv3: torch.Size([1, 16, 96, 114, 96])
shape after conv4: torch.Size([1, 16, 96, 114, 96])

所需输出:

shape after conv1: torch.Size([1, 8, 193, 229, 193])
shape after conv2 + batch norm: torch.Size([1, 8, 193, 229, 193])
...
shape after conv3: torch.Size([1, 16, 193, 229, 193])
shape after conv4: torch.Size([1, 16, 193, 229, 193])

;你的公式也适用于nn.MaxPool3d

您正在使用内核大小为2(隐式(2,2,2))的最大池层,步幅为2(隐式(2,2,2))。这意味着对于每个2x2x2块,您只获得一个值。换句话说——顾名思义:只有每个2x2x2块的最大值才会池化到输出数组中。

这就是为什么你从(1, 8, 193, 229, 193)(1, 8, 96, 114, 96)(注意被2除名)。

当然,如果你将kernel_size=3stride=1设置在nn.MaxPool3d上,你将保留你的块的形状。


#x为输入形状,#w为内核形状。如果我们希望输出具有相同的大小,那么#x = floor((#x + 2p - #w)/s + 1)需要为真。这是2p = s(#x - 1) - #x + #w = #x(s - 1) + #w - s(你的公式)

既然s = 2#w = 2,那么2p = #x是不可能的。

最新更新