YOLOv5更换骨干网络之 GhostNet

YOLOv5更换骨干网络之 GhostNet_第1张图片
YOLOv5更换骨干网络之 GhostNet_第2张图片

论文地址:https://arxiv.org/abs/1911.11907
代码地址:https://github.com/huawei-noah/ghostnet

由于内存和计算资源有限,在嵌入式设备上部署卷积神经网络(CNN)很困难。特征图中的冗余是那些成功的神经网络的重要特征,但在神经架构设计中很少研究。本文提出了一种新的Ghost模块,以从廉价的操作中生成更多的特征图。基于一组内在特征图,我们以低成本应用一系列线性变换来生成许多重影特征图,这些重影特征可以充分揭示内在特征的信息。所提出的Ghost模块可以作为即插即用组件来升级现有的卷积神经网络。Ghost瓶颈被设计为堆叠Ghost模块,然后可以轻松地建立轻量级GhostNet。在基准上进行的实验表明,所提出的Ghost模块是基线模型中卷积层的一个令人印象深刻的替代方案,并且我们的GhostNet可以在ImageNet ILSVRC2012分类数据集上以类似的计算成本实现比MobileNetV3更高的识别性能(例如,75.7%的前1精度)。代码可从https://github.com/huawei-noah/ghostnet获取。


GhostNet网络结构

YOLOv5更换骨干网络之 GhostNet_第3张图片
将YOLOv5主干网络替换为GhostNet:

yolov5lGhost.yaml

# YOLOv5  by Ultralytics, GPL-3.0 license

# Parameters
nc: 80  # number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple
anchors:
  - [10,13, 16,30, 33,23]  # P3/8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

# Ghostnet backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [16, 3, 2, 1]],            # 0-P1/2  ch_out, kernel, stride, padding, groups
   [-1, 1, G_bneck, [16, 16, 3, 1]],        # 1  ch_out, ch_mid, dw-kernel, stride

   [-1, 1, G_bneck, [24, 48, 3, 2]],        # 2-P2/4
   [-1, 1, G_bneck, [24, 72, 3, 1]],        # 3

   [-1, 1, G_bneck, [40, 72, 3, 2, True]],  # 4-P3/8
   [-1, 1, G_bneck, [40, 120, 3, 1, True]], # 5

   [-1, 1, G_bneck, [80, 240, 3, 2]],        # 6-P4/16
   [-1, 3, G_bneck, [80, 184, 3, 1]],        # 7
   [-1, 1, G_bneck, [112, 480, 3, 1, True]],
   [-1, 1, G_bneck, [112, 480, 3, 1, True]],

   [-1, 1, G_bneck, [160, 672, 3, 2, True]], # 10-P5/32
   [-1, 1, G_bneck, [160, 960, 3, 1]],       # 11
   [-1, 1, G_bneck, [160, 960, 3, 1, True]],
   [-1, 1, G_bneck, [160, 960, 3, 1]],
   [-1, 1, G_bneck, [160, 960, 3, 1, True]],
   [-1, 1, Conv, [960]],
  ]

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

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

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

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

   [[23, 26, 29], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

在YOLOv5项目中添加方式:

common.py中加入以下代码:

class SeBlock(nn.Module):
    def __init__(self, in_channel, reduction=4):
        super().__init__()
        self.Squeeze = nn.AdaptiveAvgPool2d(1)

        self.Excitation = nn.Sequential()
        self.Excitation.add_module('FC1', nn.Conv2d(in_channel, in_channel // reduction, kernel_size=1))  # 1*1卷积与此效果相同
        self.Excitation.add_module('ReLU', nn.ReLU())
        self.Excitation.add_module('FC2', nn.Conv2d(in_channel // reduction, in_channel, kernel_size=1))
        self.Excitation.add_module('Sigmoid', nn.Sigmoid())

    def forward(self, x):
        y = self.Squeeze(x)
        ouput = self.Excitation(y)
        return x * (ouput.expand_as(x))

class G_bneck(nn.Module):
    # Ghost Bottleneck https://github.com/huawei-noah/ghostnet
    def __init__(self, c1, c2, midc, k=5, s=1, use_se = False):  # ch_in, ch_mid, ch_out, kernel, stride, use_se
        super().__init__()
        assert s in [1, 2]
        c_ = midc
        self.conv = nn.Sequential(GhostConv(c1, c_, 1, 1),              # Expansion
                                  Conv(c_, c_, 3, s=2, p=1, g=c_, act=False) if s == 2 else nn.Identity(),  # dw
                                  # Squeeze-and-Excite
                                  SeBlock(c_) if use_se else nn.Sequential(),
                                  GhostConv(c_, c2, 1, 1, act=False))   # Squeeze pw-linear

        self.shortcut = nn.Identity() if (c1 == c2 and s == 1) else \
                                                nn.Sequential(Conv(c1, c1, 3, s=s, p=1, g=c1, act=False), \
                                                Conv(c1, c2, 1, 1, act=False)) # 避免stride=2时 通道数改变的情况

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

yolo.py中添加如下代码:YOLOv5更换骨干网络之 GhostNet_第4张图片


本人更多YOLOv5实战内容导航

  1. 手把手带你调参Yolo v5 (v6.2)(推理)强烈推荐

  2. 手把手带你调参Yolo v5 (v6.2)(训练)

  3. 手把手带你调参Yolo v5 (v6.2)(验证)

  4. 如何快速使用自己的数据集训练Yolov5模型

  5. 手把手带你Yolov5 (v6.2)添加注意力机制(一)(并附上30多种顶会Attention原理图)强烈推荐新增8种

  6. 手把手带你Yolov5 (v6.2)添加注意力机制(二)(在C3模块中加入注意力机制)

  7. Yolov5如何更换激活函数?

  8. Yolov5如何更换BiFPN?

  9. Yolov5 (v6.2)数据增强方式解析

  10. Yolov5更换上采样方式( 最近邻 / 双线性 / 双立方 / 三线性 / 转置卷积)

  11. Yolov5如何更换EIOU / alpha IOU / SIoU?

  12. Yolov5更换主干网络之《旷视轻量化卷积神经网络ShuffleNetv2》

  13. YOLOv5应用轻量级通用上采样算子CARAFE

  14. 空间金字塔池化改进 SPP / SPPF / SimSPPF / ASPP / RFB / SPPCSPC / SPPFCSPC

  15. 用于低分辨率图像和小物体的模块SPD-Conv

  16. GSConv+Slim-neck 减轻模型的复杂度同时提升精度

  17. 头部解耦 | 将YOLOX解耦头添加到YOLOv5 | 涨点杀器

  18. Stand-Alone Self-Attention | 搭建纯注意力FPN+PAN结构

  19. YOLOv5模型剪枝实战

  20. YOLOv5知识蒸馏实战

  21. YOLOv7知识蒸馏实战

  22. 改进YOLOv5 | 引入密集连接卷积网络DenseNet思想 | 搭建密集连接模块

  23. YOLOv5更换骨干网络之 PP-LCNet

  24. YOLOv5更换骨干网络之 EfficientNet-B0

  25. YOLOv5 框架引入 Google 轻量化网络 MobileNet V3


参考文献:

https://github.com/Gumpest/YOLOv5-Multibackbone-Compression

你可能感兴趣的:(YOLOv5改进实战,人工智能,深度学习,论文)