空间金字塔池化改进 SPP / SPPF / SimSPPF / ASPP / RFB / SPPCSPC / SPPFCSPC(一)

简介: 空间金字塔池化改进 SPP / SPPF / SimSPPF / ASPP / RFB / SPPCSPC / SPPFCSPC

大家好,我是迪菲赫尔曼😁,我最近将本人硕士阶段所有学习的计算机视觉基础知识进行了一个系统性的整理,编写了《目标检测蓝皮书🍀》,共计10 1010篇内容,涵盖从基础知识到论文改进的整个时间线,包含第1 11篇机器学习基础、第2 22篇深度学习基础、第3 33篇卷积神经网络、第4 44篇经典热门网络结构、第5 55篇目标检测基础、第6 66篇网络搭建及训练、第7 77篇模型优化方法及思路、第8 88篇模型超参数调整策略、第9 99篇模型改进技巧、第10 1010篇模型部署基础等,详细的目录大家可以看我的这篇文章:《目标检测蓝皮书》目录,专栏地址:点击跳转,欢迎大家订阅~

1 原理


1.1 SPP(Spatial Pyramid Pooling)


SPP模块是何凯明大神在2015年的论文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》中被提出。

SPP全程为空间金字塔池化结构,主要是为了解决两个问题:

  1. 有效避免了对图像区域裁剪、缩放操作导致的图像失真等问题;
  2. 解决了卷积神经网络对图相关重复特征提取的问题,大大提高了产生候选框的速度,且节省了计算成本。

image.png

image.png

class SPP(nn.Module):
    # Spatial Pyramid Pooling (SPP) layer https://arxiv.org/abs/1406.4729
    def __init__(self, c1, c2, k=(5, 9, 13)):
        super().__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)
        with warnings.catch_warnings():
            warnings.simplefilter('ignore')  # suppress torch 1.9.0 max_pool2d() warning
            return self.cv2(torch.cat([x] + [m(x) for m in self.m], 1))

1.2 SPPF(Spatial Pyramid Pooling - Fast)


这个是YOLOv5作者Glenn Jocher基于SPP提出的,速度较SPP快很多,所以叫SPP-Fast

3331ce8373224c26abee8d12f48a5427.png

class SPPF(nn.Module):
    # Spatial Pyramid Pooling - Fast (SPPF) layer for YOLOv5 by Glenn Jocher
    def __init__(self, c1, c2, k=5):  # equivalent to SPP(k=(5, 9, 13))
        super().__init__()
        c_ = c1 // 2  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c_ * 4, c2, 1, 1)
        self.m = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)
    def forward(self, x):
        x = self.cv1(x)
        with warnings.catch_warnings():
            warnings.simplefilter('ignore')  # suppress torch 1.9.0 max_pool2d() warning
            y1 = self.m(x)
            y2 = self.m(y1)
            return self.cv2(torch.cat((x, y1, y2, self.m(y2)), 1))

1.3 SimSPPF(Simplified SPPF)


美团YOLOv6提出的模块,感觉和SPPF只差了一个激活函数,简单测试了一下,单个ConvBNReLU速度要比ConvBNSiLU快18%

f47df6ff379e4e9ab391d8f830da1a05.png

class SimConv(nn.Module):
    '''Normal Conv with ReLU activation'''
    def __init__(self, in_channels, out_channels, kernel_size, stride, groups=1, bias=False):
        super().__init__()
        padding = kernel_size // 2
        self.conv = nn.Conv2d(
            in_channels,
            out_channels,
            kernel_size=kernel_size,
            stride=stride,
            padding=padding,
            groups=groups,
            bias=bias,
        )
        self.bn = nn.BatchNorm2d(out_channels)
        self.act = nn.ReLU()
    def forward(self, x):
        return self.act(self.bn(self.conv(x)))
    def forward_fuse(self, x):
        return self.act(self.conv(x))
class SimSPPF(nn.Module):
    '''Simplified SPPF with ReLU activation'''
    def __init__(self, in_channels, out_channels, kernel_size=5):
        super().__init__()
        c_ = in_channels // 2  # hidden channels
        self.cv1 = SimConv(in_channels, c_, 1, 1)
        self.cv2 = SimConv(c_ * 4, out_channels, 1, 1)
        self.m = nn.MaxPool2d(kernel_size=kernel_size, stride=1, padding=kernel_size // 2)
    def forward(self, x):
        x = self.cv1(x)
        with warnings.catch_warnings():
            warnings.simplefilter('ignore')
            y1 = self.m(x)
            y2 = self.m(y1)
            return self.cv2(torch.cat([x, y1, y2, self.m(y2)], 1))

1.4 ASPP(Atrous Spatial Pyramid Pooling)


受到SPP的启发,语义分割模型DeepLabv2中提出了ASPP模块(空洞空间卷积池化金字塔),该模块使用具有不同采样率的多个并行空洞卷积层。为每个采样率提取的特征在单独的分支中进一步处理,并融合以生成最终结果。该模块通过不同的空洞率构建不同感受野的卷积核,用来获取多尺度物体信息,具体结构比较简单如下图所示:

f2ae6442470a4c49a30fe678e83c9c79.png

ASPP是在DeepLab中提出来的,在后续的DeepLab版本中对其做了改进,如加入BN层、加入深度可分离卷积等,但基本的思路还是没变。

# without BN version
class ASPP(nn.Module):
    def __init__(self, in_channel=512, out_channel=256):
        super(ASPP, self).__init__()
        self.mean = nn.AdaptiveAvgPool2d((1, 1))  # (1,1)means ouput_dim
        self.conv = nn.Conv2d(in_channel,out_channel, 1, 1)
        self.atrous_block1 = nn.Conv2d(in_channel, out_channel, 1, 1)
        self.atrous_block6 = nn.Conv2d(in_channel, out_channel, 3, 1, padding=6, dilation=6)
        self.atrous_block12 = nn.Conv2d(in_channel, out_channel, 3, 1, padding=12, dilation=12)
        self.atrous_block18 = nn.Conv2d(in_channel, out_channel, 3, 1, padding=18, dilation=18)
        self.conv_1x1_output = nn.Conv2d(out_channel * 5, out_channel, 1, 1)
    def forward(self, x):
        size = x.shape[2:]
        image_features = self.mean(x)
        image_features = self.conv(image_features)
        image_features = F.upsample(image_features, size=size, mode='bilinear')
        atrous_block1 = self.atrous_block1(x)
        atrous_block6 = self.atrous_block6(x)
        atrous_block12 = self.atrous_block12(x)
        atrous_block18 = self.atrous_block18(x)
        net = self.conv_1x1_output(torch.cat([image_features, atrous_block1, atrous_block6,
                                              atrous_block12, atrous_block18], dim=1))
        return net


相关文章
|
6月前
|
机器学习/深度学习 编解码 边缘计算
YOLOv5改进 | 卷积模块 | 用ShuffleNetV2卷积替换Conv【轻量化网络】
本文介绍了如何在YOLOv5中用ShuffleNetV2替换卷积以减少计算量。ShuffleNetV2是一个轻量级网络,采用深度可分离卷积、通道重组和多尺度特征融合技术。文中提供了一个逐步教程,包括ShuffleNetV2模块的代码实现和在YOLOv5配置文件中的添加方法。此外,还分享了完整的代码链接和GFLOPs的比较,显示了GFLOPs的显著减少。该教程适合初学者实践,以提升深度学习目标检测技能。
YOLOv5改进 | 卷积模块 | 用ShuffleNetV2卷积替换Conv【轻量化网络】
|
4月前
|
机器学习/深度学习 计算机视觉
【YOLOv10改进-卷积Conv】RFAConv:感受野注意力卷积,创新空间注意力
【YOLO目标检测专栏】探索空间注意力局限,提出感受野注意力(RFA)机制,解决卷积核参数共享问题。RFAConv增强大尺寸卷积核处理能力,不增加计算成本,提升网络性能。已在YOLOv8中实现,详情见YOLO目标检测创新改进与实战案例专栏。
|
4月前
|
机器学习/深度学习 计算机视觉
【YOLOv10改进-卷积Conv】SCConv :即插即用的空间和通道重建卷积
YOLOv10专栏介绍了将Swin Transformer应用于目标检测的创新。Swin Transformer采用分层窗口结构,解决了视觉任务中的尺度变化问题,提供线性复杂度的效率提升。在图像分类、目标检测和语义分割任务中表现出色,超越先前最佳模型。YOLOv10结合Swin Transformer,利用其局部注意力机制和层次化设计,提升了检测性能。提供的代码片段展示了Swin Transformer模块,包括窗口划分、注意力计算和相对位置偏置。更多信息可在相关博客文章中找到。
|
4月前
|
机器学习/深度学习 编解码 计算机视觉
【YOLOv10改进-卷积Conv】 SPD-Conv空间深度转换卷积,处理低分辨率图像和小对象问题
YOLO目标检测专栏探讨了CNN在低分辨率和小目标检测中的局限性,提出SPD-Conv新架构,替代步长卷积和池化层,通过空间到深度层和非步长卷积保持细粒度信息。创新点包括消除信息损失、通用设计和性能提升。YOLOv5和ResNet应用SPD-Conv后,在困难任务上表现优越。详情见YOLO有效改进系列及项目实战目录。
|
5月前
|
计算机视觉
【YOLOv8改进】 SAConv(Switchable Atrous Convolution):可切换的空洞卷积
**DetectoRS是目标检测的先进网络,融合递归特征金字塔和可切换空洞卷积。递归金字塔在FPN基础上增加反馈,增强特征表示。SAC使用不同空洞率卷积并用开关函数融合,适应不同尺度目标。在COCO数据集上,DetectoRS达到55.7%的Box AP,48.5%的Mask AP和50.0%的
|
机器学习/深度学习 PyTorch 算法框架/工具
空间金字塔池化(Spatial Pyramid Pooling, SPP)原理和代码实现(Pytorch)
想直接看公式的可跳至第三节 3.公式修正 一、为什么需要SPP 首先需要知道为什么会需要SPP。 我们都知道卷积神经网络(CNN)由卷积层和全连接层组成,其中卷积层对于输入数据的大小并没有要求,唯一对数据大小有要求的则是第一个全连接层,因此基本上所有的CNN都要求输入数据固定大小,例如著名的VGG模型则要求输入数据大小是 (224*224) 。
2197 0
|
6月前
|
机器学习/深度学习 计算机视觉
YOLOv8改进 | 2023 | FocalModulation替换SPPF(精度更高的空间金字塔池化)
YOLOv8改进 | 2023 | FocalModulation替换SPPF(精度更高的空间金字塔池化)
324 2
|
6月前
|
机器学习/深度学习 计算机视觉
YOLOv5改进 | 2023 | FocalModulation替换SPPF(精度更高的空间金字塔池化)
YOLOv5改进 | 2023 | FocalModulation替换SPPF(精度更高的空间金字塔池化)
270 0
|
机器学习/深度学习 PyTorch 算法框架/工具
PyTorch: 池化-线性-激活函数层
PyTorch: 池化-线性-激活函数层
182 0
|
机器学习/深度学习
原始SPP及在YOLO中的SPP/SPPF对比详解
原始SPP及在YOLO中的SPP/SPPF对比详解
642 0