SPP模块特征图尺度不变解析

一、SPP源码

class SPP(nn.Module):
    # Spatial pyramid pooling layer used in YOLOv3-SPP
    def __init__(self, c1, c2, k=(5, 9, 13)):
        super(SPP, self).__init__()
        c_ = c1 // 2  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c_ * (len(k) + 1), c2, 1, 1)
        self.m = nn.ModuleList([nn.MaxPool2d(kernel_size=x, stride=1, padding=x // 2) for x in k])

    def forward(self, x):
        x = self.cv1(x)
        return self.cv2(torch.cat([x] + [m(x) for m in self.m], 1))

二、SPP结构图

在这里插入图片描述

二、尺度不变解析

1、宽高维度不变

表1 SPP模块参数

池化核(kernel_size,k)步长(strides,s)填充(Padding,p)
512
914
1316

关键:三个最大池化模块的步长和填充不同,导致三个分支特征图在[宽高维度]均没有发生改变
可经过以下公式验证:

  • F in  \mathrm{F}_{\text {in }} Fin 初始大小为:H=20,W=20
  • 计算公式: F out = ( F in − k + 2 ∗ p ) / s + 1 \mathrm{F}_{\text {out}}=\left(\mathrm{F}_{\text {in}}-\mathrm{k}+2^* \mathrm{p}\right) / \mathrm{s}+1 Fout=(Fink+2p)/s+1

表2 SPP各个分支输出F的尺寸

分支计算过程 F out  \mathrm{F}_{\text {out }} Fout 
Maxpool1(k5,s1,p2)20-5+2×2+120
Maxpool2(k9,s1,p4)20-9+2×4+120
Maxpool3(k13,s1,p6)20-13+2×6+120
  • 计算可得 F in = F out  F_{\text {in}}=F_{\text {out }} Fin=Fout 

2、通道维度不变

关键:SPP模块中conv1、conv2的卷积核数量的设置:
通道维度没有变化的话,看源码

  • 假设输入SPP模块之前c = 40,那经过conv1每个分支输入的c都为20。
  • 将4分支沿通道维度拼接(dim=1),得到的特征图 c = 20*4。
  • 经过conv2后c为40

因此,从整体看SPP模块并没有改变特征图的通道数量。

总结

---->通过控制最大池化操作的步长和填充,保证特征图尺度维度不变性。
----->通过控制内部的卷积模块核的数量,保证特征图通道维度不变性。
综上所述,SPP模块处理后的特征图,宽高通道维度均没改变。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值