💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡
专栏目录 :《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有40+篇内容,内含各种Head检测头、损失函数Loss、Backbone、Neck、NMS等创新点改进——点击即可跳转
空间金字塔池化(SPP)在捕捉远程上下文信息以进行场景解析像素级预测任务中非常重要。对于一些大小相同的目标,检测对象几乎具有相同的大小。不需要通过不同的滤波器来获得不同视野的接受域。因此,提出了一种新的池化结构SPPFCSPC-G,将特征向量分为2个通道进行处理。一个通道使用分组1×1卷积进行处理,而另一个通道主要使用具有相同并行结构(5×5 MaxPool)的多个滤波器。此外,该分支(Group-Conv)中串联了多个1×1和3×3分组卷积,以提取图像中更复杂的特征。最后,将这两部分连接(Concat)在一起,每个卷积层Conv分为4组,以减少模型中的计算量。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改,并将修改后的完整代码放在文章的最后,方便大家一键运行,小白也可轻松上手实践。以帮助您更好地学习深度学习目标检测YOLO系列的挑战。
专栏地址:YOLOv8改进——更新各种有效涨点方法——点击即可跳转
目录
1.原理
2. 将SPPFCSPC添加到YOLOv8中
2.1 SPPFCSPC代码实现
2.2 更改init.py文件
2.3 新增yaml文件
2.4 注册模块
2.5 执行程序
3. 完整代码分享
4. GFLOPs
5. 进阶
6. 总结
1.原理
SPPFCSPC(Spatial Pyramid Pooling Faster Cross Stage Partial Channel)是一个旨在增强卷积神经网络能力的模块,特别是在物体检测任务中。以下是 SPPFCSPC 的关键原理和组件,详见提供的文档:
经典 SPP 结构:
-
SPP(Spatial Pyramid Pooling)用于提高模型对空间布局和物体变化的鲁棒性。它接受任意大小的输入图像,并通过一组池化操作提取空间特征信息以形成固定大小的特征图。然后可以将该特征图输入到全连接层中。
-
核心操作涉及多个具有不同感受野(5×5、9×9、13×13)的最大池化层。
SPPF(Spatial Pyramid Pooling Faster):
-
该结构是经典 SPP 的增强。 SPPF 使用较小的核心结构进行池化,从而产生二次池化以实现更丰富的特征融合。这通过将大内核尺寸替换为较小的内核尺寸,同时连接三个相同的较小池化组件,减少了计算负荷并提高了模型速度。
SimSPPF:
-
此简化版本的 SPPF 将激活函数 (SiLU) 替换为 ReLU,而不进行其他结构调整。
SPPCSPC (SPP Cross Stage Partial Channel):
-
由与最大池化层连接的多个卷积块 (CBS 模块) 组成的串行结构。这些最大池化层的感知范围设置为特定大小 (5×5、9×9、13×13)。
SPPFCSPC-G (SPPF Cross Stage Partial Channel-Group):
-
这是本文中提出的结构,将分组卷积块与经典的 SPP 方法相结合。
-
它结合了多个分组卷积块(包括 1×1 和 3×3 卷积)和三个具有相同感受野的串行最大池化层。
-
分组卷积将输入特征图分成几组(例如四组),并在每组内执行独立的卷积操作。通过将计算分布在不同组中,这减少了计算负载(FLOPS)和参数数量。
分组卷积:
-
分组卷积将输入通道分成多个组,通过仅在每组内独立执行卷积来减少操作数量。
-
这既降低了计算成本,又减少了参数数量,同时保持甚至增强了模型的表达能力。
性能和优势
-
参数效率:与其他变体(SPP、SPPF 等)相比,SPPFCSPC-G 模型的参数更少,使其在保持高性能的同时更高效。
-
计算负荷:使用分组卷积显著降低了计算负荷(以 GFLOPS 为单位),从而缩短了推理时间。
-
模型准确度:尽管参数和计算负荷减少,但 SPPFCSPC-G 在水稻病害识别任务中的准确度和其他性能指标方面仍优于其他模型。
结论
SPPFCSPC-G 模块通过集成分组卷积增强了传统的 SPP 方法,有效地平衡了模型复杂性和性能之间的权衡。这使其非常适合需要高效和准确特征提取的任务,例如图像中的物体检测。
2. 将SPPFCSPC添加到YOLOv8中
2.1 SPPFCSPC代码实现
关键步骤一:将下面代码粘贴到在/ultralytics/ultralytics/nn/modules/block.py中,并在该文件的__all__中添加“SPPFCSPC”
class SPPFCSPC(nn.Module):
def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5, k=5):
super(SPPFCSPC, self).__init__()
c_ = int(2 * c2 * e) # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = Conv(c1, c_, 1, 1)
self.cv3 = Conv(c_, c_, 3, 1)
self.cv4 = Conv(c_, c_, 1, 1)
self.m = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)
self.cv5 = Conv(4 * c_, c_, 1, 1)
self.cv6 = Conv(c_, c_, 3, 1)
self.cv7 = Conv(2 * c_, c2, 1, 1)
def forward(self, x):
x1 = self.cv4(self.cv3(self.cv1(x)))
x2 = self.m(x1)
x3 = self.m(x2)
y1 = self.cv6(self.cv5(torch.cat((x1, x2, x3, self.m(x3)), 1)))
y2 = self.cv2(x)
return self.cv7(torch.cat((y1, y2), dim=1))
SPPFCSPC(Spatial Pyramid Pooling Faster Cross Stage Partial Channel)的主要操作步骤可以分为以下几个阶段:
1. 数据输入和预处理
-
数据输入:输入预处理和增强后的图像数据。
-
数据预处理:包括调整图像大小、归一化、数据增强(如旋转、缩放、颜色变换等)。
2. 初始卷积层
-
卷积操作:初始卷积层对输入图像进行特征提取,生成特征图。这些层通常包含卷积、批量归一化和激活函数。
-
池化操作:对特征图进行池化操作(如最大池化),以减少特征图的尺寸和计算量。
3. SPP模块
-
空间金字塔池化(SPP):使用不同大小的池化核(如5x5、9x9、13x13)对特征图进行多尺度池化,生成固定尺寸的特征向量。SPP可以捕捉不同尺度的空间信息,使得模型对不同大小和比例的对象具有鲁棒性。
4. SPPF模块
-
快速空间金字塔池化(SPPF):通过多个小型的池化层(如三层3x3的最大池化)代替单个大核的池化操作,进一步丰富特征信息并减少计算开销。
5. Cross Stage Partial Network(CSPNet)
-
CSPNet模块:将特征图分成两部分,其中一部分直接通过残差连接到后续层,另一部分经过卷积操作后再合并。这样可以减少冗余梯度信息,提升梯度流动和特征复用能力。
6. SPPFCSPC模块
-
SPPFCSPC结构:结合SPPF和CSPNet的优势,采用分组卷积操作对特征图进行处理。分组卷积将输入特征图分成多个组,分别进行卷积操作,降低计算成本和参数量,同时保持高效特征提取。
-
多尺度特征融合:通过多尺度池化和分组卷积,实现多尺度特征融合,增强模型对不同尺度目标的检测能力。
7. 输出层
-
全连接层:将特征图展平并输入到全连接层,用于分类或回归任务。
-
分类器或回归器:根据具体任务(如图像分类或目标检测),采用相应的输出层进行预测。
通过以上步骤,SPPFCSPC模块能够高效提取多尺度特征,提高模型的检测精度和速度,适用于各种图像识别和检测任务。
2.2 更改init.py文件
关键步骤二:修改modules文件夹下的__init__.py文件,先导入函数
然后在下面的__all__中声明函数
2.3 新增yaml文件
关键步骤三:在 \ultralytics\ultralytics\cfg\models\v8下新建文件 yolov8_SPPFCSPC.yaml并将下面代码复制进去
# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect
# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'
# [depth, width, max_channels]
n: [0.33, 0.25, 1024] # YOLOv8n summary: 225 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPs
s: [0.33, 0.50, 1024] # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients, 28.8 GFLOPs
m: [0.67, 0.75, 768] # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients, 79.3 GFLOPs
l: [1.00, 1.00, 512] # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPs
x: [1.00, 1.25, 512] # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs
# YOLOv8.0n backbone
backbone:
# [from, repeats, module, args]
- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2
- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
- [-1, 3, C2f, [128, True]]
- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
- [-1, 6, C2f, [256, True]]
- [-1, 1, Conv, [512, 3, 2]] # 5-P4/16
- [-1, 6, C2f, [512, True]]
- [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32
- [-1, 3, C2f, [1024, True]]
- [-1, 1, SPPFCSPC, [1024, 5]] # 9
# YOLOv8.0n head
head:
- [-1, 1, nn.Upsample, [None, 2, "nearest"]]
- [[-1, 6], 1, Concat, [1]] # cat backbone P4
- [-1, 3, C2f, [512]] # 12
- [-1, 1, nn.Upsample, [None, 2, "nearest"]]
- [[-1, 4], 1, Concat, [1]] # cat backbone P3
- [-1, 3, C2f, [256]] # 15 (P3/8-small)
- [-1, 1, Conv, [256, 3, 2]]
- [[-1, 12], 1, Concat, [1]] # cat head P4
- [-1, 3, C2f, [512]] # 18 (P4/16-medium)
- [-1, 1, Conv, [512, 3, 2]]
- [[-1, 9], 1, Concat, [1]] # cat head P5
- [-1, 3, C2f, [1024]] # 21 (P5/32-large)
- [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5)
温馨提示:因为本文只是对yolov8基础上添加模块,如果要对yolov8n/l/m/x进行添加则只需要指定对应的depth_multiple 和 width_multiple。
# YOLOv8n
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.25 # layer channel multiple
# YOLOv8s
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
# YOLOv8l
depth_multiple: 1.0 # model depth multiple
width_multiple: 1.0 # layer channel multiple
# YOLOv8m
depth_multiple: 0.67 # model depth multiple
width_multiple: 0.75 # layer channel multiple
# YOLOv8x
depth_multiple: 1.33 # model depth multiple
width_multiple: 1.25 # layer channel multiple
2.4 注册模块
关键步骤四:在parse_model函数中进行注册,添加SPPFCSPC,
2.5 执行程序
在train.py中,将model的参数路径设置为yolov8_SPPFCSPC.yaml的路径
建议大家写绝对路径,确保一定能找到
from ultralytics import YOLO
# Load a model
# model = YOLO('yolov8n.yaml') # build a new model from YAML
# model = YOLO('yolov8n.pt') # load a pretrained model (recommended for training)
model = YOLO(r'/projects/ultralytics/ultralytics/cfg/models/v8/yolov8_SPPFCSPC.yaml') # build from YAML and transfer weights
# Train the model
model.train(device = [3], batch=16)
🚀运行程序,如果出现下面的内容则说明添加成功🚀
3. 完整代码分享
https://pan.baidu.com/s/1X4oze_EAIQw-bT-Oxc9Mvw?pwd=eayy
提取码: eayy
4. GFLOPs
关于GFLOPs的计算方式可以查看:百面算法工程师 | 卷积基础知识——Convolution
未改进的YOLOv8nGFLOPs
改进后的GFLOPs
5. 进阶
可以与其他的注意力机制或者损失函数等结合,进一步提升检测效果
6. 总结
SPPFCSPC(Spatial Pyramid Pooling Faster Cross Stage Partial Channel)模块的主要原理是通过结合多尺度空间金字塔池化(SPP)和改进的跨阶段部分网络(CSPNet)结构来增强卷积神经网络的特征提取能力。SPPFCSPC首先通过不同大小的池化核进行多尺度池化,捕捉图像中的多尺度信息,然后利用快速空间金字塔池化(SPPF)模块,通过多个小型池化操作丰富特征表达,同时降低计算成本。接着,模块采用分组卷积将特征图分成多个组,分别进行卷积操作,以减少参数量和计算开销。最后,通过CSPNet的部分跨阶段连接,有效提升梯度流动和特征复用能力,进一步增强模型的性能。总体而言,SPPFCSPC模块通过多尺度特征融合和高效的特征提取,显著提高了图像识别和检测任务的准确性和效率。