【SPP】SPP、SPPF、ASPP

在这里插入图片描述


1、SPPF vs SPP vs ASPP 结构对比图(含参数量)

SPP,Spatial Pyramid Pooling(空间金字塔池化)

最早由何恺明等人在 2014 年提出,用于解决 CNN 对固定输入尺寸的限制,通过多尺度池化生成固定长度的特征表示。

==================== ① SPP(原始) ====================

        输入 (C)
           │
   ┌───────┼───────────────┐
   │       │       │       │
 MaxPool  MaxPool MaxPool Identity
  k=5      k=9     k=13
 (无参)    (无参)  (无参)   (无参)
   │       │       │       │
   └───────┴───────┴───────┘
           │
        Concat (4C)
           │
      1×1 Conv (4C → C)
      参数量:4C × C

👉 总参数:
= 4C²


======================================================

SPPF,Spatial Pyramid Pooling - Fast(快速空间金字塔池化)

SPPF 是 YOLOv5 中引入的 SPP 的高效变体,用串行的小核池化(如多个 5×5 池化)近似 SPP 的多尺度感受野,显著减少计算量,提升推理速度。

==================== ② SPPF(YOLOv5/8) ====================

==================== SPPF(Correct Version) ====================

输入: x (C)

        │
   1×1 Conv
   (C → C/2)
   参数:C × (C/2)
        │
        ├───────────────┐
        │               │
        │          MaxPool k=5
        │               │
        │               y1
        │               │
        │          MaxPool k=5
        │               │
        │               y2
        │               │
        │          MaxPool k=5
        │               │
        │               y3
        │
        └───────────────┘

Concat: [x, y1, y2, y3]
通道数:4 × (C/2) = 2C

        │
   1×1 Conv
   (2C → C)
   参数:2C × C
        │
      输出 (C)

===============================================================

ASPP,Atrous Spatial Pyramid Pooling(空洞空间金字塔池化,也称“扩张空间金字塔池化”)

是 DeepLab 系列(尤其是 DeepLab v2/v3)中提出的模块,利用空洞卷积(atrous convolution)在不同膨胀率下提取多尺度上下文信息,广泛应用于语义分割。

==================== ③ ASPP(DeepLab) ====================

                输入 (C)
                   │
   ┌────────┬────────┬────────┬────────┐
   │        │        │        │
 1×1Conv  3×3Conv  3×3Conv  3×3Conv
          dilation1 dilation6 dilation12
   │        │        │        │
 (C→C')   (C→C')   (C→C')   (C→C')
 参数:C·C'   9C·C'   9C·C'   9C·C'
   │        │        │        │
   └────────┴────────┴────────┴────────┘
                   │
               Concat (4C')
                   │
             1×1 Conv (4C' → C)
             参数:4C' × C

👉 总参数:
= (1 + 9 + 9 + 9) C·C' + 4C'·C  
= **28C·C' + 4C·C' = 32C·C'**

若 C' = C/4(常见):

👉 总参数 ≈ **8C²**

======================================================

2、三者参数量对比(统一尺度)

模块参数量级是否重
SPP4C²中等
SPPF2.5C²(最轻)✅ 最轻
ASPP~8C²❗ 最重

3、关键差异(本质理解)

🟢 SPP

  • 多尺度池化(不同kernel)
  • 并行结构
  • 感受野大,但计算略重复

略去 channel 输入输出对齐的 coding 实现:

class SPP(nn.Module):
    def __init__(self):
        """Initializes an SPP module with three different sizes of max pooling layers."""
        super().__init__()
        self.maxpool1 = nn.MaxPool2d(5, 1, padding=2)
        self.maxpool2 = nn.MaxPool2d(9, 1, padding=4)
        self.maxpool3 = nn.MaxPool2d(13, 1, padding=6)

    def forward(self, x):
        """Applies three max pooling layers on input `x` and concatenates results along channel dimension."""
        o1 = self.maxpool1(x)
        o2 = self.maxpool2(x)
        o3 = self.maxpool3(x)
        return torch.cat([x, o1, o2, o3], dim=1)

🔵 SPPF(YOLOv8用的)

  • 串行池化(复用计算)
  • 更快(Fast)
  • 参数更少 + 速度更快

👉 本质优化点:

多个大kernel → 用多个小kernel叠加模拟

略去 channel 输入输出对齐的 coding 实现:

class SPPF(nn.Module):
    def __init__(self):
        """Initializes an SPPF module with a specific configuration of MaxPool2d layer."""
        super().__init__()
        self.maxpool = nn.MaxPool2d(5, 1, padding=2)

    def forward(self, x):
        """Applies sequential max pooling and concatenates results with input tensor."""
        o1 = self.maxpool(x)
        o2 = self.maxpool(o1)
        o3 = self.maxpool(o2)
        return torch.cat([x, o1, o2, o3], dim=1)

🔴 ASPP

Atrous Spatial Pyramid Pooling(空洞空间金字塔池化,也称“扩张空间金字塔池化”)

  • 多尺度 空洞卷积
  • 不只是“看不同尺度”
  • 而是:
    👉 在卷积层建模空间结构

👉 优点:

  • 表达能力最强

👉 缺点:

  • 参数最多
  • 计算最重

在这里插入图片描述

class ASPPF(nn.Module):
    """
    Atrous Spatial Pyramid Pooling Fast (ASPPF)
    用不同膨胀率的空洞卷积替代 SPPF 的串行 MaxPool,实现多尺度特征融合。
    # 指定 kernel size + dilations
    - [-1, 1, ASPPF, [1024, 3, [1, 2, 4]]]
    """

    def __init__(self, c1, c2, k=3, dilations=(1, 2, 4)):
        """
        Args:
            c1 (int): 输入通道数
            c2 (int): 输出通道数
            k  (int): 卷积核大小,默认 3
            dilations (tuple): 空洞率列表,对应多尺度分支

            parse_model 会自动将 [c1, c2, *args[1:]] 传入,所以 args[0]=c2, args[1:] 对应 k 和 dilations。


            YAML args:        [1024,  3,   [1, 2, 4]]
                                ↓      ↓       ↓
                                args[0] args[1] args[2]
                                ↓
            c1 = ch[f]        (自动从上一层获取)
            c2 = args[0]  →  1024
                                ↓
            最终传入:  ASPPF(c1=512, c2=1024, k=3, dilations=[1,2,4])
        """
        super().__init__()
        c_mid = c1 // 2  # 中间压缩通道数

        # 输入压缩:降维减少计算量
        self.cv1 = Conv(c1, c_mid, k=1)

        # 多尺度空洞卷积分支(每个分支感受野不同)
        self.dilated_convs = nn.ModuleList([
            Conv(c_mid, c_mid, k=k, d=d)   # d=1 普通卷积; d=2,4 空洞卷积
            for d in dilations
        ])

        # MaxPool 分支(保留全局上下文,对齐 SPPF 设计)
        self.maxpool = nn.MaxPool2d(kernel_size=5, stride=1, padding=2)

        # 输出融合:所有分支 concat 后降维
        # 分支数 = cv1输出 + len(dilations)个空洞卷积 + 1个maxpool
        total_c = c_mid * (1 + len(dilations) + 1)
        self.cv2 = Conv(total_c, c2, k=1)

    def forward(self, x):
        """多尺度特征提取 → concat → 融合输出"""
        x1 = self.cv1(x)                                    # 压缩输入

        dilated_outs = [conv(x1) for conv in self.dilated_convs]  # 各空洞分支
        pool_out = self.maxpool(x1)                         # MaxPool 分支

        # concat: [压缩特征, 空洞d=1, 空洞d=2, 空洞d=4, maxpool]
        out = torch.cat([x1, *dilated_outs, pool_out], dim=1)

        return self.cv2(out)                                # 融合降维输出

4、总结

👉 SPP / SPPF:靠池化“看大范围”(轻量)

👉 ASPP:靠卷积“理解空间结构”(更强但更重)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值