首页 > 其他分享 >YOLOv9改进策略【卷积层】| 利用MobileNetv4中的UIB、ExtraDW优化RepNCSPELAN4

YOLOv9改进策略【卷积层】| 利用MobileNetv4中的UIB、ExtraDW优化RepNCSPELAN4

时间:2024-08-28 17:50:41浏览次数:12  
标签:UIB conv models MobileNetv4 YOLOv9 common RepNCSPELAN4 512 256

一、本文介绍

本文记录的是利用ExtraDW优化YOLOv9中的RepNCSPELAN4,详细说明了优化原因,注意事项等。ExtraDWMobileNetv4模型中提出的新模块,允许以低成本增加网络深度和感受野,具有ConvNext和IB的组合优势。可以在提高模型精度的同时降低一定量的模型参数。

文章目录


二、UIB介绍

Universal Inverted Bottleneck(UIB)通用反向瓶颈结构。

2.1 UIB结构设计

  1. 基于MobileNetV4

    • UIB建立在MobileNetV4之上,即采用深度可分离卷积逐点扩展及投影的反向瓶颈结构。
    • 反向瓶颈块(IB)中引入两个可选的深度可分离卷积,一个在扩展层之前,另一个在扩展层和投影层之间。
  2. UIB有四种可能的实例化形式:

    • Inverted Bottleneck (IB):对扩展后的特征激活进行空间混合,以增加成本为代价提供更大的模型容量。
    • ConvNext:通过在扩展之前进行空间混合,使用更大的核尺寸实现更便宜的空间混合。
    • ExtraDW:文中引入的新变体,允许以低成本增加网络深度和感受野,具有ConvNextIB的组合优势。
    • FFN:由两个1x1逐点卷积(PW)组成的栈,中间有激活和归一化层。

在这里插入图片描述

2.2 ExtraDW结构组成

结构组成

  • IB块中加入两个可选的深度可分离卷积一个在扩展层之前,另一个在扩展层和投影层之间。

2.3 ExtraDW特点

  1. 灵活性

    • 在每个网络阶段,可以灵活地进行空间和通道混合的权衡调整,根据需要扩大感受野,并最大化计算利用率,增强模型对输入特征的感知能力。
  2. 效率提升

    • 提供了一种廉价增加网络深度和感受野的方式。相比其他结构,它在增加网络深度和感受野的同时,不会带来过高的计算成本。
    • 在论文中,与其他注意力机制结合时,能有效提高模型的运算强度,减少内存访问需求,从而提高模型效率。

论文:http://arxiv.org/abs/2404.10518
源码:https://github.com/tensorflow/models/blob/master/official/vision/modeling/backbones/mobilenet.py

三、ExtraDW的实现代码

ExtraDW模块的实现代码如下:参考代码


def conv2d(in_channels, out_channels, kernel_size=3, stride=1, groups=1, bias=False, norm=True, act=True):
    conv = nn.Sequential()
    padding = (kernel_size - 1) // 2
    conv.append(nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding, bias=bias, groups=groups))
    if norm:
        conv.append(nn.BatchNorm2d(out_channels))
    if act:
        conv.append(nn.ReLU6())
    return conv


class UniversalInvertedBottleneckBlock(nn.Module):
    def __init__(self, in_channels, out_channels, start_dw_kernel_size, middle_dw_kernel_size, middle_dw_downsample,
                 stride, expand_ratio):
        """An inverted bottleneck block with optional depthwises.
        Referenced from here https://github.com/tensorflow/models/blob/master/official/vision/modeling/layers/nn_blocks.py
        """
        super(UniversalInvertedBottleneckBlock, self).__init__()
        # starting depthwise conv
        self.start_dw_kernel_size = start_dw_kernel_size
        if self.start_dw_kernel_size:
            stride_ = stride if not middle_dw_downsample else 1
            self._start_dw_ = conv2d(in_channels, in_channels, kernel_size=start_dw_kernel_size, stride=stride_, groups=in_channels, act=False)
        # expansion with 1x1 convs
        expand_filters = make_divisible(in_channels * expand_ratio, 8)
        self._expand_conv = conv2d(in_channels, expand_filters, kernel_size=1)
        # middle depthwise conv
        self.middle_dw_kernel_size = middle_dw_kernel_size
        if self.middle_dw_kernel_size:
            stride_ = stride if middle_dw_downsample else 1
            self._middle_dw = conv2d(expand_filters, expand_filters, kernel_size=middle_dw_kernel_size, stride=stride_, groups=expand_filters)
        # projection with 1x1 convs
        self._proj_conv = conv2d(expand_filters, out_channels, kernel_size=1, stride=1, act=False)

        # expand depthwise conv (not used)
        # _end_dw_kernel_size = 0
        # self._end_dw = conv2d(out_channels, out_channels, kernel_size=_end_dw_kernel_size, stride=stride, groups=in_channels, act=False)

    def forward(self, x):
        if self.start_dw_kernel_size:
            x = self._start_dw_(x)
            # print("_start_dw_", x.shape)
        x = self._expand_conv(x)
        # print("_expand_conv", x.shape)
        if self.middle_dw_kernel_size:
            x = self._middle_dw(x)
            # print("_middle_dw", x.shape)
        x = self._proj_conv(x)
        # print("_proj_conv", x.shape)
        return x


四、添加步骤

4.1 修改common.py

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

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

4.1.1 基础模块1

模块改进方法1️⃣:直接加入UniversalInvertedBottleneckBlock模块
将上方的实现代码粘贴到common.py文件夹下,UniversalInvertedBottleneckBlock模块添加后如下:

在这里插入图片描述

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

4.1.2 创新模块2⭐

模块改进方法2️⃣:基于UniversalInvertedBottleneckBlockRepNCSPELAN4

相较方法一中的直接插入UIB模块,利用UIB模块对卷积等其他模块进行改进,其新颖程度会更高一些,训练精度可能会表现的更高。

第二种改进方法是对YOLOv9中的RepNCSPELAN4模块进行改进。UIB 中的ExtraDW模块RepNCSPELAN4 结合后,可以为YOLOv9提供更丰富的特征表示,更好地调整特征的空间分布和通道信息,使得模型能够更有效地聚焦于目标相关的特征,减少无关信息的干扰,进而提高检测精度。

改进代码如下:

class UIBRepNCSPELAN4(nn.Module):
    # csp-elan
    def __init__(self, c1, c2, c3, c4, c5=1):  # ch_in, ch_out, number, shortcut, groups, expansion
        super().__init__()
        self.c = c3//2
        self.cv1 = Conv(c1, c3, 1, 1)
        self.cv2 = nn.Sequential(RepNCSP(c3//2, c4, c5), UniversalInvertedBottleneckBlock(c4, c4, 3, 3, True, 1, 6))
        self.cv3 = nn.Sequential(RepNCSP(c4, c4, c5), UniversalInvertedBottleneckBlock(c4, c4, 5, 3, True, 1, 4))
        self.cv4 = Conv(c3+(2*c4), c2, 1, 1)

    def forward(self, x):
        y = list(self.cv1(x).chunk(2, 1))
        y.extend((m(y[-1])) for m in [self.cv2, self.cv3])
        return self.cv4(torch.cat(y, 1))

    def forward_split(self, x):
        y = list(self.cv1(x).split((self.c, self.c), 1))
        y.extend(m(y[-1]) for m in [self.cv2, self.cv3])
        return self.cv4(torch.cat(y, 1))

在这里插入图片描述

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

4.2 修改yolo.py

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

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

UniversalInvertedBottleneckBlock模块以及UIBRepNCSPELAN4模块添加后如下:

在这里插入图片描述


五、yaml模型文件

5.1 模型改进版本一

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

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

yolov9-c.yaml中的内容复制到yolov9-c-UIB.yaml文件下,修改nc数量等于自己数据中目标的数量。
在骨干网络中,将四个RepNCSPELAN4模块替换成UniversalInvertedBottleneckBlock模块,注意修改函数中的参数。还需要注意的是,由于PAN+FPN的颈部模型结构存在,层之间的匹配也要记得修改,维度要匹配上

# 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, [128, 3, 2]],  # 2-P2/4

   # elan-1 block
   [-1, 1, UniversalInvertedBottleneckBlock, [256, 0, 3, True, 1, 2]],  # 3  修改此处

   # avg-conv down
   [-1, 1, ADown, [256]],  # 4-P3/8

   # elan-2 block
   [-1, 1, UniversalInvertedBottleneckBlock, [512, 0, 3, True, 1, 2]],  # 5  修改此处

   # avg-conv down
   [-1, 1, ADown, [512]],  # 6-P4/16

   # elan-2 block
   [-1, 1, UniversalInvertedBottleneckBlock, [512, 5, 3, True, 1, 4]],  # 7  修改此处

   # avg-conv down
   [-1, 1, ADown, [512]],  # 8-P5/32

   # elan-2 block
   [-1, 1, UniversalInvertedBottleneckBlock, [512, 5, 3, True, 1, 4]],  # 9  修改此处
  ]

# YOLOv9 head
head:
  [
   # elan-spp block
   [-1, 1, SPPELAN, [512, 256]],  # 10

   # up-concat merge
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 7], 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, 5], 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, 13], 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, 10], 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
   [5, 1, CBLinear, [[256]]], # 23
   [7, 1, CBLinear, [[256, 512]]], # 24
   [9, 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
   [[23, 24, 25, -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
   [[24, 25, -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
   [[25, -1], 1, CBFuse, [[2]]], # 36

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 37
   
   
   
   # detection head

   # detect
   [[31, 34, 37, 16, 19, 22], 1, DualDDetect, [nc]],  # DualDDetect(A3, A4, A5, P3, P4, P5)
  ]

5.2 模型改进版本二⭐

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

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

标签:UIB,conv,models,MobileNetv4,YOLOv9,common,RepNCSPELAN4,512,256
From: https://blog.csdn.net/qq_42591591/article/details/140667641

相关文章

  • AutodL训练yolov9
    AutodL训练yolov9全过程1、租借Autodl服务器:AutoDL算力云|弹性、好用、省钱。租GPU就上AutoDL选择环境,直接选择镜像,yolov9官方2、创建完成:点击Jupyterlab进入服务器,到这里服务器租用完成2、下载yolov9官网代码:https://github.com/WongKinYiu/yolov93、进入服务器,上......
  • 【教学类-75-01】花边边框01(UIBOT图片背景填充白色)15CM手工纸
    前期研究用了三天时间把所有通义万相下载的图片的背景改成纯白色。UIBOt模拟PS修图【教学类-74-01】袜子配对01(UIBOT图片背景填充白色)-CSDN博客文章浏览阅读1.4k次,点赞57次,收藏23次。【教学类-74-01】袜子配对01(UIBOT图片背景填充白色)https://blog.csdn.net/reasonsummer/a......
  • 【教学类-74-01】袜子配对01(UIBOT图片背景填充白色)
    背景需求:前期用PS修图(灰色背景变成白色背景),200张图片用了6个小时。【教学类-73-02】20240805广口瓶(宽口瓶)02-CSDN博客文章浏览阅读744次,点赞17次,收藏20次。【教学类-73-02】20240805广口瓶(宽口瓶)02https://blog.csdn.net/reasonsummer/article/details/140930505所以我想试......
  • YoloV9改进策略:注意力机制改进|通过iAFF模块优化RepNBottleneck结构,YoloV9性能飞跃|即
    摘要在深度学习和计算机视觉领域,YoloV9以其卓越的目标检测性能赢得了广泛的关注与应用。为了进一步提升YoloV9的识别精度和鲁棒性,我们创新性地在其核心组件——RepNBottleneck模块中引入了迭代注意力特征融合(iAFF)模块。这一改进不仅实现了显著的涨点效果,还展现了在复杂场景......
  • YOLOv9改进系列,YOLOv9引入SPDConv(新颖的卷积),用于低分辨率图像和小物体目标,实现大幅
    前言卷积神经网络在许多计算机视觉任务中取得了显著成功,例如图像分类和目标检测。然而,在图像分辨率较低或目标较小的更困难任务中,它们的性能会迅速下降。在本文中,指出这根源于现有CNN架构中一个常见但有缺陷的设计,即使用了步幅卷积和/或池化层,这导致了细粒度信息的丢失以......
  • 易优CMS模板标签uibackground背景图片在模板文件index.htm中调用uibackground标签,实现
    【基础用法】标签:uibackground描述:背景图片上传标签,使用时结合html一起才能完成可视化布局,只针对具有可视化功能的模板。用法:<divclass="eyou-edit"e-id="文件模板里唯一的数字ID"e-page='文件模板名'e-type="background"style="background-image:url({eyou:uibackgrounde......
  • 基于YOLOv9的停车场空闲车位检测【python源码+UI界面+数据集+模型+语音报警+安装说明
    往期精品导航基于YOLOv9的脑肿瘤区域检测智慧课堂基于YOLOv8的学生上课行为检测基于YOLOv9+pyside的安检仪x光危险物物品检测(有ui)基于YOLOv9的PCB板缺陷检测基于YOLOv9的线路绝缘子缺陷检测【python源码+UI界面+数据集+模型+语音报警+安装说明】基于YOLOv9的道路状况检测【......
  • 易优CMS模板标签uibackground背景图片在模板文件index.htm中调用uibackground标签,实现
    【基础用法】标签:uibackground描述:背景图片上传标签,使用时结合html一起才能完成可视化布局,只针对具有可视化功能的模板。用法:<divclass="eyou-edit"e-id="文件模板里唯一的数字ID"e-page='文件模板名'e-type="background"style="background-image:url({eyou:uibackgrounde......
  • 数据库迁移的神秘面纱:Liquibase异常全解析与解决之道
    哈喽,大家好,我是木头左!一、Liquibase简介与重要性Liquibase,这个名字听起来就像是液体的魔法。在软件开发的世界里,它确实是一种魔法,一种让数据库变更变得清晰、可控甚至可逆的魔法。但就像所有魔法一样,掌握它需要了解它的规则和秘密。今天,就来揭开Liquibase的神秘面纱,特别是那些......
  • liquibase脚本自动生成数据库表
    日常开发中,需要进行数据库设计建模,创建对应的表,可通过liquibase脚本自动生成数据库表,减少开发时间。1.项目中pom文件引入liquibase的maven依赖<!--liquibasestart--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-start......