首页 > 其他分享 >YOLOv9改进策略【卷积层】| GnConv:一种通过门控卷积和递归设计来实现高效、可扩展、平移等变的高阶空间交互操作

YOLOv9改进策略【卷积层】| GnConv:一种通过门控卷积和递归设计来实现高效、可扩展、平移等变的高阶空间交互操作

时间:2024-09-18 08:51:37浏览次数:3  
标签:卷积 self YOLOv9 models common 512 256 门控

一、本文介绍

本文记录的是利用GnConv优化YOLOv9的目标检测方法研究。YOLOv9在进行目标检测时,需要对不同层次的特征进行融合。GnConv可以考虑更高阶的空间交互,能够更好地捕捉特征之间的复杂关系,从而增强特征融合的效果,提高模型对目标的检测能力。

文章目录


二、HorNet原理介绍

HorNet: 利用递归门控卷积实现高效高阶空间交互

GnConv(Recursive Gated Convolution,递归门控卷积)是论文中提出的一种高效操作,用于实现长期和高阶空间交互,其设计原理、计算公式和优势如下:

2.1、GnConv设计原理

  • 输入自适应交互与门控卷积Vision Transformer的成功主要依赖于对视觉数据中空间交互的适当建模,与简单使用静态卷积核聚合相邻特征的CNN不同,Vision Transformer应用多头自注意力来动态生成权重以混合空间标记,但自注意力关于输入大小的二次复杂度在很大程度上阻碍了其应用,尤其是在需要更高分辨率特征图的下游任务中。在这项工作中,作者寻求一种更有效和高效的方法来执行空间交互,使用门控卷积(gConv)来实现输入自适应的空间混合。
  • 高阶交互与递归门控:在通过gConv实现了高效的一阶空间交互后,作者设计了递归门控卷积(GnConv)来通过引入高阶交互进一步增强模型容量。具体来说,首先使用多个线性投影层( ϕ i n \phi_{in} ϕin​)获得一组投影特征( p 0 p_0 p0​和 q k q_k qk​),然后通过递归的方式执行门控卷积( p k + 1 = f k ( q k ) ⊙ g k ( p k ) / α p_{k + 1} = f_k(q_k) \odot g_k(p_k) / \alpha pk+1​=fk​(qk​)⊙gk​(pk​)/α),其中 f k f_k fk​是一组深度卷积层, g k g_k gk​用于匹配不同阶的维度,最后将最后一次递归步骤的输出 q n q_n qn​送入投影层 ϕ o u t \phi_{out} ϕout​以获得 g n C o n v g^{n}Conv gnConv的结果。从递归公式可以看出, p k p_k pk​的交互阶数在每一步后都会增加1,因此 g n C o n v gnConv gnConv实现了 n n n阶空间交互。
  • 大核卷积与长期交互:为了使 G n C o n v GnConv GnConv能够捕捉长期交互,作者采用了两种实现方式来处理深度卷积 f f f:
    • 7×7卷积:7×7是Swin TransformersConvNext的默认窗口/核大小,研究表明该核大小在ImageNet分类和各种下游任务中产生良好性能,因此作者遵循此配置以公平地与代表性的Vision Transformer和现代CNN进行比较。
    • 全局滤波器(GF):GF层通过将频域特征与可学习的全局滤波器相乘,相当于在空间域中进行具有全局核大小和循环填充的卷积。作者使用了GF层的修改版本,即处理一半的通道与全局滤波器相乘,另一半与3×3深度卷积相乘,并仅在后期阶段使用GF层以保留更多局部细节。

2.2、GnConv计算公式

门控卷积输出

令 x ∈ R H W × C x \in \mathbb{R}^{H W \times C} x∈RHW×C为输入特征,门控卷积 y = g C o n v ( x ) y = gConv(x) y=gConv(x)的输出可写为:
[ p 0 H W × C , q 0 H W × C ] = ϕ i n ( x ) ∈ R H W × 2 C , y = f ( q 0 ) ⊙ p 0 ∈ R H W × C , y = ϕ o u t ( p 1 ) ∈ R H W × C , \begin{array}{r} {\left[p_{0}^{H W \times C}, q_{0}^{H W \times C}\right]=\phi_{in }(x) \in \mathbb{R}^{H W \times 2 C},} \\ y = f\left(q_{0}\right) \odot p_{0} \in \mathbb{R}^{H W \times C}, \\ y = \phi_{out }\left(p_{1}\right) \in \mathbb{R}^{H W \times C}, \end{array} [p0HW×C​,q0HW×C​]=ϕin​(x)∈RHW×2C,y=f(q0​)⊙p0​∈RHW×C,y=ϕout​(p1​)∈RHW×C,​

其中 ϕ i n \phi_{in} ϕin​和 ϕ o u t \phi_{out} ϕout​是线性投影层以执行通道混合, f f f是深度卷积。注意到 p 1 ( i , c ) = ∑ j ∈ Ω i w i → j c q 0 ( j , c ) p 0 ( i , c ) p_{1}^{(i, c)}=\sum_{j \in \Omega_{i}} w_{i \to j}^{c} q_{0}^{(j, c)} p_{0}^{(i, c)} p1(i,c)​=∑j∈Ωi​​wi→jc​q0(j,c)​p0(i,c)​,其中 Ω i \Omega_{i} Ωi​是以为 i i i中心的局部窗口, w i → j w_{i \to j} wi→j​代表卷积权重。

  • 递归门控卷积
    [ p 0 H W × C 0 , q 0 H W × C 0 , … , q n − 1 H W × C n − 1 ] = ϕ i n ( x ) ∈ R H W × ( C 0 + ∑ 0 ≤ k ≤ n − 1 C k ) , p k + 1 = f k ( q k ) ⊙ g k ( p k ) / α , k = 0 , 1 , … , n − 1 , \begin{aligned} &\left[p_{0}^{H W \times C_{0}}, q_{0}^{H W \times C_{0}}, \ldots, q_{n - 1}^{H W \times C_{n - 1}}\right]=\phi_{in }(x) \in \mathbb{R}^{H W \times\left(C_{0} + \sum_{0 \leq k \leq n - 1} C_{k}\right)}, \\ &p_{k + 1} = f_{k}\left(q_{k}\right) \odot g_{k}\left(p_{k}\right) / \alpha, k = 0, 1, \ldots, n - 1, \end{aligned} ​[p0HW×C0​​,q0HW×C0​​,…,qn−1HW×Cn−1​​]=ϕin​(x)∈RHW×(C0​+∑0≤k≤n−1​Ck​),pk+1​=fk​(qk​)⊙gk​(pk​)/α,k=0,1,…,n−1,​
    其中 g k g_{k} gk​的定义为: g k = { I d e n t i t y , k = 0 L i n e a r ( C k − 1 , C k ) , 1 ≤ k ≤ n − 1 g_{k}=\begin{cases}Identity, & k = 0 \\Linear\left(C_{k - 1}, C_{k}\right), & 1 \leq k \leq n - 1\end{cases} gk​={Identity,Linear(Ck−1​,Ck​),​k=01≤k≤n−1​。
  • 计算复杂度:总FLOPs为: F L O P s ( g n C o n v ) < H W C ( 2 K 2 + 11 3 × C + 2 ) FLOPs\left(g^{n}Conv\right) < HW C\left(2K^{2} + \frac{11}{3} \times C + 2\right) FLOPs(gnConv)<HWC(2K2+311​×C+2),其中 K K K是深度卷积的核大小。

在这里插入图片描述

2.3、优势

  • 高效:基于卷积的实现避免了自注意力的二次复杂度。在执行空间交互时逐渐增加通道宽度的设计也使能够以有限的复杂度实现更高阶的交互。
  • 可扩展:将自注意力中的二阶交互扩展到任意阶,以进一步提高建模能力。由于不对空间卷积的类型做假设,因此(gnConv)与各种核大小和空间混合策略兼容。
  • 平移等变性:完全继承了标准卷积的平移等变性,这为主要视觉任务引入了有益的归纳偏差,并避免了局部注意力带来的不对称性。

论文:https://arxiv.org/pdf/2207.14284
源码:https://github.com/raoyongming/HorNet

三、GnConv的实现代码

GnConv模块的实现代码如下:


def get_dwconv(dim, kernel, bias):
    return nn.Conv2d(dim, dim, kernel_size=kernel, padding=(kernel-1)//2 ,bias=bias, groups=dim)

class gnConv(nn.Module):
    def __init__(self, dim, order=5, gflayer=None, h=14, w=8, s=1.0):
        super().__init__()
        self.order = order
        self.dims = [dim // 2 ** i for i in range(order)]
        self.dims.reverse()
        self.proj_in = nn.Conv2d(dim, 2*dim, 1)
 
        if gflayer is None:
            self.dwconv = get_dwconv(sum(self.dims), 7, True)
        else:
            self.dwconv = gflayer(sum(self.dims), h=h, w=w)
        
        self.proj_out = nn.Conv2d(dim, dim, 1)
 
        self.pws = nn.ModuleList(
            [nn.Conv2d(self.dims[i], self.dims[i+1], 1) for i in range(order-1)]
        )
        self.scale = s
 
    def forward(self, x, mask=None, dummy=False):
        # B, C, H, W = x.shape gnconv [512]by iscyy/air
        fused_x = self.proj_in(x)
        pwa, abc = torch.split(fused_x, (self.dims[0], sum(self.dims)), dim=1)
        dw_abc = self.dwconv(abc) * self.scale
        dw_list = torch.split(dw_abc, self.dims, dim=1)
        x = pwa * dw_list[0]
        for i in range(self.order -1):
            x = self.pws[i](x) * dw_list[i+1]
        x = self.proj_out(x)
 
        return x

四、添加步骤

4.1 修改common.py

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

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

4.1.1 创新模块⭐

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

在这里插入图片描述

2️⃣基于gnConvRepNCSPELAN4

第二种改进方法是对YOLOv9中的RepNCSPELAN4模块进行改进。将gnConv模块RepNCSPELAN4 结合后,替换其中的普通卷积可以使YOLOv9实现更高阶的空间交互,更好地捕捉特征之间的复杂关系,从而提高模型的建模能力。

改进代码如下:

class GnRepNCSPELAN4(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), gnConv(c4))
        self.cv3 = nn.Sequential(RepNCSP(c4, c4, c5), gnConv(c4))
        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文件中需要声明的模块名称为:gnConvGnRepNCSPELAN4

4.2 修改yolo.py

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

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

gnConv模块以及GnRepNCSPELAN4模块添加后如下:

在这里插入图片描述


五、yaml模型文件

5.1 模型改进⭐

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

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

yolov9-c.yaml中的内容复制到yolov9-c-GnRepNCSPELAN4.yaml文件下,修改nc数量等于自己数据中目标的数量。
在骨干网络中,将四个RepNCSPELAN4模块替换成GnRepNCSPELAN4模块

# YOLOv9

# parameters
nc: 80  # 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, GnRepNCSPELAN4, [256, 128, 64, 1]],  # 3

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

   # elan-2 block
   [-1, 1, GnRepNCSPELAN4, [512, 256, 128, 1]],  # 5

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

   # elan-2 block
   [-1, 1, GnRepNCSPELAN4, [512, 512, 256, 1]],  # 7

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

   # elan-2 block
   [-1, 1, GnRepNCSPELAN4, [512, 512, 256, 1]],  # 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)
  ]



六、成功运行结果

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

yolov9-c-GnRepNCSPELAN4

                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   2209152  models.common.GnRepNCSPELAN4            [512, 512, 512, 256, 1]       
10                -1  1    656896  models.common.SPPELAN                   [512, 512, 256]               
11                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          
12           [-1, 7]  1         0  models.common.Concat                    [1]                           
13                -1  1   3119616  models.common.RepNCSPELAN4              [1024, 512, 512, 256, 1]      
14                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          
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  21725312  DualDDetect                             [80, [512, 512, 512, 256, 512, 512]]
yolov9-c-GnRepNCSPELAN4 summary: 974 layers, 50533760 parameters, 50533728 gradients, 239.4 GFLOPs

标签:卷积,self,YOLOv9,models,common,512,256,门控
From: https://blog.csdn.net/qq_42591591/article/details/141787872

相关文章

  • YOLOv9改进系列,YOLOv9主干网络替换为RepViT (CVPR 2024,清华提出,独家首发),助力涨点
    摘要轻量级视觉变换器(ViTs)在资源受限的移动设备上表现出优越的性能和较低的延迟,相比之下轻量级卷积神经网络(CNNs)稍显逊色。研究人员发现了许多轻量级ViTs和轻量级CNNs之间的结构联系。然而,它们在块结构、宏观和微观设计上的显著架构差异尚未得到充分研究。在本研究中......
  • YOLOv9改进策略【卷积层】| SCConv:即插即用,减少冗余计算并提升特征学习
    一、本文介绍本文记录的是利用SCConv优化YOLOv9的目标检测网络模型。深度神经网络中存在大量冗余,不仅在密集模型参数中,而且在特征图的空间和通道维度中。SCConv模块通过联合减少卷积层中空间和通道的冗余,有效地限制了特征冗余,本文利用SCConv模块改进YOLOv9,提高了模型的性能......
  • 基于卷积神经网络的图像去噪研究 毕业设计(案例展示)
    开发一种基于卷积神经网络(CNN)的高效图像去噪技术。图像去噪是图像处理领域的一个关键挑战,对于图像质量的提升、目标检测、目标跟踪以及图像分析等研究领域至关重要。CNN因其在图像识别和处理任务中的卓越性能而成为本研究的核心工具。研究内容包括分析图像去噪的重要性、评述当......
  • YOLOv9改进策略【损失函数篇】| 引入Soft-NMS,提升密集遮挡场景检测精度,包括GIoU-NMS、
    一、背景:传统的非极大值抑制(NMS)算法在目标检测中存在一个问题,即当一个物体的检测框与具有最高得分的检测框M有重叠(在预定义的重叠阈值内)时,会将该检测框的得分设置为零,从而导致该物体可能被遗漏,降低了平均精度。为了解决这个问题,作者提出了Soft-NMS算法。本文将YOLOv9默认......
  • 【特征融合】卷积神经网络中的特征融合方式有哪些??让我们一起看看!
    【特征融合】卷积神经网络中的特征融合方式总结与探索…【特征融合】卷积神经网络中的特征融合方式总结与探索…前言:**在深度学习中,**特征融合(FeatureFusion)是一种将不同特征图或不同层的输出进行组合的技术,旨在提升模型的表现。特征融合主要用于增强特征表示能力,特别......
  • YOLOv9改进策略【Neck】| 有效且轻量的动态上采样算子:DySample
    一、本文介绍本文记录的是利用DySample上采样对YOLOv9的颈部网络进行改进的方法研究。YOLOv9采用传统的最近邻插值的方法进行上采样可能无法有效地捕捉特征的细节和语义信息,从而影响模型在密集预测任务中的性能。DySample通过动态采样的方式进行上采样,能够更好地处理特征的......
  • YOLOv9改进策略【Neck】| 使用CARAFE轻量级通用上采样算子
    一、本文介绍本文记录的是利用CARAFE上采样对YOLOv9的颈部网络进行改进的方法研究。YOLOv9采用传统的最近邻插值的方法,仅考虑子像素邻域,无法捕获密集预测任务所需的丰富语义信息,从而影响模型在密集预测任务中的性能。CARAFE通过在大感受野内聚合信息、能够实时适应实例特定......
  • YOLOv9改进策略【Neck】| AIFI : 基于Transformer的尺度内特征交互,在降低计算成本的同
    一、本文介绍本文记录的是基于AIFI模块的YOLOv9目标检测改进方法研究。AIFI是RT-DETR中高效混合编码器的一部分,利用其改进YOLOv9模型,使网络在深层能够更好的捕捉到概念实体之间的联系,并有助于后续模块对对象进行定位和识别。文章目录一、本文介绍二、AIFI设计原理2.1、......
  • 卷积神经网络多输入和多输出的通道数(李沐老师课程)
    多通道卷积计算特殊的卷积层1*1卷积核代码:"""​多输入多输出的互相关运算"""importtorchfromtorchimportnnfromd2limporttorchasd2l​"""实现多输入通道互相关运算"""​​defcorr2d_multi_in(x,k): returnsum(d2l.corr......
  • 卷积神经网络(李沐老师课程)
    卷积神经网络(李沐老师课程)回顾MLP单层(上述列子需要14GBGPU)找寻图片上的人在哪里找寻图片上的人的两个基本原则从全连接层出发到卷积卷积层二维交叉相关二维卷积层案列交叉相关和卷积代码的实现importtorchfromtorchimportnnfromd2limportt......