首页 > 其他分享 >YOLOv5改进系列:小众但新颖的骨干网络ConvMixer助力涨点

YOLOv5改进系列:小众但新颖的骨干网络ConvMixer助力涨点

时间:2024-03-30 16:33:57浏览次数:20  
标签:dim YOLOv5 涨点 nn Conv self ConvMixer c2

一、论文理论

论文地址:ConvMixer:Patches Are All You Need? 

1.理论思想

背景

尽管多年来卷积网络一直是视觉任务的主要架构,但最近的实验表明,基于 Transformer 的模型,尤其是 Vision Transformer (ViT),在某些设置下可能会超过卷积的性能。然而,由于 transformer中自注意层的 quadratic runtime,ViT 需要使用 patch embeddings,将图像中的小区域组合成单个输入特征,以便应用于更大的图像尺寸。这就提出了一个问题: ViT 的性能是由于固有的更强大的Transformer架构,还是至少部分是因为使用补丁作为输入表示?

方法

本文为后者提供了一些证据:具体来说,提出了 ConvMixer,这是一个非常简单的模型,受到类似于 ViT 启发和更基本的 MLP-Mixer,ConvMixer 直接对输入的 patch 进行操作,分离空间和通道维度的混合,并在整个网络中保持相同的大小和分辨率。然而,相比之下,ConvMixer 只使用标准的卷积来实现混合步骤。

结果

尽管它很简单,本文证明了 ConvMixer 在类似参数计数和数据集大小的情况下优于 ViT、MLP-Mixer 及其一些变体,此外还优于 ResNet 等经典视觉模型。

2.创新点

操作过程:

“ 本文进而探讨了这样一个问题:即 vision transformers 的强大性能可能更多地来自于这种基于 patch 的表示,而不是 Transformer 架构本身。本文开发了一个非常简单的卷积架构,将其命名为 “ConvMixer”,因为它与最近提出的 MLP-Mixer 相似。这个架构在很多方面与 Vision Transformer (和 MLP-Mixer ) 相似:1) 它直接对 patches 进行操作,2) 在所有层中保持相同分辨率和大小的表示,3) 它在连续层不对表示进行下采样,4) 它将信息的 “channel-wise mixing” 与 “spatial mixing” 分离。但与 Vision Transformer 和 MLP-Mixer 不同的是,ConvMixer 架构只通过标准的卷积来完成所有这些操作。”

ConvMixer 取决于四个参数的实例化:(1) 宽度或隐藏维度 h (即 patch embeddings 的维数),(2) 深度 d,即 ConvMixer 层重复的次数,(3) patch 的大小 p,其控制模型的内部分辨率,(4) depthwise 卷积层卷积核的大小 k。本文以其隐藏维度和深度来命名 ConvMixers,比如ConvMixer-h/d。将原始输入大小 n 除以 patch 大小 p 作为内部分辨率;但是请注意,ConvMixers支持可变大小的输入。

二、代码部署

1.代码


def autopad(k, p=None):  # kernel, padding
    # Pad to 'same'
    if p is None:
        p = k // 2 if isinstance(k, int) else [x // 2 for x in k]  # auto-pad
    return p


class Conv(nn.Module):
    # Standard convolution
    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups
        super().__init__()
        self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)
        self.bn = nn.BatchNorm2d(c2)
        self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())

    def forward(self, x):
        return self.act(self.bn(self.conv(x)))

    def forward_fuse(self, x):
        return self.act(self.conv(x))

class ConvMix(nn.Module):
    def __init__(self, dim, dim1, kernel_size=9):
        super().__init__()
        self.Resnet =  nn.Sequential(
            nn.Conv2d(dim,dim, kernel_size=kernel_size, groups=dim, padding='same'),
            nn.GELU(),
            nn.BatchNorm2d(dim)
        )
        self.Conv_1x1 = nn.Sequential(
            nn.Conv2d(dim,dim,kernel_size=1),
            nn.GELU(),
            nn.BatchNorm2d(dim)
        )
    def forward(self,x):
        x = x +self.Resnet(x)
        x = self.Conv_1x1(x)
        return x

class CSPCM(nn.Module):
    # 
    def __init__(self, c1, c2, n=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c1, c_, 1, 1)
        self.cv3 = Conv(2 * c_, c2, 1)  # act=FReLU(c2)
        self.m = nn.Sequential(*(ConvMix(c_, c_) for _ in range(n)))

    def forward(self, x):
        return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1))

2.配置教程

(1)在models/cmmon.py中添加上述代码,将与初始代码中重复类删除

(2)在./models/yolo.py文件下里的parse_model函数,将类名加入进去

           for i, (f, n, m, args) in enumerate(d['backbone'] + d['head']):内部

        elif m in [ConvMix, CSPCM]:
            c1, c2 = ch[f], args[0]
            if c2 != no:  # if not outputss
                c2 = make_divisible(c2 * gw, 8)
            args = [c1, c2, *args[1:]]

3.yaml文件

# Parameters
nc: 2  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple
anchors:
  - [19,27,  44,40,  38,94]  # P3/8
  - [96,68,  86,152,  180,137]  # P4/16
  - [140,301,  303,264,  238,542]  # P5/32
  - [436,615,  739,380,  925,792]  # P6/64

# YOLOv5 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, C3, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 6, C3, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, CSPCM, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# YOLOv5 v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, C3, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)

   [ -1, 1, Conv, [ 128, 1, 1 ] ],
   [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ],
   [ [ -1, 2 ], 1, Concat, [ 1 ] ],  # cat backbone P2
   [ -1, 2, C3, [ 128] ],  # 21 (P2/4-xsmall)

   [ -1, 1, Conv, [ 128, 3, 2 ] ],
   [ [ -1, 18, 4], 1, Concat, [ 1 ] ],  # cat head P3
   [ -1, 2, C3, [ 256] ],  # 24 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14, 6], 1, Concat, [1]],  # cat head P4
   [-1, 2, C3, [512]],  # 27 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 2, CSPCM, [1024]],  # 30 (P5/32-large)

   [[21, 24, 27, 30], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

三、总结

本文主要工作包括ConvMixer介绍及改进代码策略,该模块为即插即用模块,部署位置可根据实际针对任务需求,自行调整

本专栏持续更新中,订阅本栏,关注更新~

标签:dim,YOLOv5,涨点,nn,Conv,self,ConvMixer,c2
From: https://blog.csdn.net/ZzzzzKnight/article/details/137175141

相关文章