原始SPP及在YOLO中的SPP/SPPF对比详解

简介: 原始SPP及在YOLO中的SPP/SPPF对比详解

b7a98eb5a3354ae39870e6af321244e4.png在卷积神经网络中我们经常看到固定输入的设计,但是有的时候难以控制,何凯明大神的论文SPPNet中的SPP结构解决了该问题。

后续在YOLO系列中也出现了SPP结构及改进的结构,但是作用与最初的SPP结构却是不同的。

✨1 SPPNet中的SPP

原始SPP结构如下图所示:

67f7a3cf8aab4ee9a5c4ae4efcdf182d.png

下面默认通道数不变

首先输入Feature map(w,h,c)需要经过三个池化层:

k=(w, h, c)的池化层相当于将对整个图像取一次最大化操作,输出为(1, 1, c)的特征图。

k=(w/2, h/2, c)的池化层相当于将整个图像平均划分为4分,每一份取一次最大化操作,输出为(2, 2, c)的特征图。

k=(w/4, h/4, c)的池化层相当于将整个图像平均划分为16分,每一份取一次最大化操作,输出为(4, 4, c)的特征图。

然后将三个池化操作分别进行维度变换,再进行拼接操作。最终产生维度为(21, c)的向量。

通过上述两个步骤,可以看到我们的输入(w, h, c)不管如何变化,最终的输出都是(21, c)。

这里更多的是提供了一个思想,在不同网络中采用了不同的尝试,比如利用卷积层代替池化层等等…

✨2 YOLO中的SPP/SPPF

与上面何凯明大神提出的不同,这里的SPP虽然也叫SPP,但是作用更多的是实现局部特征和全局特征的featherMap级别的融合

🥓2.1 SPP

下面忽略了通道数的变化

eca2f2fd470048b4912be6dbf293e7f0.png

其中k(kernel_size)为卷积核尺寸。s(stride)为步长,p(padding)为在所有边界增加值。

可以看到与上面介绍的何凯明大神提出的SPP是不同的,输入Feature map(w, h, c)经过三次卷积操作像素并没有发生改变,作用更多的是实现局部特征和全局特征的featherMap级别的融合。

YOLO中的代码

class SPP(nn.Module):
    def __init__(self, c1, c2, k=(5, 9, 13)):  # 5,9,13分别是三个卷积操作的卷积核大小
        super().__init__()
        c_ = c1 // 2
        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))

💫2.2 SPPF

SPPF由yolo系列中的SPP结构改进而来,目的没有变化,只是从SPP改进为SPPF后,模型的计算量变小了很多,模型速度提升

YOLOV5中的SPPF结构:

忽略了通道数的变化

f1cc368b06df4856a2ecb998905a3405.png

其中Conv和Maxpool中第一个数(kernel_size)为卷积核尺寸。第二个数(stride)为步长,第三个数(padding)为在所有边界增加值。

YOLO V5代码:

class SPPF(nn.Module):
    """
        This code referenced to https://github.com/ultralytics/yolov5
    """
    def __init__(self, in_dim, out_dim, expand_ratio=0.5, pooling_size=5, act_type='lrelu', norm_type='BN'):
        super().__init__()
        inter_dim = int(in_dim * expand_ratio)
        self.out_dim = out_dim
        self.cv1 = Conv(in_dim, inter_dim, k=1, act_type=act_type, norm_type=norm_type)
        self.cv2 = Conv(inter_dim * 4, out_dim, k=1, act_type=act_type, norm_type=norm_type)
        self.m = nn.MaxPool2d(kernel_size=pooling_size, stride=1, padding=pooling_size // 2)
    def forward(self, x):
        x = self.cv1(x)
        y1 = self.m(x)
        y2 = self.m(y1)
        return self.cv2(torch.cat((x, y1, y2, self.m(y2)), 1))

从代码中可以看到其中进行的三次池化操作用到的均是统一个池化核。

相关文章
|
6月前
|
机器学习/深度学习 计算机视觉 网络架构
改进YOLOv8:添加CBAM注意力机制(涨点明显)
改进YOLOv8:添加CBAM注意力机制(涨点明显)
3655 1
|
6月前
YOLOv5改进 | Neck篇 | 2024.1最新MFDS-DETR的HS-FPN改进特征融合层(轻量化Neck、全网独家首发)
YOLOv5改进 | Neck篇 | 2024.1最新MFDS-DETR的HS-FPN改进特征融合层(轻量化Neck、全网独家首发)
482 4
|
6月前
|
机器学习/深度学习 编解码 边缘计算
YOLOv5改进 | 卷积模块 | 用ShuffleNetV2卷积替换Conv【轻量化网络】
本文介绍了如何在YOLOv5中用ShuffleNetV2替换卷积以减少计算量。ShuffleNetV2是一个轻量级网络,采用深度可分离卷积、通道重组和多尺度特征融合技术。文中提供了一个逐步教程,包括ShuffleNetV2模块的代码实现和在YOLOv5配置文件中的添加方法。此外,还分享了完整的代码链接和GFLOPs的比较,显示了GFLOPs的显著减少。该教程适合初学者实践,以提升深度学习目标检测技能。
YOLOv5改进 | 卷积模块 | 用ShuffleNetV2卷积替换Conv【轻量化网络】
|
6月前
|
机器学习/深度学习 编解码 算法
YOLOv5改进 | 主干网络 | 用EfficientNet卷积替换backbone【教程+代码 】
在YOLOv5的GFLOPs计算量中,卷积占了其中大多数的比列,为了减少计算量,研究人员提出了用EfficientNet代替backbone。本文给大家带来的教程是**将原来的主干网络替换为EfficientNet。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改,并将修改后的完整代码放在文章的最后,方便大家一键运行,小白也可轻松上手实践。以帮助您更好地学习深度学习目标检测YOLO系列的挑战。
|
机器学习/深度学习 PyTorch 算法框架/工具
空间金字塔池化(Spatial Pyramid Pooling, SPP)原理和代码实现(Pytorch)
想直接看公式的可跳至第三节 3.公式修正 一、为什么需要SPP 首先需要知道为什么会需要SPP。 我们都知道卷积神经网络(CNN)由卷积层和全连接层组成,其中卷积层对于输入数据的大小并没有要求,唯一对数据大小有要求的则是第一个全连接层,因此基本上所有的CNN都要求输入数据固定大小,例如著名的VGG模型则要求输入数据大小是 (224*224) 。
2188 0
|
6月前
|
算法框架/工具
使用MobileNetV3的PSPNet网络结构
使用MobileNetV3的PSPNet网络结构
37 1
|
6月前
|
计算机视觉
YOLOv5改进 | 2023Neck篇 | 利用Damo-YOLO的RepGFPN改进特征融合层
YOLOv5改进 | 2023Neck篇 | 利用Damo-YOLO的RepGFPN改进特征融合层
211 1
YOLOv5改进 | 2023Neck篇 | 利用Damo-YOLO的RepGFPN改进特征融合层
|
6月前
|
机器学习/深度学习 自动驾驶 计算机视觉
YOLOv8改进 | Neck篇 | Slim-Neck替换特征融合层实现超级涨点 (又轻量又超级涨点)
YOLOv8改进 | Neck篇 | Slim-Neck替换特征融合层实现超级涨点 (又轻量又超级涨点)
691 2
|
6月前
|
机器学习/深度学习 计算机视觉
YOLOv8改进 | 2023 | FocalModulation替换SPPF(精度更高的空间金字塔池化)
YOLOv8改进 | 2023 | FocalModulation替换SPPF(精度更高的空间金字塔池化)
316 2
|
6月前
|
机器学习/深度学习 自动驾驶 计算机视觉
YOLOv5改进 | Neck篇 | Slim-Neck替换特征融合层实现超级涨点 (又轻量又超级涨点)
YOLOv5改进 | Neck篇 | Slim-Neck替换特征融合层实现超级涨点 (又轻量又超级涨点)
465 0
YOLOv5改进 | Neck篇 | Slim-Neck替换特征融合层实现超级涨点 (又轻量又超级涨点)