填充和步长
填充
- 给定(32 x32)输入图像
- 应用 5 × 5 大小的卷积核
- 第1层得到输出大小 28 × 28
- 第7层得到输出大小 4 × 4
- 更大的卷积核可以更快地减小输出大小
- 形状从nh × nw 减少到(nh -kh + 1)×(nw - kw + 1)
实际填充

规则:
- 填充ph 行和pw列,输出形状为 (nh -kn +Ph + 1) ×(nw - kw +pw + 1)
- 通常取 ph= kh-l,Pw= kw1
- 当 kh 为奇数:在上下两侧填充 ph/2
- 当 kh 为偶数:在上侧填充「ph/2],在下侧填充 LPh/2』
步幅
填充减小的输出大小与层数线性相关
- 给定输入大小、224×224,在使用5×5卷积核的情况下,需要44层将输出降低到 4×4
- 需要大量计算才能得到较小输出

规则:

总结
- 填充和步幅是卷积层的超参数
- 填充在输入周围添加额外的行/列,来控制输出形状的减少量
- 步幅是每次滑动核窗口时的行/列的步长,可以成倍的减少输出形状
实践代码
详情
<!-- #include-env-start: D:/code/klc/test/share4ai/docs/book/dive_into_on_dl/cnn/basic -->
```python
# 解决 jupyter notebook Kernel Restarting内核崩溃
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
# 在所有侧边填充1个像素
import torch
from torch import nn
def comp_conv2d(conv2d, X):
X = X.reshape((1, 1) + X.shape) # (8,8) → (1,1,8,8)
Y = conv2d(X) # nn.Conv2d 要求输入格式为 (N, C, H, W): batch size,输入通道数,高和宽
return Y.reshape(Y.shape[2:]) # 去掉 batch 和 channel 维度,返回 (H_out, W_out)
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1) # O = (W - K + 2P) / S + 1 =(8-3+2*1)/1 +1 = 8
X = torch.rand(size=(8, 8))
comp_conv2d(conv2d, X).shape
torch.Size([8, 8])
# 填充不同的高度和宽度
conv2d = nn.Conv2d(1, 1, kernel_size=(5, 3), padding=(2, 1))
comp_conv2d(conv2d, X).shape
torch.Size([8, 8])
# 将高度和宽度的步幅设置为2
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1, stride=2)
comp_conv2d(conv2d, X).shape
torch.Size([4, 4])
