当前位置:   article > 正文

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

yolov5轻量化改进

在这里插入图片描述


前言

轻量化网络设计是一种针对移动设备等资源受限环境的深度学习模型设计方法。下面是一些常见的轻量化网络设计方法:

  1. 网络剪枝:移除神经网络中冗余的连接和参数,以达到模型压缩和加速的目的。
  2. 分组卷积:将卷积操作分解为若干个较小的卷积操作,并将它们分别作用于输入的不同通道,从而减少计算量。
  3. 深度可分离卷积:将标准卷积分解成深度卷积和逐点卷积两个步骤,使得在大部分情况下可以大幅减少计算量。
  4. 跨层连接:通过跨越多个层级的连接方式来增加神经网络的深度和复杂性,同时减少了需要训练的参数数量。
  5. 模块化设计:将神经网络分解为多个可重复使用的模块,以提高模型的可调节性和适应性。

传统的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%。
在这里插入图片描述

  • 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([y, self.cv2(y)], 1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 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)))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

二、代码实现

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[f], args[0]
    if c2 != no:  # if not output
        c2 = make_divisible(c2 * gw, 8)

    args = [c1, c2, *args[1:]]
    if m in {BottleneckCSP, C3, C3TR, C3Ghost, C3x}:
        args.insert(2, n)  # number of repeats
        n = 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.2 yolov5s-ghost-backbone.yaml

细心的小伙伴可能会发现在models/hub文件夹下已经有yolov5s-ghost.yaml配置文件,不过官方给的是将整个网络的Conv和C3模块替换成了GhostConvC3Ghost。这里我们只替换Backbone中的Conv和C3模块,当然两者哪个效果更好,需要各位去实测一番。

# YOLOv5 声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签