YOLOv5改进(六)--引入YOLOv8中C2F模块

文章目录

  • 1、前言
  • 2、C3模块和C2F模块
    • 2.1、C3模块
    • 2.2、BottleNeck模块
    • 2.3、C2F模块
  • 3、C2F代码实现
    • 3.1、common.py
    • 3.2、yolo.py
    • 3.3、yolov5s_C2F.yaml
  • 4、目标检测系列文章

1、前言

本文主要使用YOLOv8的C2F模块替换YOLOv5中的C3模块,经过实验测试,发现YOLOv5更加适合嵌入式设备,所以并不是越新的框架性能就会越好。通常大部分的目标检测模型都是在coco数据集上进行训练,然后再与旧的模型进行比较,如果只看在coco数据集上的表现确实v7、v8是要优于v5的,但是在自己数据集上面训练可能就是另外一种结果,所以可以尝试将不同模型的不同模块进行融合,试一试训练效果。

2、C3模块和C2F模块

2.1、C3模块

YOLOV5 采用C3模块,类似于残差结构的思想,C3模块由三个CBS模块,也就是三个卷积层,再加上若干个BottleNeck模块构成,输入进来的特征,分为两个部分,一部分特征是只经过CBS模块处理,一部分经过CBS+BottleNeck处理,最后通过concat将两部分特征进行拼接,再经过一个CBS层将特征维度进行恢复。

class C3(nn.Module):# CSP Bottleneck with 3 convolutionsdef __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansionsuper().__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c1, c_, 1, 1)self.cv3 = Conv(2 * c_, c2, 1)  # optional act=FReLU(c2)self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))def forward(self, x):return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))

YOLOv5-v6.0版本中使用了C3模块,替代了早期的BottleneckCSP模块。这两者结构作用基本相同,均为CSP架构,只是在修正单元的选择上有所不同,C3模块包含了3个标准卷积层以及多个Bottleneck模块,与BottleneckCSP模块所不同的是,C3经过Bottleneck模块输出后的Conv模块被去掉了。旧版本的yolov5的CSP模块如下:

2.2、BottleNeck模块

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

2.3、C2F模块

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

n个BottleNeck的特征融合方式很像FPN特征金字塔自顶向下融合,将深层特征与浅层特征进行融合 。

在这里插入图片描述

C2f 使用了3个卷积模块(ConV+BN+SILU),以及n个BottleNeck构成输入的特征经过Split之后通道数变为原来的一半(h ∗ w ∗ 0.5cout),一半的特征图不做处理,另外一半则是传入到BottleNeck模块中做特征融合操作,其结构图如下:

3、C2F代码实现

添加C2f和C2F_Bottleneck模块代码,因为YOLOv5和YOLOv8的Bottleneck模块不一致,这里直接拷贝YOLOv8源码的C2f和C2F_Bottleneck模块。

3.1、common.py

models/common.py的加入C2fC2F_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 channelsself.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, andexpansion."""super().__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, k[0], 1)self.cv2 = Conv(c_, c2, k[1], 1, g=g)self.add = shortcut and c1 == c2def 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.2、yolo.py

models/yolo.py的parse_model函数,添加C2f 模块

if m in [Conv, GhostConv, Bottleneck, GhostBottleneck, SPP, DWConv, MixConv2d, Focus, CrossConv, BottleneckCSP,C3, C2f]:

在这里插入图片描述

3.3、yolov5s_C2F.yaml

models文件夹新建一个yolov5s_C2F.yaml文件,将yolov5s所有的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、目标检测系列文章

  1. YOLOv5s网络模型讲解(一看就会)
  2. 生活垃圾数据集(YOLO版)
  3. YOLOv5如何训练自己的数据集
  4. 双向控制舵机(树莓派版)
  5. 树莓派部署YOLOv5目标检测(详细篇)
  6. YOLO_Tracking 实践 (环境搭建 & 案例测试)
  7. 目标检测:数据集划分 & XML数据集转YOLO标签
  8. DeepSort行人车辆识别系统(实现目标检测+跟踪+统计)
  9. YOLOv5参数大全(parse_opt篇)
  10. YOLOv5改进(一)-- 轻量化YOLOv5s模型
  11. YOLOv5改进(二)-- 目标检测优化点(添加小目标头检测)
  12. YOLOv5改进(三)-- 引进Focaler-IoU损失函数
  13. YOLOv5改进(四)–轻量化模型ShuffleNetv2
  14. YOLOv5改进(五)-- 轻量化模型MobileNetv3

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

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

相关文章

C++之类的三种继承修饰符(public、private、protected)总结

1、前言 前文博客介绍了修饰符public、private、protected在类中成员变量和函数访问权限限制的总结,主要如下: public(公有): 公有成员在类的内部和外部都可以被访问。 private(私有): 私有成员只能在类的内…

Qt xml学习之calculator-qml

1.功能说明:制作简易计算器 2.使用技术:qml,scxml 3.项目效果: 4.qml部分: import Calculator 1.0 //需要引用对应类的队友版本 import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 1.4 import QtScxml…

Linux 的权限

目录 Linux 的用户 root 用户 和 普通用户 如何新建普通用户? 如何切换用户? 一开始是以 root 用户登录: 一开始以普通用户登录: 如何删除用户? Linux文件权限 什么是读权限( r )&#…

vs2019 c++20 规范的 STL 库的智能指针 shared、unique 、weak 、auto 及 make_** 函数的源码注释汇总,和几个结论

智能指针的源码都在 《memory》 头文件中。因为头文件太长,再者本次整理是基于以前的零散的模板分析。故相当于抽取了该头文件中关于智能指针的源码进行分析,注释。 (1 探讨一)当独占指针指向数组时,其默认的删除器是…

ABP框架+Mysql(二)

展示页面--图书列表页面 本地化 开始的UI开发之前,我们首先要准备本地化的文本(这是你通常在开发应用程序时需要做的).本地化文本在前端页面会常用。 本地化文本位于 Acme.BookStore.Domain.Shared 项目的 Localization/BookStore 文件夹下: 打开 en.json (英文翻译)文件并更…

STM32-- GPIO->EXTI->NVIC中断

一、NVIC简介 什么是 NVIC ? NVIC 即嵌套向量中断控制器,全称 Nested vectored interrupt controller 。它 是内核的器件,所以它的更多描述可以看内核有关的资料。M3/M4/M7 内核都是支持 256 个中断,其中包含了 16 个系统中…

MySQL—函数—数值函数(基础)

一、引言 首先了解一下常见的数值函数哪些?并且直到它们的作用,并且演示这些函数的使用。 二、数值函数 常见的数值函数如下: 注意: 1、ceil(x)、floor(x) :向上、向下取整。 2、mod(x,y):模运算&#x…

CTF本地靶场搭建——GZ:CTF基础使用

GZ::CTF 是一个基于 ASP.NET Core 的开源 CTF 平台。 简介 GZ::CTF 是一个基于 ASP.NET Core 的开源 CTF 平台,采用 Docker 或 K8s 作为容器部署后端,提供了可自定义的题目类型、动态容器和动态分值功能。 本项目缘起于作者认为 CTFd 的实现不优雅&a…

Photoshop 首选项设置建议

Windows Ps菜单:编辑/首选项 Edit/Preferences 快捷键:Ctrl K macOS Ps菜单:Photoshop/首选项 Photoshop/Preferences 快捷键:Cmd K 对 Photoshop 的首选项 Preferences进行设置,可以提高修图与设计效率。下面是一些…

burp插件new_xp_capcha识别验证码的简易安装

1.new_xp_capcha 插件是大佬开发的可以正常白嫖,感谢大佬,我找了个不需要任何高级操作就可以做的安装手法,因为我在网上搜了一下就发现这个的安装过程攻略都还蛮复杂,我这里用了个简单的手法 2.安装 下载地址:smxia…

上网是不是必须路由器和光猫之一负责拨号?

链接:https://www.zhihu.com/question/624856022/answer/3245182557 上网并非一定要“拨号”,使用固定IP地址可以直接上网,不需要拨号。你们公司的宽带属于商用宽带,运营商(电信)给配置了固定的IP&#…

不同程序猿的六一表情

初级 中级高级资深#猿脑2.0

小程序模板开发与定制开发的对比

一、引言 随着移动互联网的快速发展,小程序作为一种轻量级的应用形态,已经深入到人们的日常生活和工作中。小程序以其无需安装、即用即走的特点,受到了广大用户的青睐。在小程序开发领域,模板开发和定制开发是两种常见的开发方式…

[补题记录]LeetCode 6.Z字形变换

传送门:Z字形变换 转自:Z字形变换 Thought/思路 关键点在于,最后的答案是一行行连接起来的。 这样我们就会发现,这个 Z 字,实际上会让行数 不断加 1,然后又 不断减 1。每次按顺序选择 S 中的一个字符即…

基于C#使用ACCESS数据库时遇到的问题记录

一、32位版本Office与64位AccessDatabaseEngine共存安装方法 1. 使用winrar、7zip等软件将AccessDatabaseEngine_X64.exe解压缩,得到AceRedist.msi和files14.cat2个文件 2. 下载Orca MSI编辑修改工具。安装后,使用Orca打开AceRedist.msi,找到…

IF:83.5!一作兼通讯,​Nature系列综述:可以吃的机器人!

在当今科技与生物工程快速融合的时代,传统领域之间的界限正在逐渐模糊,创造了许多前所未有的创新机会。机器人设计与食品加工这两个看似无关的研究领域,正在通过材料特性、制造工艺和功能的交叉融合,展现出巨大的潜力。 可食用机器…

Python 算法交易实验70 简单回顾

说明 感觉停滞了一段时间,本来qtv200应该在去年12月就迭代好了。回顾了一下原因: 1 工作的约束。因为量化现在是打辅助的角色(现在的工作还是比较香的),去年上了项目,几乎与世隔绝的那种,打断了整体的节奏。2 信心的…

各类封装函数代码

计算相关系数,Filter方法,并筛选特征 def feature_select_pearson(train, test):"""利用pearson系数进行相关性特征选择:param train:训练集:param test:测试集:return:经过特征选择后的训练集与测试集"""print(feature_select...)features = …

【每日刷题】Day54

【每日刷题】Day54 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 575. 分糖果 - 力扣(LeetCode) 2. 147. 对链表进行插入排序 - 力扣&#xf…

多源 BFS 详解

目录 一、多源与单源的区别 二、例题练习 2.1 例题1:01 矩阵 2.2 例题2:飞地的数量 2.3 例题3:地图中的最高点 2.4 例题4:地图分析 一、多源与单源的区别 单源最短路问题如何解决已经在上篇博客给出BFS 解决最短路问题&am…