CNN卷积层的填充和步幅

2022-09-04  本文已影响0人  小黄不头秃

(一)填充和步幅

(1)填充

假设我们有一张(32,32)大小的图片,使用的卷积核是(5,5).那么每经过一次卷积核,图片的高和宽就会减少4个像素。

更大的卷积核可以加速图片图片压缩的更小。
经过一层图片的形状变化的公式:
(n_h,\ n_w)\ =>\ (n_h-k_h+1,\ n_w-k_w+1)

那么问题来了,因为每一次经过卷积过后,图片就会缩小,极有可能经过几次的卷积之后,图片就已经变得很小了。如果我不想让他那么快的变小怎么办呢?

答案是:填充。即,在输入的四周添加额外的行和列

经过填充后,输出的形状就会发生改变。

(n_h+p_h,\ n_w+p_w)\ =>\ (n_h-k_h+p_h+1,\ n_w-k_w+p_w+1)

通常我们让p_h = k_h-1, 因为这样能够让输入经过卷积后大小不发生变化。

(2)步幅

假设我们的输入的形状是(244,244),在使用(5,5)大小的卷积核的情况下,如果我们要将输出变成(4,4)的大小,我们需要55层。这样也是我们不希望的,这将耗费大量的计算。我们可以通过控制步幅来加速图片的压缩

步幅:指的是卷积核在扫描输入做计算的时候在行和列上,一次移动的长度。上面所有的都是默认为1.下图表示的是步幅为2.

经过步幅的调整后,输出的形状也会发生变化。

(二)代码实现

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)
上一篇 下一篇

猜你喜欢

热点阅读