(一)填充和步幅
(1)填充
假设我们有一张(32,32)大小的图片,使用的卷积核是(5,5).那么每经过一次卷积核,图片的高和宽就会减少4个像素。
- 第一层输出为(28,28)
- 第七层的输出为(4,4)
更大的卷积核可以加速图片图片压缩的更小。
经过一层图片的形状变化的公式:
那么问题来了,因为每一次经过卷积过后,图片就会缩小,极有可能经过几次的卷积之后,图片就已经变得很小了。如果我不想让他那么快的变小怎么办呢?
答案是:填充。即,在输入的四周添加额外的行和列
![](https://img.haomeiwen.com/i12824314/ec826ec0538154dd.png)
经过填充后,输出的形状就会发生改变。
![](https://img.haomeiwen.com/i12824314/47ebe9a34bbbe0f6.png)
通常我们让, 因为这样能够让输入经过卷积后大小不发生变化。
(2)步幅
假设我们的输入的形状是(244,244),在使用(5,5)大小的卷积核的情况下,如果我们要将输出变成(4,4)的大小,我们需要55层。这样也是我们不希望的,这将耗费大量的计算。我们可以通过控制步幅来加速图片的压缩
步幅:指的是卷积核在扫描输入做计算的时候在行和列上,一次移动的长度。上面所有的都是默认为1.下图表示的是步幅为2.
![](https://img.haomeiwen.com/i12824314/8b11c0ae6ffbf518.png)
经过步幅的调整后,输出的形状也会发生变化。
![](https://img.haomeiwen.com/i12824314/acfe37035861270a.png)
(二)代码实现
import torch
from torch import nn
X = torch.rand(size=(8,8))
def com_conv2d(conv2d, X):
X = X.reshape((1,1)+X.shape)
Y = conv2d(X)
return Y.reshape(Y.shape[2:])
# 四周填充1个像素,那么输入和输出的形状是一样的。
conv2d = nn.Conv2d(1,1,kernel_size=(3,3),padding=1)
print(com_conv2d(conv2d,X).shape)
# 也可以填充不同的高度和宽度,上下为2,左右为1
conv_2d = nn.Conv2d(1,1,kernel_size=(5,3),padding=(2,1))
print(com_conv2d(conv2d,X).shape)
# 使用步长为2
conv2d = nn.Conv2d(1,1,kernel_size=(3,3),padding=1,stride=2)
print(com_conv2d(conv2d,X).shape)
conv2d = nn.Conv2d(1,1,kernel_size=(3,5),padding=(0,1),stride=(3,4))
print(com_conv2d(conv2d,X).shape)
网友评论