不到断气不罢休 发表于 2024-6-22 19:57:46

YOLOv5改进实战 | 更换主干网络Backbone(一)之轻量化网络Ghostnet

https://img-blog.csdnimg.cn/98a8f2433e8f48d79132f8f70890a741.png#pic_center
前言
轻量化网络计划是一种针对移动设备等资源受限环境的深度学习模子计划方法。下面是一些常见的轻量化网络计划方法:

[*]网络剪枝:移除神经网络中冗余的毗连和参数,以达到模子压缩和加快的目的。
[*]分组卷积:将卷积操作分解为若干个较小的卷积操作,并将它们分别作用于输入的差别通道,从而淘汰计算量。
[*]深度可分离卷积:将尺度卷积分解成深度卷积和逐点卷积两个步骤,使得在大部分情况下可以大幅淘汰计算量。
[*]跨层毗连:通过超过多个层级的毗连方式来增加神经网络的深度和复杂性,同时淘汰了需要练习的参数数量。
[*]模块化计划:将神经网络分解为多个可重复使用的模块,以进步模子的可调节性温顺应性。
传统的YOLOv5系列中,Backbone采用的是较为复杂的C3网络结构,这使得模子计算量大幅度的增加,检测速度较慢,应用受限,在某些真实的应用场景如移动或者嵌入式设备,云云大而复杂的模子时难以被应用的。为了解决这个问题,本章节通过采用Ghostnet轻量化主干网络作为Backbone的基础结构,从而在保证检测性能的同时,将网络结构精简到最小,大大减小了模子的参数量和计算量。


一、Ghostnet

   2020 CVPR 论文链接:GhostNet: More Features from Cheap Operations
Pytorch code:ghostnet_pytorch
轻量级神经网络Ghostnet是专门为移动设备上的应用而计划的,由Ghost bottleneck搭建而成,而Ghost bottleneck通过Ghost模块堆叠。Ghost 模块是一种新颖的即插即用模块。Ghost 模块计划的初衷是使用更少的参数来生成更多特征图 (generate more features by using fewer parameters)。在ImageNet分类任务,GhostNet在相似计算量情况下Top-1精确率达75.7%,高于MobileNetV3的75.2%。
https://img-blog.csdnimg.cn/46825c1b8cd94e58b709447af5420197.png#pic_center


[*] GhostConv
class GhostConv(nn.Module):
    # Ghost Convolution https://github.com/huawei-noah/ghostnet
    def __init__(self, c1, c2, k=1, s=1, g=1, act=True):# ch_in, ch_out, kernel, stride, groups
      super(GhostConv, self).__init__()
      c_ = c2 // 2# hidden channels
      self.cv1 = Conv(c1, c_, k, s, None, g, act)
      self.cv2 = Conv(c_, c_, 5, 1, None, c_, act)

    def forward(self, x):
      y = self.cv1(x)
      return torch.cat(, 1)

[*] Ghost Bottleneck
class GhostBottleneck(nn.Module):
    # Ghost Bottleneck https://github.com/huawei-noah/ghostnet
    def __init__(self, c1, c2, k=3, s=1):# ch_in, ch_out, kernel, stride
      super().__init__()
      c_ = c2 // 2
      self.conv = nn.Sequential(
            GhostConv(c1, c_, 1, 1),# pw
            DWConv(c_, c_, k, s, act=False) if s == 2 else nn.Identity(),# dw
            GhostConv(c_, c2, 1, 1, act=False))# pw-linear
      self.shortcut = nn.Sequential(DWConv(c1, c1, k, s, act=False), Conv(c1, c2, 1, 1,
                                                                            act=False)) if s == 2 else nn.Identity()

    def forward(self, x):
      return self.conv(x) + self.shortcut(x)

[*] C3Ghost
class C3Ghost(C3):
    # C3 module with GhostBottleneck()
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
      super().__init__(c1, c2, n, shortcut, g, e)
      c_ = int(c2 * e)# hidden channels
      self.m = nn.Sequential(*(GhostBottleneck(c_, c_) for _ in range(n)))

二、代码实现

2.1 无需修改common.py和yolo.py文件

YOLOv5-7.0最新版已经添加了GhostConv、Ghost Bottleneck、C3Ghost三个模块,可以说是很方便了。甚至在models/yolo.py文件中已经注册这三个模块。所以我们无需做任何修改,只需修改yaml文件。
if m in {
      Conv, GhostConv, Bottleneck, GhostBottleneck, SPP, SPPF, DWConv, MixConv2d, Focus, CrossConv,
      BottleneckCSP, C3, C3TR, C3SPP, C3Ghost, nn.ConvTranspose2d, DWConvTranspose2d, C3x}:
    c1, c2 = ch, args
    if c2 != no:# if not output
      c2 = make_divisible(c2 * gw, 8)

    args = ]
    if m in {BottleneckCSP, C3, C3TR, C3Ghost, C3x}:
      args.insert(2, n)# number of repeats
      n = 1
2.2 yolov5s-ghost-backbone.yaml

细心的小伙伴可能会发现在models/hub文件夹下已经有yolov5s-ghost.yaml设置文件,不过官方给的是将整个网络的Conv和C3模块更换成了GhostConv和C3Ghost。这里我们只更换Backbone中的Conv和C3模块,当然两者哪个结果更好,需要各位去实测一番。
# YOLOv5
页: [1]
查看完整版本: YOLOv5改进实战 | 更换主干网络Backbone(一)之轻量化网络Ghostnet