填充
填充过程中,在很多情况下,我们会设置和
来使输入和输出具有相同的高和宽。这样会方便在构造网络时推测每个层的输出形状。假设这里
是奇数,我们会在高的两侧分别填充
行。如果
是偶数,一种可能是在输入的顶端一侧填充
行,而在底端一侧填充
行。在宽的两侧填充同理。
在讲例子之前,先补充一下pytorch操作维度时的contactate也就是连接操作。可以看到x.view后的(1, 1)参数直接与x.shape进行了连接。这样就对张量进行了升维的操作。
x = torch.rand(8, 8)x = x.view((1, 1) + x.shape)print(x.shape)结果:torch.Size([1, 1, 8, 8])
在定义卷积层时可以通过padding参数设置填充,可以看到设置为1后经过卷积计算张量形状不变。
def comp_conv2d(conv2d, x):x = x.view((1, 1) + x.shape)y = conv2d(x)return y.view(y.shape[2:])conv2d = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, padding=1)x = torch.rand(8, 8)print(comp_conv2d(conv2d, x).shape)conv2d = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=(5, 3), padding=(2, 1))print(comp_conv2d(conv2d, x).shape)结果:torch.Size([8, 8])torch.Size([8, 8])
步幅
步幅就是卷积核一次移动的步长,非常简单。
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1, stride=2)print(comp_conv2d(conv2d, x).shape)conv2d = nn.Conv2d(1, 1, kernel_size=(3, 5), padding=(0, 1), stride=(3, 4))print(comp_conv2d(conv2d, x).shape)结果:torch.Size([4, 4])torch.Size([2, 2])
小结
当输入的高和宽两侧的填充数分别为时,我们称填充为
。特别地,当
时,填充为
。当在高和宽上的步幅分别为
时,我们称步幅为
。特别地,当
时,步幅为
。在默认情况下,填充为0,步幅为1。
