YOLOv9改进策略【模型轻量化】| MoblieNetV3:基于搜索技术和新颖架构设计的轻量型网络模型

本文主要是介绍YOLOv9改进策略【模型轻量化】| MoblieNetV3:基于搜索技术和新颖架构设计的轻量型网络模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、本文介绍

本文记录的是基于MobileNet V3的YOLOv9目标检测轻量化改进方法研究MobileNet V3的模型结构是通过网络搜索得来的,其中的基础模块结合了MobileNet V1的深度可分离卷积、MobileNet V2的线性瓶颈和倒置残差结构以及MnasNet中基于挤压和激励的轻量级注意力模块,使模型在性能、效率和灵活性方面都具有显著的优势。

模型参数量计算量推理速度(bs=32)
YOLOv9-c50.69M236.6GFLOPs32.1ms
Improved42.05M192.3GFLOPs28.1ms

文章目录

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


二、MoblieNet V3设计原理

MobileNet V3是基于一系列互补的搜索技术和新颖的架构设计而提出的新一代神经网络模型,其设计的原理和优势主要包括以下几个方面:

  1. 原理
    • 网络搜索
      • 平台感知的NAS(Platform - Aware NAS):用于搜索全局网络结构,通过优化每个网络块来实现。对于大型移动模型,复用了MnasNet - A1的结构,并在此基础上应用NetAdapt和其他优化。对于小型移动模型,观察到原奖励设计未针对其优化,因此调整了权重因子w,重新进行架构搜索以找到初始种子模型。
      • NetAdapt:用于逐层搜索过滤器的数量,是对平台感知的NAS的补充。它从平台感知的NAS找到的种子网络架构开始,通过生成新的提案并根据某些指标选择最佳提案,逐步微调单个层,直到达到目标延迟。在选择提案时,修改了算法以最小化延迟变化和准确率变化的比率。
    • 网络改进
      • 重新设计昂贵层:对网络末尾和开头的一些昂贵层进行修改。对于末尾的层,将产生最终特征的层移动到最终平均池化之后,以降低延迟并保持高维特征,同时去除了之前瓶颈层中的投影和过滤层,进一步降低计算复杂度。对于初始的滤波器层,实验发现使用hard swish非线性函数并将滤波器数量减少到16时,能在保持准确率的同时减少延迟和计算量。
      • 非线性函数:引入了名为h-swish的非线性函数,它是swish非线性函数的改进版本,计算更快且更有利于量化。通过将sigmoid函数替换为分段线性的hard版本(如h - swish [x] = x * ReLU6(x + 3) / 6),并在网络的后半部分使用h-swish,减少了计算成本,同时在准确率上与原始版本没有明显差异。
      • 大的挤压 - 激励(Large squeeze - and - excite):将挤压 - 激励瓶颈的大小固定为扩展层通道数的1 / 4,在增加少量参数的情况下提高了准确率,且没有明显的延迟成本。
    • 高效的移动构建块:结合了MobileNet V1的深度可分离卷积、MobileNet V2的线性瓶颈和倒置残差结构以及MnasNet中基于挤压和激励的轻量级注意力模块,同时升级了这些层,使用修改后的swish非线性函数以提高效率。

在这里插入图片描述

  1. 优势

    • MobileNet V3通过网络搜索和改进,结合了多种技术的优势,在性能、效率和灵活性方面都具有显著的优势,适用于移动设备上的各种计算机视觉任务。并且定义了MobileNetV3 - LargeMobileNetV3 - Small两个模型,分别针对高资源和低资源使用场景,可根据不同需求进行选择和应用。

论文:https://arxiv.org/abs/2211.12905
源码:https://github.com/huawei-noah/Efficient-AI-Backbones/tree/master/ghostnetv2_pytorch

三、GhostModuleV2模块的实现代码

GhostModuleV2模块的实现代码如下:

class h_sigmoid(nn.Module):def __init__(self, inplace=True):super(h_sigmoid, self).__init__()self.relu = nn.ReLU6(inplace=inplace)def forward(self, x):return self.relu(x + 3) / 6class h_swish(nn.Module):def __init__(self, inplace=True):super(h_swish, self).__init__()self.sigmoid = h_sigmoid(inplace=inplace)def forward(self, x):return x * self.sigmoid(x)class SELayer(nn.Module):def __init__(self, channel, reduction=4):super(SELayer, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.fc = nn.Sequential(nn.Linear(channel, channel // reduction),nn.ReLU(inplace=True),nn.Linear(channel // reduction, channel),h_sigmoid())def forward(self, x):b, c, _, _ = x.size()y = self.avg_pool(x)y = y.view(b, c)y = self.fc(y).view(b, c, 1, 1)return x * yclass conv_bn_hswish(nn.Module):def __init__(self, c1, c2, stride):super(conv_bn_hswish, self).__init__()self.conv = nn.Conv2d(c1, c2, 3, stride, 1, bias=False)self.bn = nn.BatchNorm2d(c2)self.act = h_swish()def forward(self, x):return self.act(self.bn(self.conv(x)))def fuseforward(self, x):return self.act(self.conv(x))class MobileNet_Block(nn.Module):def __init__(self, inp, oup, hidden_dim, kernel_size, stride, use_se, use_hs):super(MobileNet_Block, self).__init__()assert stride in [1, 2]self.identity = stride == 1 and inp == oupif inp == hidden_dim:self.conv = nn.Sequential(# dwnn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, (kernel_size - 1) // 2, groups=hidden_dim,bias=False),nn.BatchNorm2d(hidden_dim),h_swish() if use_hs else nn.ReLU(inplace=True),# Squeeze-and-ExciteSELayer(hidden_dim) if use_se else nn.Sequential(),# pw-linearnn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),nn.BatchNorm2d(oup),)else:self.conv = nn.Sequential(# pwnn.Conv2d(inp, hidden_dim, 1, 1, 0, bias=False),nn.BatchNorm2d(hidden_dim),h_swish() if use_hs else nn.ReLU(inplace=True),# dwnn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, (kernel_size - 1) // 2, groups=hidden_dim,bias=False),nn.BatchNorm2d(hidden_dim),# Squeeze-and-ExciteSELayer(hidden_dim) if use_se else nn.Sequential(),h_swish() if use_hs else nn.ReLU(inplace=True),# pw-linearnn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),nn.BatchNorm2d(oup),)def forward(self, x):y = self.conv(x)if self.identity:return x + yelse:return y

四、添加步骤

4.1 修改common.py

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

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

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

在这里插入图片描述

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

4.2 修改yolo.py

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

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

conv_bn_hswishMobileNet_Block模块添加后如下:

在这里插入图片描述


五、yaml模型文件

5.1 模型改进⭐

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

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

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

📌 模型的修改方法是将骨干网络中的所有RepNCSPELAN4模块替换成MobileNet_Block模块,搭建MobileNetV3 - Small模型,并将其替换YOLOv9的骨干网络,相比原有的骨干网络,这可以大大减少模型的计算负担,提高推理速度,并且减小后的模型,使其在部署应用方面更加方便。

结构如下:

# 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, [64, 3, 2]],  # 1-P1/2# conv down[-1, 1, conv_bn_hswish, [16, 2]],  # 1-P1/2# elan-1 block[-1, 1, MobileNet_Block, [16,  16, 3, 2, 1, 0]],  # 2-P2/4# avg-conv down[-1, 1, MobileNet_Block, [24,  72, 3, 2, 0, 0]],  # 3-P3/8# elan-2 block[-1, 1, MobileNet_Block, [24,  88, 3, 1, 0, 0]],  # 4# avg-conv down[-1, 1, MobileNet_Block, [40,  96, 5, 2, 1, 1]],  # 5-P4/16# elan-2 block[-1, 1, MobileNet_Block, [40, 240, 5, 1, 1, 1]],  # 6[-1, 1, MobileNet_Block, [40, 240, 5, 1, 1, 1]],  # 7[-1, 1, MobileNet_Block, [48, 120, 5, 1, 1, 1]],  # 8[-1, 1, MobileNet_Block, [48, 144, 5, 1, 1, 1]],  # 9# avg-conv down[-1, 1, MobileNet_Block, [96, 288, 5, 2, 1, 1]],  # 10-P5/32# elan-2 block[-1, 1, MobileNet_Block, [96, 576, 5, 1, 1, 1]],  # 11[-1, 1, MobileNet_Block, [96, 576, 5, 1, 1, 1]],  # 12]# YOLOv9 head
head:[# elan-spp block[-1, 1, SPPELAN, [512, 256]],  # 10# up-concat merge[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 9], 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, 4], 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, 16], 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, 13], 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[4, 1, CBLinear, [[256]]], # 23[9, 1, CBLinear, [[256, 512]]], # 24[12, 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[[26, 27, 28, -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[[27, 28, -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[[28, -1], 1, CBFuse, [[2]]], # 36# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 37# detection head# detect[[34, 37, 40, 19, 22, 25], 1, DualDDetect, [nc]],  # DualDDetect(A3, A4, A5, P3, P4, P5)]

六、成功运行结果

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

yolov9-c-mobilenetv3

                 from  n    params  module                                  arguments                     0                -1  1         0  models.common.Silence                   []                            1                -1  1       464  models.common.conv_bn_hswish            [3, 16, 2]                    2                -1  1       612  models.common.MobileNet_Block           [16, 16, 16, 3, 2, 1, 0]      3                -1  1      3864  models.common.MobileNet_Block           [16, 24, 72, 3, 2, 0, 0]      4                -1  1      5416  models.common.MobileNet_Block           [24, 24, 88, 3, 1, 0, 0]      5                -1  1     13736  models.common.MobileNet_Block           [24, 40, 96, 5, 2, 1, 1]      6                -1  1     55340  models.common.MobileNet_Block           [40, 40, 240, 5, 1, 1, 1]     7                -1  1     55340  models.common.MobileNet_Block           [40, 40, 240, 5, 1, 1, 1]     8                -1  1     21486  models.common.MobileNet_Block           [40, 48, 120, 5, 1, 1, 1]     9                -1  1     28644  models.common.MobileNet_Block           [48, 48, 144, 5, 1, 1, 1]     10                -1  1     91848  models.common.MobileNet_Block           [48, 96, 288, 5, 2, 1, 1]     11                -1  1    294096  models.common.MobileNet_Block           [96, 96, 576, 5, 1, 1, 1]     12                -1  1    294096  models.common.MobileNet_Block           [96, 96, 576, 5, 1, 1, 1]     13                -1  1    550400  models.common.SPPELAN                   [96, 512, 256]                14                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          15           [-1, 9]  1         0  models.common.Concat                    [1]                           16                -1  1   2882048  models.common.RepNCSPELAN4              [560, 512, 512, 256, 1]       17                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          18           [-1, 4]  1         0  models.common.Concat                    [1]                           19                -1  1    787712  models.common.RepNCSPELAN4              [536, 256, 256, 128, 1]       20                -1  1    164352  models.common.ADown                     [256, 256]                    21          [-1, 16]  1         0  models.common.Concat                    [1]                           22                -1  1   2988544  models.common.RepNCSPELAN4              [768, 512, 512, 256, 1]       23                -1  1    656384  models.common.ADown                     [512, 512]                    24          [-1, 13]  1         0  models.common.Concat                    [1]                           25                -1  1   3119616  models.common.RepNCSPELAN4              [1024, 512, 512, 256, 1]      26                 4  1      6400  models.common.CBLinear                  [24, [256]]                   27                 9  1     37632  models.common.CBLinear                  [48, [256, 512]]              28                12  1    124160  models.common.CBLinear                  [96, [256, 512, 512]]         29                 0  1      1856  models.common.Conv                      [3, 64, 3, 2]                 30                -1  1     73984  models.common.Conv                      [64, 128, 3, 2]               31                -1  1    212864  models.common.RepNCSPELAN4              [128, 256, 128, 64, 1]        32                -1  1    164352  models.common.ADown                     [256, 256]                    33  [26, 27, 28, -1]  1         0  models.common.CBFuse                    [[0, 0, 0]]                   34                -1  1    847616  models.common.RepNCSPELAN4              [256, 512, 256, 128, 1]       35                -1  1    656384  models.common.ADown                     [512, 512]                    36      [27, 28, -1]  1         0  models.common.CBFuse                    [[1, 1]]                      37                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]       38                -1  1    656384  models.common.ADown                     [512, 512]                    39          [28, -1]  1         0  models.common.CBFuse                    [[2]]                         40                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]       41[34, 37, 40, 19, 22, 25]  1  21542822  models.yolo.DualDDetect                 [1, [512, 512, 512, 256, 512, 512]]
yolov9-c-mobilenetv3 summary: 902 layers, 42053396 parameters, 42053364 gradients, 192.3 GFLOPs

这篇关于YOLOv9改进策略【模型轻量化】| MoblieNetV3:基于搜索技术和新颖架构设计的轻量型网络模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1128055

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

图神经网络模型介绍(1)

我们将图神经网络分为基于谱域的模型和基于空域的模型,并按照发展顺序详解每个类别中的重要模型。 1.1基于谱域的图神经网络         谱域上的图卷积在图学习迈向深度学习的发展历程中起到了关键的作用。本节主要介绍三个具有代表性的谱域图神经网络:谱图卷积网络、切比雪夫网络和图卷积网络。 (1)谱图卷积网络 卷积定理:函数卷积的傅里叶变换是函数傅里叶变换的乘积,即F{f*g}