深入理解卷积神经网络中的填充与步幅——基于Dive-into-DL-PyTorch项目

深入理解卷积神经网络中的填充与步幅——基于Dive-into-DL-PyTorch项目

引言

在卷积神经网络(CNN)中,填充(padding)和步幅(stride)是两个至关重要的超参数,它们直接影响着卷积层的输出特征图尺寸。本文将基于Dive-into-DL-PyTorch项目中的相关内容,深入浅出地讲解这两个概念的原理和应用。

基础概念回顾

在标准的二维卷积操作中,假设输入特征图的尺寸为$n_h×n_w$,卷积核的尺寸为$k_h×k_w$,那么输出特征图的尺寸可以通过以下公式计算:

$$(n_h-k_h+1) × (n_w-k_w+1)$$

这意味着在不进行任何处理的情况下,卷积操作会使特征图的尺寸逐渐缩小。为了解决这个问题,我们引入了填充和步幅的概念。

填充(Padding)详解

什么是填充?

填充是指在输入特征图的周围添加额外的像素值(通常是0),以控制输出特征图的尺寸。填充的主要作用有:

  1. 保持特征图的空间尺寸不变
  2. 防止边缘信息过快丢失
  3. 使网络能够学习到边缘特征

填充的计算方法

当我们在高度方向填充$p_h$行,在宽度方向填充$p_w$列时,输出尺寸变为:

$$(n_h-k_h+p_h+1)×(n_w-k_w+p_w+1)$$

常见填充策略

  1. Same Padding:使输出尺寸与输入尺寸相同

    • 当$k_h$为奇数时:$p_h = k_h - 1$,两侧各填充$(k_h-1)/2$
    • 当$k_h$为偶数时:上侧填充$\lceil (k_h-1)/2 \rceil$,下侧填充$\lfloor (k_h-1)/2 \rfloor$
  2. Valid Padding:不进行任何填充,输出尺寸自然缩小

PyTorch实现示例

import torch
from torch import nn

# 定义卷积层,kernel_size=3,padding=1(保持尺寸不变)
conv2d = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, padding=1)

# 8x8的输入经过卷积后仍然是8x8
X = torch.rand(8, 8)
output = conv2d(X.view(1,1,8,8))  # 添加batch和channel维度
print(output.shape[2:])  # 输出: torch.Size([8, 8])

步幅(Stride)详解

什么是步幅?

步幅是指卷积核在输入特征图上滑动的步长。默认步幅为1,表示卷积核每次移动一个像素。增大步幅可以:

  1. 减少计算量
  2. 降低特征图分辨率
  3. 扩大感受野

步幅的计算方法

当高度方向步幅为$s_h$,宽度方向步幅为$s_w$时,输出尺寸为:

$$\lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor × \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor$$

常见步幅策略

  1. 小步幅(1或2):保留更多空间信息
  2. 大步幅(≥3):快速降采样,扩大感受野

PyTorch实现示例

# 步幅为2,输出尺寸减半
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1, stride=2)
output = conv2d(X.view(1,1,8,8))
print(output.shape[2:])  # 输出: torch.Size([4, 4])

# 非对称步幅和填充
conv2d = nn.Conv2d(1, 1, kernel_size=(3,5), padding=(0,1), stride=(3,4))
output = conv2d(X.view(1,1,8,8))
print(output.shape[2:])  # 输出: torch.Size([2, 2])

填充与步幅的组合应用

在实际网络设计中,我们经常需要组合使用填充和步幅来控制特征图的尺寸变化:

  1. 保持尺寸:padding=(k-1)/2, stride=1
  2. 降采样:适当padding, stride>1
  3. 非对称处理:不同方向使用不同参数

实践建议

  1. 大多数情况下使用奇数大小的卷积核(3×3,5×5等),便于对称填充
  2. 步幅的选择要考虑网络深度和最终需要的特征图尺寸
  3. 在深层网络中使用更大的步幅来替代池化操作
  4. 注意边界效应,特别是在使用大卷积核时

总结

填充和步幅是卷积神经网络中控制特征图尺寸的两个关键超参数。通过合理设置它们,我们可以在保持网络表达能力的同时,优化计算效率和内存使用。理解它们的数学原理和实现方式,对于设计高效的CNN架构至关重要。

通过本文的讲解,希望读者能够掌握:

  1. 填充的原理和计算方法
  2. 步幅的作用和影响
  3. 如何在PyTorch中实现不同的填充和步幅策略
  4. 实际应用中的最佳实践

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值