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

打印 上一主题 下一主题

主题 540|帖子 540|积分 1620




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

  • 网络剪枝:移除神经网络中冗余的毗连和参数,以达到模子压缩和加快的目的。
  • 分组卷积:将卷积操作分解为若干个较小的卷积操作,并将它们分别作用于输入的差别通道,从而淘汰计算量。
  • 深度可分离卷积:将尺度卷积分解成深度卷积和逐点卷积两个步骤,使得在大部分情况下可以大幅淘汰计算量。
  • 跨层毗连:通过超过多个层级的毗连方式来增加神经网络的深度和复杂性,同时淘汰了需要练习的参数数量。
  • 模块化计划:将神经网络分解为多个可重复使用的模块,以进步模子的可调节性温顺应性。
传统的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
    1. class GhostConv(nn.Module):
    2.     # Ghost Convolution https://github.com/huawei-noah/ghostnet
    3.     def __init__(self, c1, c2, k=1, s=1, g=1, act=True):  # ch_in, ch_out, kernel, stride, groups
    4.         super(GhostConv, self).__init__()
    5.         c_ = c2 // 2  # hidden channels
    6.         self.cv1 = Conv(c1, c_, k, s, None, g, act)
    7.         self.cv2 = Conv(c_, c_, 5, 1, None, c_, act)
    8.     def forward(self, x):
    9.         y = self.cv1(x)
    10.         return torch.cat([y, self.cv2(y)], 1)
    复制代码
  • Ghost Bottleneck
    1. class GhostBottleneck(nn.Module):
    2.     # Ghost Bottleneck https://github.com/huawei-noah/ghostnet
    3.     def __init__(self, c1, c2, k=3, s=1):  # ch_in, ch_out, kernel, stride
    4.         super().__init__()
    5.         c_ = c2 // 2
    6.         self.conv = nn.Sequential(
    7.             GhostConv(c1, c_, 1, 1),  # pw
    8.             DWConv(c_, c_, k, s, act=False) if s == 2 else nn.Identity(),  # dw
    9.             GhostConv(c_, c2, 1, 1, act=False))  # pw-linear
    10.         self.shortcut = nn.Sequential(DWConv(c1, c1, k, s, act=False), Conv(c1, c2, 1, 1,
    11.                                                                             act=False)) if s == 2 else nn.Identity()
    12.     def forward(self, x):
    13.         return self.conv(x) + self.shortcut(x)
    复制代码
  • C3Ghost
    1. class C3Ghost(C3):
    2.     # C3 module with GhostBottleneck()
    3.     def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
    4.         super().__init__(c1, c2, n, shortcut, g, e)
    5.         c_ = int(c2 * e)  # hidden channels
    6.         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文件。
  1. if m in {
  2.         Conv, GhostConv, Bottleneck, GhostBottleneck, SPP, SPPF, DWConv, MixConv2d, Focus, CrossConv,
  3.         BottleneckCSP, C3, C3TR, C3SPP, C3Ghost, nn.ConvTranspose2d, DWConvTranspose2d, C3x}:
  4.     c1, c2 = ch[f], args[0]
  5.     if c2 != no:  # if not output
  6.         c2 = make_divisible(c2 * gw, 8)
  7.     args = [c1, c2, *args[1:]]
  8.     if m in {BottleneckCSP, C3, C3TR, C3Ghost, C3x}:
  9.         args.insert(2, n)  # number of repeats
  10.         n = 1
复制代码
2.2 yolov5s-ghost-backbone.yaml

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

不到断气不罢休

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表