CNN中卷积核大小、池化以及padding对输入图像大小的影响

我们发现在不使用padding操作时,经过卷积操作后,输出图像比输入图像小一点。

为保证输出图像的大小不变,我们可以使用padding操作:

conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
pool1 = nn.MaxPool2d(2)
conv2 = nn.Conv2d(16, 8, kernel_size=3, padding=1)
pool2 = nn.MaxPool2d(2)
output1 = conv1(img.unsqueeze(0))
print(img.unsqueeze(0).shape)
print(output1.shape)
output2 = pool1(output1)
print(output2.shape)
output3 = conv2(output2)
print(output3.shape)
output4 = pool1(output3)
print(output4.shape)

输出:

可见只有池化操作使图像减半。

先放计算公式:

对于尺寸为WxH大小的输入图像,卷积层使用的卷积核大小为fxf,步长为s,padding=p。

则输出的图像尺寸:

w' = (w+2p-f)/s+1

h' = (h+2p-f)/s+1

我们来验证一下:

(1,3,32,32)——>conv1(3,16,kernel_size=3,padding=1)

其中,f = 3, s = 1(默认值),p = 1

w' = (32 + 2*1 - 3)/1 + 1 = 32 输出尺寸不改变

其他可以同理进行验证。

但是,padding=1并不是会保证其他尺寸卷积核作用下的图像大小不变:

###5x5卷积核对图片尺寸的影响
conv1 = nn.Conv2d(3, 16, kernel_size=5, padding=1)
pool1 = nn.MaxPool2d(2)
conv2 = nn.Conv2d(16, 8, kernel_size=5, padding=1)
pool2 = nn.MaxPool2d(2)
output1 = conv1(img.unsqueeze(0))
print(img.unsqueeze(0).shape)
print(output1.shape)
output2 = pool1(output1)
print(output2.shape)
output3 = conv2(output2)
print(output3.shape)
output4 = pool1(output3)
print(output4.shape)

输出:

这是符合上边公式的。

值得一提的是,13x13的尺寸在经过最大池化层后尺寸变为6x6,可以验证池化层之后的尺寸是向下取整的:13/2 = 6。

如果我们想在使用5x5卷积核时保持输出图像的大小不变,怎么选择padding?

很简单,接着上边例子,解下边方程即可:

32 = (32 + 2p - 5)/ 1 + 1

解得p=2,验证一下:

###5x5卷积核对图片尺寸的影响
conv1 = nn.Conv2d(3, 16, kernel_size=5, padding=2)
pool1 = nn.MaxPool2d(2)
conv2 = nn.Conv2d(16, 8, kernel_size=5, padding=2)
pool2 = nn.MaxPool2d(2)
output1 = conv1(img.unsqueeze(0))
print(img.unsqueeze(0).shape)
print(output1.shape)
output2 = pool1(output1)
print(output2.shape)
output3 = conv2(output2)
print(output3.shape)
output4 = pool1(output3)
print(output4.shape)

确实~

猜你喜欢

转载自blog.csdn.net/weixin_45985148/article/details/124765912