YOLOv5改进 | 主干网络 | 用SimRepCSP作为主干网络提取特征【全网独家 + 降本增效】

news2024/11/26 15:51:33

💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡

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 主要原理

  1. 模块组合

    • 卷积模块:SimRepCSP 集成了标准的卷积模块。

    • 重新参数化卷积模块(RepConv):这些是专门设计的卷积层,通过增加模型参数来提高性能,而不会显著增加计算成本。

    • 跨阶段部分网络(CSP):该网络结构连接不同的模块,增强特征传播和网络学习能力。

  2. 结构和效率

    • SimRepCSP 通过组合三个卷积模块、一个 RepConv 模块和一个连接到 CSP 网络的级联模块构建而成。

    • 这些模块排列的目的是最大化特征提取和重用,从而在减少参数数量的情况下提升性能。

    • 每个卷积模块都包含批量归一化和 SiLU 激活函数。

  3. 与 YOLO 的集成

    • SimRepCSP 可以作为替代背骨集成到 YOLOv8 模型中,分别称为 SimRepCSPv1 和 SimRepCSPv2。这种集成旨在提升模型性能指标,相较于原始的 YOLOv8 背骨。

    • SimRepCSP 的架构包括一个焦点层、多层 SimRepCSP 模块和一个 SPPF(快速空间金字塔池化)模块,用于多尺度特征聚合。

  4. 实验结果

    • 在 GlobalWheat2020 数据集上进行的实验表明,带有 SimRepCSP 模块(SimRepCSPv1 和 SimRepCSPv2)的模型在减少训练和应用成本的同时,实现了更高的性能指标。

    • 主要改进包括减少了 FLOPS(每秒浮点运算次数)、GPU 内存使用量和整体模型重量,同时保持或提高了目标检测的准确性。

  5. 目标和优势

    • 降低计算成本:通过减少所需操作次数,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 主要流程:

  1. 输入图片预处理

    • 图片读取:从存储介质或摄像头读取输入图片。

    • 图片缩放:将图片缩放到模型所需的输入尺寸(例如,YOLOv8 通常使用 640x640 像素的输入大小)。

    • 归一化处理:将图片像素值归一化到 [0, 1] 区间。

  2. 特征提取(通过 SimRepCSP 模块)

    • 初始卷积和下采样:输入图片首先通过一个初始卷积层和下采样层,这有助于减少图片的空间尺寸并提取基本特征。

    • CSP 模块处理:图片特征进入多个 SimRepCSP 模块,每个模块由标准卷积、RepConv 和 CSP 网络组成。具体流程如下:

      • 标准卷积:标准卷积层提取局部特征。

      • RepConv:重新参数化卷积层在训练期间增强模型的表示能力。

      • CSP 网络:跨阶段部分网络将特征进行跨层传递和整合,进一步丰富特征表示。

  3. 多尺度特征提取

    • 特征金字塔网络(FPN):SimRepCSP 结合特征金字塔网络,提取不同尺度的特征以应对不同尺寸的目标物体。

    • 空间金字塔池化(SPPF):在 SimRepCSPv1 和 SimRepCSPv2 中引入 SPPF 模块,用于多尺度特征的聚合和增强。

  4. 特征融合与预测

    • 特征融合:将不同尺度的特征融合,生成最终的特征图。

    • 检测头:最终特征图传递给检测头,进行目标的分类和定位预测。检测头包括一系列的卷积层和激活函数,用于输出目标的类别和边界框坐标。

    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 模型的效率和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1797020.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

政安晨【零基础玩转各类开源AI项目】解析开源:IDM-VTON:改进真实虚拟试穿的扩散模型

目录 概述 要求 数据准备 服饰代码 推理 政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: 零基础玩转各类开源AI项目 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 项目地址&…

添加图片到资源文件,QPixmap ,QSplash的用法

实现1个QSplash加载之后&#xff0c;呈现主窗体的效果 1、创建资源文件&#xff0c;添加Splash.png文件 2、main.cpp 编码实现 将图像添加资源文件&#xff0c;复制文件的路径 main.cpp :/img/Splash.png 为资源的文件路径 #include "mainwindow.h" #include <…

Flink任务如何跑起来之 1.DataStream和Transformation

Flink任务如何跑起来之 1.DataStream和Transformation 1. 滥觞 在使用Flink完成业务功能之余&#xff0c;有必要了解下我们的任务是如何跑起来的。知其然&#xff0c;知其所以然。 既然重点是学习应用程序如何跑起来&#xff0c;那么应用程序的内容不重要&#xff0c;越简单…

【设计模式深度剖析】【4】【行为型】【策略模式】

文章目录 策略模式定义英文原话直译 角色类图策略接口Strategy&#xff1a;具体策略类上下文类Context测试类 策略模式的应用策略模式的优点策略模式的缺点策略模式的使用场景 策略模式 策略模式&#xff08;Strategy Pattern&#xff09; Strategy策略也称作Policy政策。 想…

快速搭建rtsp server(Ubuntu)

在现代视频监控和实时视频流媒体应用中&#xff0c;实时流协议&#xff08;RTSP&#xff09;服务器扮演着至关重要的角色。无论是家庭安防系统、企业级监控还是流媒体服务&#xff0c;RTSP服务器都能提供高效、稳定的解决方案。然而&#xff0c;对于许多初学者或开发者来说&…

单轮对话和多轮对话

参考&#xff1a;数据集对应关系说明 - 千帆大模型平台 | 百度智能云文档 (baidu.com) 什么是单轮对话 单轮对话和多轮对话是两种不同的对话形式&#xff0c;它们分别指的是在一次对话中只涉及一个问题和对应的回答&#xff0c;以及在一次对话中涉及多个问题和对应的回答。 …

【JMeter接口测试工具】第二节.JMeter基本功能介绍(上)【入门篇】

文章目录 前言一、获取所有学院信息接口执行二、线程组的介绍 2.1 并发和顺序执行 2.2 优先和最后执行线程组 2.3 线程组的设置细节三、HTTP请求的介绍四、查看结果树的配置使用总结 前言 一、获取所有学院信息接口执行 我们先针对一条简单的接口进行执行&#…

【Python报错】已解决AttributeError: ‘method‘ object has no attribute ‘xxx‘

解决Python报错&#xff1a;AttributeError: ‘method’ object has no attribute ‘xxx’ 在Python中&#xff0c;AttributeError通常表明你试图访问的对象没有你请求的属性或方法。如果你遇到了AttributeError: method object has no attribute xxx的错误&#xff0c;这通常意…

Mintegral数据洞察:全球中轻度游戏市场与创意更新频率

基于2024年3月大盘数据&#xff0c;汇量科技数据研究中心发现&#xff0c;超休闲品类仍是投流中轻度手游的中流砥柱。而投流力度较大的其他细分品类里&#xff0c;可以看到棋牌、模拟经营、非4X策略以及合成X游戏的身影&#xff0c;这些品类是近年来经常出现融合玩法的新兴赛道…

算法课程笔记——可撤销并查集

算法课程笔记——可撤销并查集 Gv

(学习笔记)数据基建-数据质量

数据基建-数据质量 数据质量数据质量保障措施如何推动上下游开展数据质量活动数据质量保障如何量化产出数据质量思考全链路数据质量保障项目 数据质量 概念&#xff1a;数据质量&#xff0c;意如其名&#xff0c;就是数据的准确性&#xff0c;他是数据仓库的基石&#xff0c;控…

【Java】static 类方法中注意事项

static 类方法中注意事项 目录 代码示例&#xff1a; package suziguang_d4_staticNote;public class Student {public int score 66;public static String name "zhangsan";// 1.类方法中可以直接访问类的成员&#xff0c;不可以直接访问实例成员public static v…

Unity Vuforia

首先在unity2019版本里可以在windows->PackageManager里搜Vuforia EngineAR; &#xff08;unity2021版本里搜不到&#xff09; 在官网注册账号&#xff1a; 添加识别图等&#xff1b; 将导出的unitypackage包导入unity中。 unity里导入package之后&#xff0c;新建场景&am…

【SpringBoot + Vue 尚庭公寓实战】房间支付方式管理接口实现(三)

【SpringBoot Vue 尚庭公寓实战】房间支付方式管理接口实现&#xff08;三&#xff09; 文章目录 【SpringBoot Vue 尚庭公寓实战】房间支付方式管理接口实现&#xff08;三&#xff09;1、查询全部支付方式列表2、保存或更新支付方式3、根据ID删除支付方式 房间支付方式管理…

C++设计模式——Adapter适配器模式

一&#xff0c;适配器模式简介 适配器模式是一种结构型设计模式&#xff0c;用于将已有接口转换为调用者所期望的另一种接口。 适配器模式让特定的API接口可以适配多种场景。例如&#xff0c;现有一个名为"Reader()"的API接口只能解析txt格式的文件&#xff0c;给这…

CF1553F Pairwise Modulo

#include<bits/stdc.h> #define int long long using namespace std; int n,s,ss,ma,l,r,a[300005],b[300005],c[300005]; //b 记录个数 //c 记录a[i]*k void insert(int x) {int yx;while(x<ma) b[x],x(x&-x); } void insert1(int x,int y) {while(x<ma) c[x]…

掌控数据流:深入解析 Java Stream 编程

Java 8 引入了一种新的抽象称为流&#xff08;Stream&#xff09;&#xff0c;它可以让你以一种声明的方式处理数据。Java 8 Stream API 可以极大提高 Java 程序员的生产力&#xff0c;使代码更简洁&#xff0c;更易读&#xff0c;并利用多核架构进行外部迭代。这里将详细介绍 …

电商核心技术系列58:电商平台的智能数据分析与业务洞察

相关系列文章 电商技术揭秘相关系列文章合集&#xff08;1&#xff09; 电商技术揭秘相关系列文章合集&#xff08;2&#xff09; 电商技术揭秘相关系列文章合集&#xff08;3&#xff09; 电商核心技术揭秘56&#xff1a;客户关系管理与忠诚度提升 电商核心技术揭秘57:数…

【python进阶】python图形化编程之美--tkinter模块初探

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

SwiftUI中GeometryReader与GeometryProxy的理解与使用

SwiftUI中的GeometryReader是一个视图&#xff0c;使用它我们可以很容易地访问父视图的大小和位置&#xff0c;并使用这些信息来创建一个响应式布局&#xff0c;以适应不同的设备和方向。 在本文中&#xff0c;我们将探索使用GeometryReader的好处&#xff0c;并提供一些如何在…