当前位置: 首页 > news >正文

YOLOv9改进策略【Neck】| 使用CARAFE轻量级通用上采样算子

一、本文介绍

本文记录的是利用CARAFE上采样对YOLOv9的颈部网络进行改进的方法研究YOLOv9采用传统的最近邻插值的方法,仅考虑子像素邻域,无法捕获密集预测任务所需的丰富语义信息,从而影响模型在密集预测任务中的性能。CARAFE通过在大感受野内聚合信息、能够实时适应实例特定内容且保持计算效率。

文章目录

  • 一、本文介绍
  • 二、CARAFE介绍
    • 2.1、CARAFE原理
    • 2.2、优势
  • 三、CARAFE的实现代码
  • 四、添加步骤
    • 4.1 修改common.py
    • 4.2 修改yolo.py
  • 五、yaml模型文件
    • 5.1 模型改进
  • 六、成功运行结果


二、CARAFE介绍

CARAFE内容感知的特征重新组合

CARAFE(Content - Aware ReAssembly of FEatures)是一种用于特征上采样的操作符,其设计原理和优势如下:

2.1、CARAFE原理

  • 总体框架CARAFE由两个关键组件组成,即核预测模块内容感知重组模块。给定大小为 C × H × W C×H×W C×H×W的特征图 x x x和上采样比例 σ \sigma σ(假设 σ \sigma σ是整数),CARAFE将产生大小为 C × σ H × σ W C×\sigma H×\sigma W C×σH×σW的新特征图 X ′ X' X
  • 核预测模块:负责以内容感知的方式生成重组核。每个源位置 x x x上对应 σ 2 \sigma^{2} σ2个目标位置 X ′ X' X上,每个目标位置需要一个 k u p × k u p k_{u p}×k_{u p} kup×kup的重组核,因此该模块将输出大小为 C u p × H × W C_{u p}×H×W Cup×H×W的重组核,其中 C u p = σ 2 k u p 2 C_{u p} = \sigma^{2}k_{u p}^{2} Cup=σ2kup2。该模块由三个子模块组成,分别是通道压缩器、内容编码器和核归一化器。
    • 通道压缩器:采用 1 × 1 1×1 1×1卷积层将输入特征通道从 C C C压缩到 C m C_{m} Cm,减少特征图的通道数,从而减少后续步骤的参数和计算成本,使CARAFE更高效。
    • 内容编码器:使用核大小为 k e n c o d e r k_{encoder} kencoder的卷积层根据输入特征的内容生成重组核,编码器的参数为 k e n c o d e r × k e n c o d e r × C m × C u p k_{encoder}×k_{encoder}×C_{m}×C_{u p} kencoder×kencoder×Cm×Cup。增大 k e n c o d e r k_{encoder} kencoder可以扩大编码器的感受野,利用更大区域内的上下文信息,但计算复杂度也会随之增加。通过研究, k e n c o d e r = k u p − 2 k_{encoder} = k_{u p} - 2 kencoder=kup2是性能和效率之间的良好平衡。
    • 核归一化器:在将每个 k u p × k u p k_{u p}×k_{u p} kup×kup重组核应用于输入特征图之前,使用softmax函数对其进行空间归一化,使核值之和为 1 1 1,这是对局部区域的软选择。
  • 内容感知重组模块:对于目标位置 l ′ l' l和以 l = ( i , j ) l = (i, j) l=(i,j)为中心的相应方形区域 N ( X l , k u p ) N(X_{l}, k_{u p}) N(Xl,kup),重组过程如公式 X l ′ ′ = ∑ n = − r r ∑ m = − r r W l ′ ( n , m ) ⋅ X ( i + n , j + m ) \mathcal{X}_{l'}' = \sum_{n = -r}^{r}\sum_{m = -r}^{r}\mathcal{W}_{l'(n, m)}·\mathcal{X}_{(i + n, j + m)} Xl=n=rrm=rrWl(n,m)X(i+n,j+m)所示,其中 r = ⌊ k u p / 2 ⌋ r = \lfloor k_{u p} / 2\rfloor r=kup/2。通过重组核,区域 N ( X l , k u p ) N(X_{l}, k_{u p}) N(Xl,kup)中的每个像素根据特征的内容而不是位置的距离对上采样像素 l ′ l' l的贡献不同,使得重组后的特征图的语义比原始特征图更强。

在这里插入图片描述

2.2、优势

  • 大视野:与之前仅利用子像素邻域的工作不同,CARAFE可以在大感受野内聚合上下文信息。
  • 内容感知处理CARAFE能够根据实例特定的内容进行实时处理,为每个样本生成自适应的内核,而不是使用固定的内核。
  • 轻量且计算快速CARAFE引入的计算开销很小,可以很容易地集成到现代网络架构中。
  • 通用性和有效性:在对象检测、实例分割、语义分割、图像修复等广泛的密集预测任务中,CARAFE都能显著提升性能。

论文:https://arxiv.org/abs/1905.02188
源码:https://github.com/tiny-smart/dysample

三、CARAFE的实现代码

CARAFE模块的实现代码如下:

class CARAFE(nn.Module):def __init__(self, c, k_enc=3, k_up=5, c_mid=64, scale=2):""" The unofficial implementation of the CARAFE module.The details are in "https://arxiv.org/abs/1905.02188".Args:c: The channel number of the input and the output.c_mid: The channel number after compression.scale: The expected upsample scale.k_up: The size of the reassembly kernel.k_enc: The kernel size of the encoder.Returns:X: The upsampled feature map."""super(CARAFE, self).__init__()self.scale = scaleself.comp = Conv(c, c_mid)self.enc = Conv(c_mid, (scale * k_up) ** 2, k=k_enc, act=False)self.pix_shf = nn.PixelShuffle(scale)self.upsmp = nn.Upsample(scale_factor=scale, mode='nearest')self.unfold = nn.Unfold(kernel_size=k_up, dilation=scale,padding=k_up // 2 * scale)def forward(self, X):b, c, h, w = X.size()h_, w_ = h * self.scale, w * self.scaleW = self.comp(X)  # b * m * h * wW = self.enc(W)  # b * 100 * h * wW = self.pix_shf(W)  # b * 25 * h_ * w_W = torch.softmax(W, dim=1)  # b * 25 * h_ * w_X = self.upsmp(X)  # b * c * h_ * w_X = self.unfold(X)  # b * 25c * h_ * w_X = X.view(b, c, -1, h_, w_)  # b * 25 * c * h_ * w_X = torch.einsum('bkhw,bckhw->bchw', [W, X])  # b * c * h_ * w_return X

四、添加步骤

4.1 修改common.py

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

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

CARAFE模块添加后如下:

在这里插入图片描述

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

4.2 修改yolo.py

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

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

def parse_model(d, ch)中将CARAFE模块添加后如下:

在这里插入图片描述

elif m in [CARAFE]:args = [ch[f], *args[0:]]

五、yaml模型文件

5.1 模型改进

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

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

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

📌 修改方法是将CARAFE模块替换YOLOv9颈部网络中的上采样模块nn.Upsample

# 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, RepNCSPELAN4, [256, 128, 64, 1]],  # 3# avg-conv down[-1, 1, ADown, [256]],  # 4-P3/8# elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 5# avg-conv down[-1, 1, ADown, [512]],  # 6-P4/16# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 7(可替换)# avg-conv down[-1, 1, ADown, [512]],  # 8-P5/32# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 9(可替换)]# YOLOv9 head
head:[# elan-spp block[-1, 1, SPPELAN, [512, 256]],  # 10# up-concat merge[-1, 1, CARAFE, []],[[-1, 7], 1, Concat, [1]],  # cat backbone P4# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 13# up-concat merge[-1, 1, CARAFE, []],[[-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)]

六、成功运行结果

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

yolov9-c-CARAFE

                 from  n    params  module                                  arguments                     0                -1  1         0  models.common.Silence                   []                            1                -1  1      1856  models.common.Conv                      [3, 64, 3, 2]                 2                -1  1     73984  models.common.Conv                      [64, 128, 3, 2]               3                -1  1    212864  models.common.RepNCSPELAN4              [128, 256, 128, 64, 1]        4                -1  1    164352  models.common.ADown                     [256, 256]                    5                -1  1    847616  models.common.RepNCSPELAN4              [256, 512, 256, 128, 1]       6                -1  1    656384  models.common.ADown                     [512, 512]                    7                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]       8                -1  1    656384  models.common.ADown                     [512, 512]                    9                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]       10                -1  1    656896  models.common.SPPELAN                   [512, 512, 256]               11                -1  1     90696  models.common.CARAFE                    [512]                         12           [-1, 7]  1         0  models.common.Concat                    [1]                           13                -1  1   3119616  models.common.RepNCSPELAN4              [1024, 512, 512, 256, 1]      14                -1  1     90696  models.common.CARAFE                    [512]                         15           [-1, 5]  1         0  models.common.Concat                    [1]                           16                -1  1    912640  models.common.RepNCSPELAN4              [1024, 256, 256, 128, 1]      17                -1  1    164352  models.common.ADown                     [256, 256]                    18          [-1, 13]  1         0  models.common.Concat                    [1]                           19                -1  1   2988544  models.common.RepNCSPELAN4              [768, 512, 512, 256, 1]       20                -1  1    656384  models.common.ADown                     [512, 512]                    21          [-1, 10]  1         0  models.common.Concat                    [1]                           22                -1  1   3119616  models.common.RepNCSPELAN4              [1024, 512, 512, 256, 1]      23                 5  1    131328  models.common.CBLinear                  [512, [256]]                  24                 7  1    393984  models.common.CBLinear                  [512, [256, 512]]             25                 9  1    656640  models.common.CBLinear                  [512, [256, 512, 512]]        26                 0  1      1856  models.common.Conv                      [3, 64, 3, 2]                 27                -1  1     73984  models.common.Conv                      [64, 128, 3, 2]               28                -1  1    212864  models.common.RepNCSPELAN4              [128, 256, 128, 64, 1]        29                -1  1    164352  models.common.ADown                     [256, 256]                    30  [23, 24, 25, -1]  1         0  models.common.CBFuse                    [[0, 0, 0]]                   31                -1  1    847616  models.common.RepNCSPELAN4              [256, 512, 256, 128, 1]       32                -1  1    656384  models.common.ADown                     [512, 512]                    33      [24, 25, -1]  1         0  models.common.CBFuse                    [[1, 1]]                      34                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]       35                -1  1    656384  models.common.ADown                     [512, 512]                    36          [25, -1]  1         0  models.common.CBFuse                    [[2]]                         37                -1  1   2857472  models.common.RepNCSPELAN4              [512, 512, 512, 256, 1]       38[31, 34, 37, 16, 19, 22]  1  21542822  DualDDetect                             [1, [512, 512, 512, 256, 512, 512]]
yolov9-c-CARAFE summary: 982 layers, 51180982 parameters, 51180950 gradients, 239.2 GFLOPs
http://www.lryc.cn/news/433228.html

相关文章:

  • SpringMVC上
  • 嵌入式软件--51单片机 DAY 2
  • 高精度加法,减法,乘法,除法
  • 学习计划(大三上)
  • 【第0006页 · 数组】寻找重复数
  • 移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——10.继承
  • uniapp+vue3实现双通道透明MP4播放支持小程序和h5
  • 汇编:嵌入式软件架构学习资源
  • python编程知识(实现数据加密和解密)
  • 如何使div居中?CSS居中终极指南
  • Redis 篇-深入了解分布式锁 Redisson 原理(可重入原理、可重试原理、主从一致性原理、解决超时锁失效)
  • PostgreSQL中的多版本并发控制(MVCC)深入解析
  • SpringBoot项目-实现简单的CRUD功能和分页查询
  • CCF编程能力等级认证GESP—C++2级—20240907
  • C语言手撕实战代码_二叉排序树(二叉搜索树)_构建_删除_插入操作详解
  • YC教父的创始人模式VS职业经理人模式:AI时代的独立开发者崛起
  • [SUCTF 2019]Pythonginx
  • 省市县相关校验sql随笔
  • uniapp ios sticky定位,内部 u-tabs(包含scroll-view)消失问题
  • web群集--nginx配置文件location匹配符的优先级顺序详解及验证
  • Vivado编译报错黑盒子问题
  • 【建造者模式】
  • 自动化表格处理的革命:智能文档系统技术解析
  • 【Hot100】LeetCode—394. 字符串解码
  • 12. 如何在MyBatis中进行分页查询?常见的分页实现方式有哪些?
  • @[TOC](力扣题目-滑动窗口-qsort排序-二分法查找)
  • Docker容器相关命令
  • 【老课推荐】基于LangChain和知识图谱的大模型医疗问答机器人项目
  • Adobe Sensei——自动化视频编辑、特效应用和素材增强,通过AI技术快速优化视频内容,自动修复视频质量、自动添加背景音乐或字幕
  • 【AIGC数字人】EchoMimic:基于可编辑关键点条件的类人音频驱动肖像动画