【YOLOv5改进系列(7)】高效涨点----使用yolov8中的C2F模块替换yolov5中的C3模块

在这里插入图片描述


文章目录

  • 🚀🚀🚀前言
  • 一、1️⃣ C3模块和C2F模块详解
    • 1.1 🎓 C3模块
    • 1.2 ✨BottleNeck模块
    • 1.3 ⭐️C2F模块
  • 二、2️⃣添加C2f和C2F_Bottleneck模块代码
  • 三、3️⃣新建yolov5s_C2F.yaml文件
  • 四、4️⃣修改yolo.py中的parse_model函数
  • 五、5️⃣实验部分


在这里插入图片描述

👀🎉📜系列文章目录

【YOLOv5改进系列(1)】高效涨点----使用EIoU、Alpha-IoU、SIoU、Focal-EIOU替换CIou
【YOLOv5改进系列(2)】高效涨点----Wise-IoU详细解读及使用Wise-IoU(WIOU)替换CIOU
【YOLOv5改进系列(3)】高效涨点----Optimal Transport Assignment:OTA最优传输方法
【YOLOv5改进系列(4)】高效涨点----添加可变形卷积DCNv2
【YOLOv5改进系列(5)】高效涨点----添加密集小目标检测NWD方法
【YOLOv5改进系列(6)】高效涨点----使用DAMO-YOLO中的Efficient RepGFPN模块替换yolov5中的Neck部分

🚀🚀🚀前言

🚀这里解释一下为什么要使用yolov8中的C2F模块替换yolov5中的C3模块,可能在大家印象当中最新的模型要比旧的模型性能要好,其实博主在训练不同数据集的时候会发现yolov5的检测性能可能会优于v7甚至v8,因为目前大部分的目标检测模型都是在coco数据集上进行训练,然后再与旧的模型进行比较,如果只看在coco数据集上的表现确实v7、v8是要优于v5的,但是在自己数据集上面训练可能就是另外一种结果,所以可以尝试将不同模型的不同模块进行融合,试一试训练效果。我在钢轨疵点数据集上进行实验,添加了c2f模块之后的yolov5要比基准模型的map@50提高了2个百分点


一、1️⃣ C3模块和C2F模块详解

1.1 🎓 C3模块

这里解释一下为什么叫C3模块,因为是由三个CBS模块,也就是三个卷积层,再加上若干个BottleNeck模块构成,输入进来的特征,分为两个部分,一部分特征是只经过CBS模块处理,一部分经过CBS+BottleNeck处理,最后通过concat将两部分特征进行拼接,再经过一个CBS层将特征维度进行恢复。
在这里插入图片描述
YOLOv5-v6.0版本中使用了C3模块,替代了早期的BottleneckCSP模块。这两者结构作用基本相同,均为CSP架构,只是在修正单元的选择上有所不同,C3模块包含了3个标准卷积层以及多个Bottleneck模块,与BottleneckCSP模块所不同的是,经过Bottleneck模块输出后的Conv模块被去掉了。旧版本的yolov5的CSP模块如下:
在这里插入图片描述

1.2 ✨BottleNeck模块

在上面解释C3模块的时候,其中是有一个BottleNeck模块,该模块是类似与resnet残差结构,该模块其实存在两种形式,也就是BottleNeck1和BottleNeck2,BottleNeck1是以resnet残差结构连接的,该残差结构是由两条路构成,其中一路先进行1×1卷积将特征图的通道数减小一半,从而减少计算量,再通过3×3卷积提取特征,并且将通道数加倍,其输入与输出的通道数是不发生改变的,而另外一路通过shortcut进行残差连接,与第一路的输出特征图相加,从而实现特征融合;BottleNeck2只是经过一次1x1卷积的CBS和一次3x3卷积的CBS。
在这里插入图片描述

1.3 ⭐️C2F模块

在理解C2F模块模块的时候建议是先看第一幅图,通过CBS处理之后的特征首先进行Split分割成两部分特征一部分特征保留不做任何处理,一部分经过若干个BottleNeck进行处理其中每个BottleNeck又会分出两条通道,一条是将处理过的特征传递给下一个BottleNeck,一条则是保留下来用作后面的concat连接。最后经过n个BottleNeck之后将所有的特征进行融合。

📜有意思的是Split分出的这条线路和连接方式比较像残差连接结构(不知道这样解释对不对) ,n个BottleNeck的特征融合方式很像FPN特征金字塔自顶向下融合,将深层特征与浅层特征进行融合

在这里插入图片描述

✨✨✨详细的特征处理可以看下面这个结构图,输入的特征经过Split之后通道数变为原来的一半( h ∗ w ∗ 0.5 c o u t h*w*0.5 cout hw0.5cout),一半的特征图不做处理,另外一半则是传入到BottleNeck模块中做特征融合操作。
在这里插入图片描述

二、2️⃣添加C2f和C2F_Bottleneck模块代码

🔥🔥🔥🔥温馨提示:这里的C2f和C2F_Bottleneck其实是我直接从github上的yolov8源码拷贝下来的,修改了部分参数命名,在一开始我是打算直接使用yolov5中的Bottleneck模块,但是仔细阅读v5和v8中的Bottleneck模块发现还是有部分内容不一定,像卷积核大小设置,为了保证代码能够正常运行,所以在拷贝C2f的同时连同v8中的Bottleneck一块拷贝到yolov5中间。

📌首先找到models文件夹下common.py文件,在该文件的最后一行添加如下代码;分别是`C2f和C2F_Bottleneck``模块。

class C2f(nn.Module):
    """Faster Implementation of CSP Bottleneck with 2 convolutions."""

    def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):
        """Initialize CSP bottleneck layer with two convolutions with arguments ch_in, ch_out, number, shortcut, groups,
        expansion.
        """
        super().__init__()
        self.c = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, 2 * self.c, 1, 1)
        self.cv2 = Conv((2 + n) * self.c, c2, 1)  # optional act=FReLU(c2)
        self.m = nn.ModuleList(C2F_Bottleneck(self.c, self.c, shortcut, g, k=((3, 3), (3, 3)), e=1.0) for _ in range(n))

    def forward(self, x):
        """Forward pass through C2f layer."""
        y = list(self.cv1(x).chunk(2, 1))
        y.extend(m(y[-1]) for m in self.m)
        return self.cv2(torch.cat(y, 1))

    def forward_split(self, x):
        """Forward pass using split() instead of chunk()."""
        y = list(self.cv1(x).split((self.c, self.c), 1))
        y.extend(m(y[-1]) for m in self.m)
        return self.cv2(torch.cat(y, 1))


class C2F_Bottleneck(nn.Module):
    """Standard bottleneck."""

    def __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5):
        """Initializes a bottleneck module with given input/output channels, shortcut option, group, kernels, and
        expansion.
        """
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, c_, k[0], 1)
        self.cv2 = Conv(c_, c2, k[1], 1, g=g)
        self.add = shortcut and c1 == c2

    def forward(self, x):
        """'forward()' applies the YOLO FPN to input data."""
        return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))

三、3️⃣新建yolov5s_C2F.yaml文件

🔥在models文件夹新建一个yolov5s_C2F.yaml文件,因为我使用的yolov5s权重进行训练,然后将如下代码都拷贝到yolov5s_C2F.yaml文件当中,这里我将所有的C3模块都换成了C2f模块。

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license

# Parameters
nc: 6  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # 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] 输出640*640
  [ [ -1, 1, Conv, [ 64, 6, 2, 2 ] ],  # 0-P1/2 320*320    64表示输出的channel,但是需要乘以width_multiple,6表示卷积核的大小,2表示padding大小,2表示stride大小
    [ -1, 1, Conv, [ 128, 3, 2 ] ],  # 1-P2/4   160*160*128      2表示stride大小
    [ -1, 3, C2f, [ 128 ] ],
    [ -1, 1, Conv, [ 256, 3, 2 ] ],  # 3-P3/8   80*80*256
    [ -1, 6, C2f, [ 256 ] ],
    [ -1, 1, Conv, [ 512, 3, 2 ] ],  # 5-P4/16   40*40*512
    [ -1, 9, C2f, [ 512 ] ],
    [ -1, 1, Conv, [ 1024, 3, 2 ] ],  # 7-P5/32   20*20
    [ -1, 3, C2f, [ 1024 ] ],
    [ -1, 1, SPPF, [ 1024, 5 ] ],  # 9
  ]

# YOLOv5 v6.0 head
head:
  #  ================ 自下向上融合FPN =====================
  [ [ -1, 1, Conv, [ 512, 1, 1 ] ], # 降维 20*20*1024->20*20*512
    [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ], #上采样 20*20*512->40*40*512
    [ [ -1, 6 ], 1, Concat, [ 1 ] ],  # cat backbone P4 40*40*(512+512)
    [ -1, 3, C2f, [ 512, False ] ],  # 13             40*40*1024->40*40*512

    [ -1, 1, Conv, [ 256, 1, 1 ] ],         #40*40*512->40*40*256
    [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ],   # 40*40*256->80*80*256
    [ [ -1, 4 ], 1, Concat, [ 1 ] ],  # cat backbone P3 80*80*(256+256)
    [ -1, 3, C2f, [ 256, False ] ],  # 17 (P3/8-small) 80*80*512->80*80*256


    # ================ 自上向下融合PAN ==================
    [ -1, 1, Conv, [ 256, 3, 2 ] ],  # 80*80*256->40*40*256
    [ [ -1, 14 ], 1, Concat, [ 1 ] ],  # cat head P4  40*40*(256+256)
    [ -1, 3, C2f, [ 512, False ] ],  # 20 (P4/16-medium)

    [ -1, 1, Conv, [ 512, 3, 2 ] ],   #40*40*(256+256)-> 20*20*512
    [ [ -1, 10 ], 1, Concat, [ 1 ] ],  # cat head P5  20*20*(512+512)
    [ -1, 3, C2f, [ 1024, False ] ],  # 23 (P5/32-large)

    [ [ 17, 20, 23 ], 1, Detect, [ nc, anchors ] ],  # Detect(P3, P4, P5)
  ]

四、4️⃣修改yolo.py中的parse_model函数

models文件夹下面找到yolo.py文件,在该文件找到parse_model网络解析函数,然后添加C2f,添加内容如下:

在这里插入图片描述

五、5️⃣实验部分

yolov5基准模型训练结果:F1置信度分数为0.71、map@0.5=0.779;
在这里插入图片描述

使用C2F模块替换之后训练结果F1置信度分数为0.73、map@0.5=0.794
在这里插入图片描述
总结:使用yolov8中的C2F模块替换yolov5中的C3模块之后,F1置信分数和map@0.5都上涨了将近2个百分点。


在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Collction的三种遍历

目录 集合体系结构 迭代器遍历: 增强for遍历: Lambda表达式遍历 集合体系结构 List 系列集合 : 添加元素是有序的、可重复的,有索引的; 有序的:存和取的顺序是一样的; Set 系列集合 &#…

综合实验1

一、配置IP地址 [AR1]int g0/0/0 [AR1-GigabitEthernet0/0/0]ip add 192.168.1.254 24 [AR1-GigabitEthernet0/0/0]int se4/0/0 [AR1-Serial4/0/0]ip add 15.1.1.1 24 [AR1-Serial4/0/0] [AR2]int g0/0/0 [AR2-GigabitEthernet0/0/0]ip add 192.168.2.254 24 [AR2-Giga…

Sui与Revolut合作,加速Sui区块链教育和采用

作为全球一体化金融平台,Revolut与Sui合作推出了最新的加密货币学习课程。Revolut拥有全球超过4,000万用户,提供一系列数字银行产品和服务,包括购买和出售加密货币,其中包括SUI。 Revolut的学习计划为其用户提供有关Sui的教育&am…

蓝桥杯嵌入式学习笔记(7):ADC程序设计

目录 前言 1. ADC原理 1.1 主要特性 1.2 模拟输出电路图 2. 使用CubeMX进行源工程的配置 2.1 引脚配置 2.2 配置AD1 2.3 配置AD2 2.4 配置时钟 3. 代码编程 3.1 预备工作 3.2 bsp_adc.h文件编写 3.3 bsp_adc.c文件编写 3.4 main.c编写 3.4.1 时钟函数配置 3…

java子集(力扣Leetcode78)

子集 力扣原题链接 问题描述 给定一个整数数组 nums,数组中的元素互不相同。返回该数组所有可能的子集(幂集)。解集不能包含重复的子集。可以按任意顺序返回解集。 示例 示例 1: 输入:nums [1,2,3] 输出&#x…

python3将exe 转支持库错误 AssertionError: None does not smell like code

exe -> pyc包(*.exe_extracted) 安装反编译工具 exe反编译工具:pyinstxtractor.py下载:https://sourceforge.net/projects/pyinstallerextractor/ python pyinstxtractor.py hello.exe包反编译 懒的写!!! 这有详…

英语广场期刊投稿发表论文

《英语广场》是由国家新闻出版总署批准的正规期刊,杂志本着“轻松读原作,快乐学英语”的宗旨,倡导“寓学于乐”的学习理念,其活泼的办刊风格和优秀的文章选材受到读者特别是广大中学生的广泛欢迎,取得了良好的社会效益…

redis 的设计与实现(三)——对象

1. 前言: 在第一章节我们了解到了,redis底层所涉及的数据结构,但是这并非是离我们最近的一层,在此之上,redis实现了一层对象与我们交互。我们在本篇内容中将了解到: 对象对应的实现redis一些常用特性的实现…

数字化坚鹏:小熊电器面向数字化转型的大数据顶层设计实践培训

小熊电器面向数字化转型的大数据顶层设计实践培训圆满结束 ——努力打造“数据技术营销”三轮驱动的数字化领先企业 小熊电器股份有限公司由李一峰创立于2006年,是一家专业从事创意小家电研发、设计、生产和销售的实业型企业。2019年8月23日正式在深交所挂牌上市。…

rust使用Command库调用cmd命令或者shell命令,并支持多个参数和指定文件夹目录

想要在不同的平台上运行flutter doctor命令,就需要知道对应的平台是windows还是linux,如果是windows就需要调用cmd命令,如果是linux平台,就需要调用sh命令,所以可以通过cfg!实现不同平台的判断,然后调用不同…

【21-40】操作系统基础知识(非常详细)从零基础入门到精通,看完这一篇就够了

【21-40】操作系统基础知识(非常详细)从零基础入门到精通,看完这一篇就够了 以下是本文参考的资料 欢迎大家查收原版 本版本仅作个人笔记使用44、程序从堆中动态分配内存时,虚拟内存上怎么操作的45、常见的几种磁盘调度算法1. 先来…

codesys通过moudbus TCP连接西门子1214c,西门子做客户端

思路在codesys中发送数据到西门子,西门子原封不动的将数据传回。 1.首先配置codesys; 我设置了500个,但是好像发不这么多,只能120多个。因为什么来我忘了。但是这里不影响。 2.配置映射: 3.写代码 PROGRAM PLC_PRG VARarySendDa…

URL编码:原理、应用与安全性

title: URL编码:原理、应用与安全性 date: 2024/3/29 18:32:42 updated: 2024/3/29 18:32:42 tags: URL编码百分号编码特殊字符处理网络安全应用场景标准演变未来发展 在网络世界中,URL(统一资源定位符)是我们访问网页、发送请求…

Laya1.8.4 UI长按选择对应位置释放技能

需求: 需要实现拖拽摇杆选择技能释放位置,释放技能。 原理:首先拆分需求,分为两部分,UI部分和场景部分,UI部分需要实现长按效果,长按后又要有拖动效果,将官方文档的示例代码改了改…

HANA-公司间销售ICS-IDOC系统配置-保姆级配置文档

HANA公司间销售ICS-IDOC系统配置—保姆级配置文档 在项目实施过程中经常会遇到关联方交易的问题,有公司间采购的业务场景,也会存在公司间销售的业务场景,本文将着重讲解公司间销售在SAP系统中的实现场景。很多公司会在香港设置一个公司用于对外的销售接单,然后将接到的销售…

企业微信知识库:从了解到搭建的全流程

你是否也有这样的疑惑:为什么现在的企业都爱创建企业微信知识库?企业微信知识库到底有什么用?如果想要使用企业微信知识库企业应该如何创建?这就是我今天要探讨的问题,感兴趣的话一起往下看吧! | 为什么企业…

小白python爬虫基础教程(看这一篇就完了)

爬虫的五个步骤: 1)需求分析,找到需求相关的网址 2)获取网址的返回信息(urllib,requests) 3)定位需要的信息所在位置(re正则表达式,XPATH, CSS selector) 4&#xff…

argo rollout使用

一、前言 argorollout是比argocd更高级的发布工具,其中包含自动化金丝雀发布、自动化蓝绿发布、还可以通过argo命令或者dashboard查看发布的过程 二、使用 需要先部署argo rollout服务 参考:https://github.com/argoproj/argo-rollouts/tree/master/m…

关于web_server项目的学习记录(自用)

主要参考资料: 我在地铁吃闸机 基础处理框架:Multi-reactor muduo库有三个核心组件实现持续监听reactor的fd:channel;epoll/poller/eventloop类 channel 事件监听器epoll_ctl监听到了fd发生了什么事件,channel类会封装每个fd和fd感兴趣的事…

036—pandas 按行将列名根据值由大到小排序

前言 数据处理中,按行排列的列名可以提供更直观的数据探索和分析方式。 你可以逐行查看列名,了解每列的含义和特征,有助于更好地理解数据集的结构和内容。 需求: 需要增加一列「分布方式」,每行的值是本行基金名称对…