Neural network 计算Pytorch中3D CNN的填充

Neural network 计算Pytorch中3D CNN的填充,neural-network,pytorch,conv-neural-network,padding,Neural Network,Pytorch,Conv Neural Network,Padding,我目前正在尝试将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 第一层的填充为1: P = ((1-1)*193-1+3)/2 P= 1.0 尽管我还得到了后续每个层的1.0结果。有人有什么建议吗?对不起,这里是初学者 可复制

我目前正在尝试将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
第一层的填充为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])

TLDR;您的公式也适用于

您正在使用内核大小为
2
(隐式
(2,2,2)
)的最大池层,跨步为
2
(隐式
(2,2,2)
)。这意味着对于每个
2x2x2
块,您只能得到一个值。换句话说-顾名思义:只有来自每个
2x2x2
块的最大值被汇集到输出数组中

这就是为什么要从
(1,8193229193)
(1,8,96,114,96)
(注意除以
2

当然,如果您在
nn.MaxPool3d
上设置
kernel\u size=3
stride=1
,您将保留块的形状


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

由于
s=2
#w=2
,因此
2p=#x
,这是不可能的