💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡
SimRepCSP 类似于 YOLOv7的主干网络,由卷积模块和重参数化卷积(RepConv)模块组合而成,以 Cross Stage Partial(CSP)网络作为模块之间的连接。通过将 SimRepCSP 作为替代主干纳入 YOLOv5,本文介绍了一种简单而有效的替代模块SimRepCSP 。在本文中,给大家带来的教程是在原来的主干网络修改为SimRepCSP 。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改,并将修改后的完整代码放在文章的最后,方便大家一键运行,小白也可轻松上手实践。以帮助您更好地学习深度学习目标检测YOLO系列的挑战。
专栏地址: YOLOv5改进+入门——持续更新各种有效涨点方法 点击即可跳转
目录
1. 原理
2. SimRepCSP的代码实现
2.1 将SimRepCSP添加到YOLOv5中
SimRepCSP 主要流程:
2.2 新增yaml文件
2.3 注册模块
2.4 执行程序
3. 完整代码分享
4. GFLOPs
5.总结
1. 原理
官方论文:Modified YOLO Model for Small Platform Application using SimRepCSP Module with Case Study——点击即可跳转
SimRepCSP 是一种针对 YOLO 模型的改进背骨模块,其设计旨在提高训练效率和模型性能,同时降低成本。以下是 SimRepCSP 的主要原理及其应用:
SimRepCSP 主要原理
-
模块组合:
-
卷积模块:SimRepCSP 集成了标准的卷积模块。
-
重新参数化卷积模块(RepConv):这些是专门设计的卷积层,通过增加模型参数来提高性能,而不会显著增加计算成本。
-
跨阶段部分网络(CSP):该网络结构连接不同的模块,增强特征传播和网络学习能力。
-
-
结构和效率:
-
SimRepCSP 通过组合三个卷积模块、一个 RepConv 模块和一个连接到 CSP 网络的级联模块构建而成。
-
这些模块排列的目的是最大化特征提取和重用,从而在减少参数数量的情况下提升性能。
-
每个卷积模块都包含批量归一化和 SiLU 激活函数。
-
-
与 YOLO 的集成:
-
SimRepCSP 可以作为替代背骨集成到 YOLOv8 模型中,分别称为 SimRepCSPv1 和 SimRepCSPv2。这种集成旨在提升模型性能指标,相较于原始的 YOLOv8 背骨。
-
SimRepCSP 的架构包括一个焦点层、多层 SimRepCSP 模块和一个 SPPF(快速空间金字塔池化)模块,用于多尺度特征聚合。
-
-
实验结果:
-
在 GlobalWheat2020 数据集上进行的实验表明,带有 SimRepCSP 模块(SimRepCSPv1 和 SimRepCSPv2)的模型在减少训练和应用成本的同时,实现了更高的性能指标。
-
主要改进包括减少了 FLOPS(每秒浮点运算次数)、GPU 内存使用量和整体模型重量,同时保持或提高了目标检测的准确性。
-
-
目标和优势:
-
降低计算成本:通过减少所需操作次数,SimRepCSP 旨在使模型更加高效。
-
增强参数性能:通过微调和优化参数来提高模型的准确性和有效性。
-
降低 GPU 内存成本:最小化内存需求以允许更大的批处理大小和更高效的训练。
-
减少模型重量:创建一个轻量级模型,便于部署而不影响性能。
-
总结
SimRepCSP 通过优化网络架构、减少计算和内存成本以及增强特征提取和参数调优,显著提高了 YOLO 模型的效率和性能。
2. SimRepCSP的代码实现
2.1 将SimRepCSP添加到YOLOv5中
关键步骤一: 将下面代码粘贴到/projects/yolov5-6.1/models/common.py文件中
*注:代码过长,请查看完整代码
class RepConv(nn.Module):
# Represented convolution
# https://arxiv.org/abs/2101.03697
def __init__(self, c1, c2, k=3, s=1, p=None, g=1, act=True, deploy=False):
super(RepConv, self).__init__()
self.deploy = deploy
self.groups = g
self.in_channels = c1
self.out_channels = c2
assert k == 3
assert autopad(k, p) == 1
padding_11 = autopad(k, p) - k // 2
self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity()) #
if deploy:
self.rbr_reparam = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=True)
else:
self.rbr_identity = (nn.BatchNorm2d(num_features=c1) if c2 == c1 and s == 1 else None)
self.rbr_dense = nn.Sequential(
nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False),
nn.BatchNorm2d(num_features=c2),
)
self.rbr_1x1 = nn.Sequential(
nn.Conv2d( c1, c2, 1, s, padding_11, groups=g, bias=False),
nn.BatchNorm2d(num_features=c2),
)
def forward(self, inputs):
if hasattr(self, "rbr_reparam"):
return self.act(self.rbr_reparam(inputs))
if self.rbr_identity is None:
id_out = 0
else:
id_out = self.rbr_identity(inputs)
return self.act(self.rbr_dense(inputs) + self.rbr_1x1(inputs) + id_out)
def get_equivalent_kernel_bias(self):
kernel3x3, bias3x3 = self._fuse_bn_tensor(self.rbr_dense)
kernel1x1, bias1x1 = self._fuse_bn_tensor(self.rbr_1x1)
kernelid, biasid = self._fuse_bn_tensor(self.rbr_identity)
return (
kernel3x3 + self._pad_1x1_to_3x3_tensor(kernel1x1) + kernelid,
bias3x3 + bias1x1 + biasid,
)
def _pad_1x1_to_3x3_tensor(self, kernel1x1):
if kernel1x1 is None:
return 0
else:
return nn.functional.pad(kernel1x1, [1, 1, 1, 1])
def _fuse_bn_tensor(self, branch):
if branch is None:
return 0, 0
if isinstance(branch, nn.Sequential):
kernel = branch[0].weight
running_mean = branch[1].running_mean
running_var = branch[1].running_var
gamma = branch[1].weight
beta = branch[1].bias
eps = branch[1].eps
else:
assert isinstance(branch, nn.BatchNorm2d)
if not hasattr(self, "id_tensor"):
input_dim = self.in_channels // self.groups
kernel_value = np.zeros(
(self.in_channels, input_dim, 3, 3), dtype=np.float32
)
for i in range(self.in_channels):
kernel_value[i, i % input_dim, 1, 1] = 1
SimRepCSP 主要流程:
-
输入图片预处理:
-
图片读取:从存储介质或摄像头读取输入图片。
-
图片缩放:将图片缩放到模型所需的输入尺寸(例如,YOLOv8 通常使用 640x640 像素的输入大小)。
-
归一化处理:将图片像素值归一化到 [0, 1] 区间。
-
-
特征提取(通过 SimRepCSP 模块):
-
初始卷积和下采样:输入图片首先通过一个初始卷积层和下采样层,这有助于减少图片的空间尺寸并提取基本特征。
-
CSP 模块处理:图片特征进入多个 SimRepCSP 模块,每个模块由标准卷积、RepConv 和 CSP 网络组成。具体流程如下:
-
标准卷积:标准卷积层提取局部特征。
-
RepConv:重新参数化卷积层在训练期间增强模型的表示能力。
-
CSP 网络:跨阶段部分网络将特征进行跨层传递和整合,进一步丰富特征表示。
-
-
-
多尺度特征提取:
-
特征金字塔网络(FPN):SimRepCSP 结合特征金字塔网络,提取不同尺度的特征以应对不同尺寸的目标物体。
-
空间金字塔池化(SPPF):在 SimRepCSPv1 和 SimRepCSPv2 中引入 SPPF 模块,用于多尺度特征的聚合和增强。
-
-
特征融合与预测:
-
特征融合:将不同尺度的特征融合,生成最终的特征图。
-
检测头:最终特征图传递给检测头,进行目标的分类和定位预测。检测头包括一系列的卷积层和激活函数,用于输出目标的类别和边界框坐标。
2.2 新增yaml文件
关键步骤二:在下/projects/yolov5-6.1/models下新建文件 yolov5_SimRepCSP.yaml并将下面代码复制进去
-
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
# Parameters
nc: 80 # number of classes
depth_multiple: 1 # model depth multiple
width_multiple: 1 # layer channel multiple
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
# YOLOv5 v6.0 backbone
backbone:
# [from, number, module, args]
[[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], #1 1-P2/4
[-1, 1, Conv, [64, 1, 1]], #2
[-1, 1, RepConv, [64, 3, 1]], #3
[[-1,-2], 1, Concat, [1]], #4
[-1, 1, Conv, [128, 1, 1]], #5
[-1, 1, Conv, [256, 3, 2]], #6/ 3-P3/8
[-1, 1, Conv, [128, 1, 1]], #7
[-1, 1, RepConv, [128, 3, 1]], #8
[[-1,-2], 1, Concat, [1]], #9
[-1, 1, Conv, [256, 1, 1]], #10 -P4/16
[-1, 1, Conv, [512, 3, 2]], #11
[-1, 1, Conv, [256, 1, 1]], #12
[-1, 1, RepConv, [256, 3, 1]], #13
[[-1,-2], 1, Concat, [1]], #14
[-1, 1, Conv, [512, 1, 1]], #15
[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 16
[-1, 1, Conv, [512, 1, 1]], #17
[-1, 1, RepConv, [512, 3, 1]], #18
[[-1,-2], 1, Concat, [1]], #19
[-1, 1, Conv, [1024, 1, 1]], #20
[-1, 1, SPPF, [1024, 5]], # 21
]
# YOLOv5 v6.0 head
head:
[[-1, 1, Conv, [512, 1, 1]], #22
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 11], 1, Concat, [1]], # cat backbone P4
[-1, 3, C3, [512, False]], # 25
[-1, 1, Conv, [256, 1, 1]], #26
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], #28 cat backbone P3
[-1, 3, C3, [256, False]], # 29 (P3/8-small)
[-1, 1, Conv, [256, 3, 2]],
[[-1,26], 1, Concat, [1]], # 31 cat head P4
[-1, 3, C3, [512, False]], # 32 (P4/16-medium)
[-1, 1, Conv, [512, 3, 2]],
[[-1, 22], 1, Concat, [1]], #34 cat head P5
[-1, 3, C3, [1024, False]], #35 (P5/32-large)
[[29, 32, 35], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
温馨提示:本文只是对yolov5l基础上添加模块,如果要对yolov5n/l/m/x进行添加则只需要指定对应的depth_multiple 和 width_multiple。
# YOLOv5n
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.25 # layer channel multiple
# YOLOv5s
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
# YOLOv5l
depth_multiple: 1.0 # model depth multiple
width_multiple: 1.0 # layer channel multiple
# YOLOv5m
depth_multiple: 0.67 # model depth multiple
width_multiple: 0.75 # layer channel multiple
# YOLOv5x
depth_multiple: 1.33 # model depth multiple
width_multiple: 1.25 # layer channel multiple
2.3 注册模块
关键步骤三:在yolo.py中注册, 大概在260行左右添加 ‘RepConv’
2.4 执行程序
在train.py中,将cfg的参数路径设置为yolov5_SimRepCSP.yaml的路径
建议大家写绝对路径,确保一定能找到
🚀运行程序,如果出现下面的内容则说明添加成功🚀
3. 完整代码分享
https://pan.baidu.com/s/17lq0bRONXbtMRgAalj77gA?pwd=39uq
提取码: 39uq
4. GFLOPs
关于GFLOPs的计算方式可以查看:百面算法工程师 | 卷积基础知识——Convolution
未改进的GFLOPs
改进后的GFLOPs
5.总结
SimRepCSP 是一种针对 YOLO 模型的改进backbone模块,其设计旨在提高训练效率和模型性能,同时降低成本。它通过集成标准卷积模块、重新参数化卷积模块(RepConv)和跨阶段部分网络(CSP)来增强特征传播和网络学习能力。SimRepCSP 的结构包括三个卷积模块、一个 RepConv 模块和一个连接到 CSP 网络的级联模块,这些模块的排列旨在最大化特征提取和重用,从而在减少参数数量的情况下提升性能。每个卷积模块都包含批量归一化和 SiLU 激活函数。SimRepCSP 可以作为替代backbone集成到 YOLOv5 模型中,分别称为 SimRepCSPv1 和 SimRepCSPv2,这种集成旨在提升模型性能指标,相较于原始的backbone。SimRepCSP 的架构包括一个焦点层、多层 SimRepCSP 模块和一个 SPPF(快速空间金字塔池化)模块,用于多尺度特征聚合。带有 SimRepCSP 模块的模型在减少训练和应用成本的同时,实现了更高的性能指标,主要改进包括减少了 FLOPS(每秒浮点运算次数)、GPU 内存使用量和整体模型重量,同时保持或提高了目标检测的准确性。SimRepCSP 的目标和优势在于通过减少所需操作次数降低计算成本,通过微调和优化参数增强参数性能,最小化内存需求以允许更大的批处理大小和更高效的训练,并创建一个轻量级模型,便于部署而不影响性能。总体而言,SimRepCSP 通过优化网络架构、减少计算和内存成本以及增强特征提取和参数调优,显著提高了 YOLO 模型的效率和性能。