0


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

《ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design》

这篇是2018年发表在ECCV上的论文,同时本篇论文还获得了VALSE年度杰出论文奖
原文地址
官方代码


ShuffleNet V2属于比较经典的轻量化网络,通过大量实验提出四条轻量化网络设计准则,对输入输出通道、分组卷积组数、网络碎片化程度、逐元素操作对不同硬件上的速度和内存访问量MAC的影响进行了详细分析。

提出ShuffleNet V2模型,通过Channel Split替代分组卷积,满足四条设计准则,达到了速度和精度的最优权衡。
在这里插入图片描述

Channel Shuffle原理

请添加图片描述

(a)(b)为ShuffleNet V1原理图,(c)(d)为ShuffleNet V2原理图(d为降采样层)


YOLOv5更换方法,三步搞定
第一步;添加如下代码到

common.py
# 通道重排,跨group信息交流defchannel_shuffle(x, groups):
    batchsize, num_channels, height, width = x.data.size()
    channels_per_group = num_channels // groups

    # reshape
    x = x.view(batchsize, groups,
               channels_per_group, height, width)

    x = torch.transpose(x,1,2).contiguous()# flatten
    x = x.view(batchsize,-1, height, width)return x

classCBRM(nn.Module):#conv BN ReLU Maxpool2ddef__init__(self, c1, c2):# ch_in, ch_outsuper(CBRM, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(c1, c2, kernel_size=3, stride=2, padding=1, bias=False),
            nn.BatchNorm2d(c2),
            nn.ReLU(inplace=True),)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)defforward(self, x):return self.maxpool(self.conv(x))classShuffle_Block(nn.Module):def__init__(self, ch_in, ch_out, stride):super(Shuffle_Block, self).__init__()ifnot(1<= stride <=2):raise ValueError('illegal stride value')
        self.stride = stride

        branch_features = ch_out //2assert(self.stride !=1)or(ch_in == branch_features <<1)if self.stride >1:
            self.branch1 = nn.Sequential(
                self.depthwise_conv(ch_in, ch_in, kernel_size=3, stride=self.stride, padding=1),
                nn.BatchNorm2d(ch_in),

                nn.Conv2d(ch_in, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
                nn.BatchNorm2d(branch_features),
                nn.ReLU(inplace=True),)

        self.branch2 = nn.Sequential(
            nn.Conv2d(ch_in if(self.stride >1)else branch_features,
                      branch_features, kernel_size=1, stride=1, padding=0, bias=False),
            nn.BatchNorm2d(branch_features),
            nn.ReLU(inplace=True),

            self.depthwise_conv(branch_features, branch_features, kernel_size=3, stride=self.stride, padding=1),
            nn.BatchNorm2d(branch_features),

            nn.Conv2d(branch_features, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
            nn.BatchNorm2d(branch_features),
            nn.ReLU(inplace=True),)@staticmethoddefdepthwise_conv(i, o, kernel_size, stride=1, padding=0, bias=False):return nn.Conv2d(i, o, kernel_size, stride, padding, bias=bias, groups=i)defforward(self, x):if self.stride ==1:
            x1, x2 = x.chunk(2, dim=1)# 按照维度1进行split
            out = torch.cat((x1, self.branch2(x2)), dim=1)else:
            out = torch.cat((self.branch1(x), self.branch2(x)), dim=1)

        out = channel_shuffle(out,2)return out

第二步

yolo.py

里加上

CBRM

Shuffle_Block

请添加图片描述

第三步;修改配置文件

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license# Parametersnc:20# number of classesdepth_multiple:1.0# model depth multiplewidth_multiple:1.0# layer channel multipleanchors:-[10,13,16,30,33,23]# P3/8-[30,61,62,45,59,119]# P4/16-[116,90,156,198,373,326]# P5/32# YOLOv5 v6.0 backbonebackbone:# [from, number, module, args]# Shuffle_Block: [out, stride][[-1,1, CBRM,[32]],# 0-P2/4[-1,1, Shuffle_Block,[128,2]],# 1-P3/8[-1,3, Shuffle_Block,[128,1]],# 2[-1,1, Shuffle_Block,[256,2]],# 3-P4/16[-1,7, Shuffle_Block,[256,1]],# 4[-1,1, Shuffle_Block,[512,2]],# 5-P5/32[-1,3, Shuffle_Block,[512,1]],# 6]# YOLOv5 v6.0 headhead:[[-1,1, Conv,[256,1,1]],[-1,1, nn.Upsample,[None,2,'nearest']],[[-1,4],1, Concat,[1]],# cat backbone P4[-1,1, C3,[256,False]],# 10[-1,1, Conv,[128,1,1]],[-1,1, nn.Upsample,[None,2,'nearest']],[[-1,2],1, Concat,[1]],# cat backbone P3[-1,1, C3,[128,False]],# 14 (P3/8-small)[-1,1, Conv,[128,3,2]],[[-1,11],1, Concat,[1]],# cat head P4[-1,1, C3,[256,False]],# 17 (P4/16-medium)[-1,1, Conv,[256,3,2]],[[-1,7],1, Concat,[1]],# cat head P5[-1,1, C3,[512,False]],# 20 (P5/32-large)[[14,17,20],1, Detect,[nc, anchors]],# Detect(P3, P4, P5)]


更详细的网络结构复现请看ShuffleNet v2网络结构复现(Pytorch版)


本人更多YOLOv5实战内容导航🍀🌟🚀

  1. 手把手带你调参Yolo v5 (v6.2)(推理)🌟强烈推荐
  2. 手把手带你调参Yolo v5 (v6.2)(训练)🚀
  3. 手把手带你调参Yolo v5 (v6.2)(验证)
  4. 如何快速使用自己的数据集训练Yolov5模型
  5. 手把手带你Yolov5 (v6.2)添加注意力机制(一)(并附上30多种顶会Attention原理图)🌟强烈推荐
  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 减轻模型的复杂度同时提升精度🍀

有问题欢迎大家指正,如果感觉有帮助的话请点赞支持下👍📖🌟

!!转载请注明出处!!

标签: 网络 cnn 深度学习

本文转载自: https://blog.csdn.net/weixin_43694096/article/details/126109839
版权归原作者 迪菲赫尔曼 所有, 如有侵权,请联系我们删除。

“Yolov5更换主干网络之《旷视轻量化卷积神经网络ShuffleNetv2》”的评论:

还没有评论