YOLOv9改进策略【模型轻量化】| ShufflenetV2,通过通道划分构建高效网络

一、本文介绍

本文记录的是基于ShufflenetV2的YOLOv9目标检测轻量化改进方法研究FLOPs是评价模型复杂独的重要指标,但其无法考虑到模型的内存访问成本和并行度,因此本文在YOLOv9的基础上引入ShufflenetV2使其在在保持准确性的同时提高模型的运行效率

模型参数量计算量推理速度(bs=32)
YOLOv9-c50.69M236.6GFLOPs32.1ms
Improved42.88M194.5GFLOPs23.2ms

文章目录

  • 一、本文介绍
  • 二、ShuffleNet V2设计原理
  • 三、ShuffleNet V2基础模块的实现代码
  • 四、添加步骤
    • 4.1 修改common.py
    • 4.2 修改yolo.py
  • 五、yaml模型文件
    • 5.1 模型改进⭐
  • 六、成功运行结果


二、ShuffleNet V2设计原理

ShuffleNet V2是一种高效的卷积神经网络架构,其模型结构及优势如下:

  1. 模型结构
    • 回顾ShuffleNet v1ShuffleNet是一种广泛应用于低端设备的先进网络架构,为增加在给定计算预算下的特征通道数量,采用了点组卷积和瓶颈结构,但这增加了内存访问成本(MAC),且过多的组卷积和元素级“Add”操作也存在问题。
    • 引入Channel Split和ShuffleNet V2:为解决上述问题,引入了名为Channel Split的简单操作。在每个单元开始时,将 c c c个特征通道的输入分为两个分支,分别具有 c − c ′ c - c' cc c ′ c' c个通道。一个分支保持不变,另一个分支由三个具有相同输入和输出通道的卷积组成,以满足G1(平衡卷积,即相等的通道宽度可最小化MAC)。两个 1 × 1 1 \times 1 1×1卷积不再是组式的,这部分是为了遵循G2(避免过多的组卷积增加MAC),部分是因为拆分操作已经产生了两个组。卷积后,两个分支连接,通道数量保持不变,并使用与ShuffleNet v1相同的“通道洗牌”操作来实现信息通信。对于空间下采样,单元进行了略微修改,删除了通道拆分操作,使输出通道数量加倍。
    • 整体网络结构:通过反复堆叠构建块来构建整个网络,设置 c ′ = c / 2 c' = c/2 c=c/2,整体网络结构与ShuffleNet v1相似,并在全局平均池化之前添加了一个额外的 1 × 1 1 \times 1 1×1卷积层来混合特征。
  2. 优势
    • 高效且准确:遵循了高效网络设计的所有准则,每个构建块的高效率使其能够使用更多的特征通道和更大的网络容量,并且在每个块中,一半的特征通道直接通过块并加入下一个块,实现了一种特征重用模式,类似于DenseNet,但更高效。
    • 速度优势明显:在与其他网络架构的比较中,ShuffleNet v2在速度方面表现出色,特别是在GPU上明显快于其他网络(如MobileNet v2、ShuffleNet v1和Xception)。在ARM上,ShuffleNet v1、Xception和ShuffleNet v2的速度相当,但MobileNet v2较慢,这是因为MobileNet v2的MAC较高。
    • 兼容性好:可以与其他技术(如Squeeze - and - excitation模块)结合进一步提高性能。

论文:https://arxiv.org/pdf/1807.11164.pdf
源码:https://gitcode.com/gh_mirrors/sh/ShuffleNet-Series/blob/master/ShuffleNetV2/blocks.py?utm_source=csdn_github_accelerator&isLogin=1

三、ShuffleNet V2基础模块的实现代码

ShuffleNet V2基础模块的实现代码如下:

def channel_shuffle(x, groups):batchsize, num_channels, height, width = x.data.size()channels_per_group = num_channels // groups# reshapex = x.view(batchsize, groups,channels_per_group, height, width)x = torch.transpose(x, 1, 2).contiguous()# flattenx = x.view(batchsize, -1, height, width)return xclass conv_bn_relu_maxpool(nn.Module):def __init__(self, c1, c2):  # ch_in, ch_outsuper(conv_bn_relu_maxpool, self).__init__()self.conv = nn.Sequential(nn.Conv2d(c1, c2, kernel_size=3, stride=2, padding=1, bias=False),nn.BatchNorm2d(c2),nn.ReLU(inplace=True),)self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)def forward(self, x):return self.maxpool(self.conv(x))class Shuffle_Block(nn.Module):def __init__(self, inp, oup, stride):super(Shuffle_Block, self).__init__()if not (1 <= stride <= 3):raise ValueError('illegal stride value')self.stride = stridebranch_features = oup // 2assert (self.stride != 1) or (inp == branch_features << 1)if self.stride > 1:self.branch1 = nn.Sequential(self.depthwise_conv(inp, inp, kernel_size=3, stride=self.stride, padding=1),nn.BatchNorm2d(inp),nn.Conv2d(inp, branch_features, kernel_size=1, stride=1, padding=0, bias=False),nn.BatchNorm2d(branch_features),nn.ReLU(inplace=True),)self.branch2 = nn.Sequential(nn.Conv2d(inp if (self.stride > 1) else branch_features,branch_features, kernel_size=1, stride=1, padding=0, bias=False),nn.BatchNorm2d(branch_features),nn.ReLU(inplace=True),self.depthwise_conv(branch_features, branch_features, kernel_size=3, stride=self.stride, padding=1),nn.BatchNorm2d(branch_features),nn.Conv2d(branch_features, branch_features, kernel_size=1, stride=1, padding=0, bias=False),nn.BatchNorm2d(branch_features),nn.ReLU(inplace=True),)@staticmethoddef depthwise_conv(i, o, kernel_size, stride=1, padding=0, bias=False):return nn.Conv2d(i, o, kernel_size, stride, padding, bias=bias, groups=i)def forward(self, x):if self.stride == 1:x1, x2 = x.chunk(2, dim=1)  # 按照维度1进行splitout = torch.cat((x1, self.branch2(x2)), dim=1)else:out = torch.cat((self.branch1(x), self.branch2(x)), dim=1)out = channel_shuffle(out, 2)return out

四、添加步骤

4.1 修改common.py

此处需要修改的文件是models/common.py

common.py中定义了网络结构的通用模块,我们想要加入新的模块就只需要将模块代码放到这个文件内即可。

此时需要将上方实现的代码添加到common.py中。

在这里插入图片描述

注意❗:在4.2小节中的yolo.py文件中需要声明的模块名称为:conv_bn_relu_maxpoolShuffle_Block

4.2 修改yolo.py

此处需要修改的文件是models/yolo.py

yolo.py用于函数调用,我们只需要将common.py中定义的新的模块名添加到parse_model函数下即可。

conv_bn_relu_maxpool模块以及Shuffle_Block模块添加后如下:

在这里插入图片描述


五、yaml模型文件

5.1 模型改进⭐

在代码配置完成后,配置模型的YAML文件。

此处以models/detect/yolov9-c.yaml为例,在同目录下创建一个用于自己数据集训练的模型文件yolov9-c-shufflenetv2.yaml

yolov9-c.yaml中的内容复制到yolov9-c-shufflenetv2.yaml文件下,修改nc数量等于自己数据中目标的数量。

📌 模型的修改方法是将YOLOv9的骨干网络替换成Shufflenet V2ShuffleNet V2 在设计上注重减少内存访问成本并提高并行度,这有助于在保持准确性的同时提高模型的运行效率。相比YOLOv9原骨干网络,ShuffleNet V2 具有更低的计算复杂度,能够在相同或更少的计算资源下完成推理,对于实时性要求较高的任务具有重要意义。

结构如下:

# YOLOv9# parameters
nc: 1  # number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()# anchors
anchors: 3# YOLOv9 backbone
backbone:[[-1, 1, Silence, []],  # conv down[-1, 1, conv_bn_relu_maxpool, [64, 3, 2]],  # 1-P1/2# conv down[-1, 1, Shuffle_Block, [ 128, 2 ]],  # 2-P2/4[-1, 3, Shuffle_Block, [ 128, 1 ]],  # 3[-1, 1, Shuffle_Block, [ 256, 2 ]],  # 4-P4/16 [-1, 7, Shuffle_Block, [ 256, 1 ]],  # 5[-1, 1, Shuffle_Block, [ 512, 2 ]],  # 6-P4/16[-1, 3, Shuffle_Block, [ 512, 1 ]],  # 7]# YOLOv9 head
head:[# elan-spp block[-1, 1, SPPELAN, [512, 256]],  # 10# up-concat merge[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 5], 1, Concat, [1]],  # cat backbone P4# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 13# up-concat merge[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 3], 1, Concat, [1]],  # cat backbone P3# elan-2 block[-1, 1, RepNCSPELAN4, [256, 256, 128, 1]],  # 16 (P3/8-small)# avg-conv-down merge[-1, 1, ADown, [256]],[[-1, 11], 1, Concat, [1]],  # cat head P4# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 19 (P4/16-medium)# avg-conv-down merge[-1, 1, ADown, [512]],[[-1, 8], 1, Concat, [1]],  # cat head P5# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 22 (P5/32-large)# multi-level reversible auxiliary branch# routing[3, 1, CBLinear, [[256]]], # 23[5, 1, CBLinear, [[256, 512]]], # 24[7, 1, CBLinear, [[256, 512, 512]]], # 25# conv down[0, 1, Conv, [64, 3, 2]],  # 26-P1/2# conv down[-1, 1, Conv, [128, 3, 2]],  # 27-P2/4# elan-1 block[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 28# avg-conv down fuse[-1, 1, ADown, [256]],  # 29-P3/8[[21, 22, 23, -1], 1, CBFuse, [[0, 0, 0]]], # 30  # elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 31# avg-conv down fuse[-1, 1, ADown, [512]],  # 32-P4/16[[22, 23, -1], 1, CBFuse, [[1, 1]]], # 33 # elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 34# avg-conv down fuse[-1, 1, ADown, [512]],  # 35-P5/32[[23, -1], 1, CBFuse, [[2]]], # 36# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 37# detection head# detect[[29, 32, 35, 14, 17, 20], 1, DualDDetect, [nc]],  # DualDDetect(A3, A4, A5, P3, P4, P5)]

六、成功运行结果

分别打印网络模型可以看到Shuffle_Block已经加入到模型中,并可以进行训练了。

yolov9-c-shufflenetv2

                 from  n    params  module                                  arguments                     0                -1  1         0  models.common.Silence                   []                            1                -1  1      1856  models.common.conv_bn_relu_maxpool      [3, 64]                       2                -1  1     14080  models.common.Shuffle_Block             [64, 128, 2]                  3                -1  3     27456  models.common.Shuffle_Block             [128, 128, 1]                 4                -1  1     52736  models.common.Shuffle_Block             [128, 256, 2]                 5                -1  7    242816  models.common.Shuffle_Block             [256, 256, 1]                 6                -1  1    203776  models.common.Shuffle_Block             [256, 512, 2]                 7                -1  3    404736  models.common.Shuffle_Block             [512, 512, 1]                 8                -1  1    656896  models.common.SPPELAN                   [512, 512, 256]               9                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          10           [-1, 5]  1         0  models.common.Concat                    [1]                           11                -1  1   2988544  models.common.RepNCSPELAN4              [768, 512, 512, 256, 1]       12                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          13           [-1, 3]  1         0  models.common.Concat                    [1]                           14                -1  1    814336  models.common.RepNCSPELAN4              [640, 256, 256, 128, 1]       15                -1  1    164352  models.common.ADown                     [256, 256]                    16          [-1, 11]  1         0  models.common.Concat                    [1]                           17                -1  1   2988544  models.common.RepNCSPELAN4              [768, 512, 512, 256, 1]       18                -1  1    656384  models.common.ADown                     [512, 512]                    19           [-1, 8]  1         0  models.common.Concat                    [1]                           20                -1  1   3119616  models.common.RepNCSPELAN4              [1024, 512, 512, 256, 1]      21                 3  1     33024  models.common.CBLinear                  [128, [256]]                  22                 5  1    197376  models.common.CBLinear                  [256, [256, 512]]             23                 7  1    656640  models.common.CBLinear                  [512, [256, 512, 512]]        24                 0  1      1856  models.common.Conv                      [3, 64, 3, 2]                 25                -1  1     73984  models.common.Conv                      [64, 128, 3, 2]               26                -1  1    212864  models.common.RepNCSPELAN4              [128, 256, 128, 64, 1]        27                -1  1    164352  models.common.ADown                     [256, 256]                    28  [21, 22, 23, -1]  1         0  models.common.CBFuse                    [[0, 0, 0]]                   29                -1  1    847616  models.common.RepNCSPELAN4              [256, 512, 256, 128, 1]       30                -1  1    656384  models.common.ADown                     [512, 512]                    31      [22, 23, -1]  1         0  models.common.CBFuse                    [[1, 1]]                      32                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]       33                -1  1    656384  models.common.ADown                     [512, 512]                    34          [23, -1]  1         0  models.common.CBFuse                    [[2]]                         35                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]       36[29, 32, 35, 14, 17, 20]  1  21542822  models.yolo.DualDDetect                 [1, [512, 512, 512, 256, 512, 512]]
yolov9-c-shufflenetv2 summary: 870 layers, 43094374 parameters, 43094342 gradients, 195.9 GFLOPs

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

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

相关文章

多线程篇(基本认识 - 锁优化)(持续更新迭代)

目录 一、前言 二、阿里开发手册 三、synchronized 锁优化的背景 四、Synchronized的性能变化 1. Java5之前&#xff1a;用户态和内核态之间的切换 2. java6开始&#xff1a;优化Synchronized 五、锁升级 1. 无锁 2. 偏向锁 2.1. 前言 2.2. 什么是偏向锁 2.3. 偏向…

ChatTTS 长音频合成和本地部署2种方式,让你的“儿童绘本”发声的实战教程(文末有福利)

接上文&#xff08;GLM-4-Flash 大模型 API 免费了&#xff0c;手把手构建“儿童绘本”应用实战&#xff08;附源码&#xff09;&#xff09;&#xff0c;老牛同学通过 GLM-4-Flash 文生文和 CogView-3 文生图大模型&#xff0c;和大家一起编写了一个图文并茂的儿童绘本应用&am…

从默默无名到销量激增,极越CEO哭了

文 | 智能相对论 作者 | 周晚 8月28日&#xff0c;极越汽车CEO夏一平在接受媒体采访的时候泪洒当场&#xff01; 倒不是因为极越汽车销量寥寥&#xff0c;而是因为突然销量激增&#xff0c;他带领的极越团队走出低谷&#xff0c;当他们回过头去看今年上半年的巨大压力&#…

欧拉 函数

互质&#xff1a; 互质是公约数只有1的两个整数&#xff0c;叫做互质整数。公约数只有1的两个自然数&#xff0c;叫做互质自然数&#xff0c;后者是前者特殊情况。 &#xff08;1和-1与所有整数互质&#xff0c;而且它们是唯一与0互质的整数&#xff09; 互质的判断方法&…

1500+ HuggingFace API token暴露,使数百万 Meta-Llama、Bloom 等大模型用户面临风险

HugginingFace 和 GitHub 是AI开发人员的重要平台&#xff0c;因此我们决定对这些平台做更为深入的研究。在这项研究中&#xff0c;我们发现了数以千计的 API 令牌&#xff0c;这些令牌暴露给恶意行为者&#xff0c;使数百万最终用户可能受到攻击。 本文的主要内容包括&#x…

MySQL高阶练习题1- 寻找面试候选人

目录 题目 准备数据 分析数据 实现代码 总结 题目 返回 所有面试候选人 的姓名 name 和邮件 mail 。当用户满足以下两个要求中的 任意一条 &#xff0c;其成为 面试候选人 : 该用户在 连续三场及更多 比赛中赢得 任意 奖牌。该用户在 三场及更多不同的 比赛中赢得 金牌&…

python实战三-提取Word数据到Excel

视频源码&#xff1a; 链接&#xff1a;https://pan.quark.cn/s/83db5bb15383 一个文件夹下有大量会议通知文件&#xff0c;为word文件&#xff0c;文件格式都是一致的&#xff0c;现在要将文件中的一些字段提取出来汇总到Excel文件中。 会议通知文件格式如下&#xff1a; 要提…

C++(1)基础语法

C(1)之基础语法 Author: Once Day Date: 2024年8月29日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: 源码分析_Once-Day的博客-CSDN博客 参考文…

通用后台管理系统实战演示(Vue3 + element-plus)汇总篇一

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

【Windows学习笔记】1:OneCore和Windows API

1 OneCore 主流Windows跑在PC上&#xff0c;Xbox跑的是从Windows 2000分支出来的版本&#xff0c;Windows Phone跑的是基于Windows CE&#xff08;实时操作系统&#xff09;的版本。 为了维护和扩展这些code方便&#xff0c;微软将kernels和base platform集成在一起叫OneCore…

宿舍|基于SprinBoot+vue的宿舍管理系统(源码+数据库+文档)

宿舍管理系统 基于SprinBootvue的私人诊所管理系统 一、前言 二、系统设计 三、系统功能设计 系统功能实现 后台模块实现 管理员功能实现 学生功能实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&…

【计算机组成原理】六、总线:3.操作和定时

5.操作和定时 文章目录 5.操作和定时5.1总线传输的四个阶段5.2总线定时5.2.1同步通信5.2.2异步通信5.2.3半同步通信5.2.4分离式通信 2.3按时序控制方式 同步总线异步总线 5.1总线传输的四个阶段 总线周期&#xff1a; 申请分配阶段&#xff1a;由需要使用总线的主模块&#…

【C++11及其特性】左值和右值

左值和右值目录 一.左值和右值的报错1.简单定义2.函数返回值作左值3.表达式作左值 二.存储的层次结构1.CPU2.内存3.磁盘4.三者联系5.寄存器 三.左值和右值的概念1.左值2.右值3.转换 一.左值和右值的报错 1.简单定义 赋值号’左边的为左值,右边的为右值. 2.函数返回值作左值 …

力扣刷题(3)

整数反转 整数反转-力扣 思路&#xff1a; 利用%和/不断循环取待反转整数的最后一位&#xff0c;注意判断是否超出范围。 int reverse(int x){int y0;while(x){if(y > INT_MAX/10 || y < INT_MIN/10)return 0;int tmpx%10;yy*10tmp;x/10;}return y; }字符串转换整数 …

自动化代码报错:ElementClickInterceptedException 解决方案

在自动化测试中&#xff0c;如果有多个弹窗出现&#xff0c;代码执行可能会遇到ElementClickInterceptedException的错误&#xff0c;表明元素点击被拦截&#xff1a; 一般由于以下原因&#xff1a; 一、页面加载未完成 在页面尚未完全加载完成时尝试点击某个元素&#xff0c…

ENVI SARscape||笔记

介绍就不介绍了&#xff0c;直入主题&#xff01; 第一章 ENVI和SARscape 下载与安装&#xff1a; ENVI 5.6 软件安装包下载及安装激活教程&#xff01; (qq.com)https://mp.weixin.qq.com/s/kH0g5g9AALgDNPssfdZ8wQ 启动 ENVI 的启动模式有两种&#xff1a;ENVI和ENVIIDL&…

前端性能优化:提升网站加载速度的五个关键技巧

聚沙成塔每天进步一点点 本文回顾 ⭐ 专栏简介前端性能优化&#xff1a;提升网站加载速度的五个关键技巧1. 引言2. 前端性能优化的五个关键技巧2.1 减少HTTP请求技巧说明实现示例 2.2 启用浏览器缓存技巧说明实现示例 2.3 使用内容分发网络&#xff08;CDN&#xff09;技巧说明…

Adobe DC 2022提示无法识别的错误 - 解决方案

Adobe DC 2022提示无法识别的错误 - 解决方案 问题解决方案更改安装&#xff08;推荐&#xff09;重新安装&#xff08;推荐&#xff09;降级安装&#xff08;不推荐&#xff09; 问题 使用Adobe DC 2022合并图片创建PDF时&#xff0c;会提示无法识别的错误&#xff0c;这是因…

Mac 安装Hadoop教程

1. 引言 本教程旨在介绍在Mac 电脑上安装Hadoop&#xff0c;便于编程开发人员对大数据技术的熟悉和掌握。 2.前提条件 2.1 安装JDK 想要在你的Mac电脑上安装Hadoop&#xff0c;你必须首先安装JDK。具体安装步骤这里就不详细描述了。你可参考Mac 下载JDK8。 2.2 配置ssh环境…

2024如何开始进入美业?美业创业步骤分享|博弈美业系统管理系统源码

进入美业可以是一个令人兴奋且具有挑战性的决定。以下是一些步骤&#xff0c;希望可以帮助你在美业建立自己的职业生涯&#xff1a; 1.确定你的兴趣和专长&#xff1a; 首先要考虑你对美业的兴趣和擅长的领域&#xff0c;比如化妆、美发、美甲、美容护理等。确定自己的兴趣和优…