当前位置:网站首页>Yolov5 replaces the backbone network of "Megvii Lightweight Convolutional Neural Network ShuffleNetv2"
Yolov5 replaces the backbone network of "Megvii Lightweight Convolutional Neural Network ShuffleNetv2"
2022-08-04 08:02:00 【Di Mr Herman】
《ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design》
这篇是2018年发表在ECCV上的论文,At the same time, this paper has also obtainedVALSEOutstanding Paper Award of the Year
原文地址
官方代码
ShuffleNet V2It is a relatively classic lightweight network,通过大量实验提出四条轻量化网络设计准则,对输入输出通道、分组卷积组数、网络碎片化程度、逐元素操作对不同硬件上的速度和内存访问量MAC的影响进行了详细分析.
提出ShuffleNet V2模型,通过Channel Split替代分组卷积,满足四条设计准则,达到了速度和精度的最优权衡.
YOLOv5更换方法,三步搞定
第一步;添加如下代码到common.py
# 通道重排,跨group信息交流
def channel_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
class CBRM(nn.Module): #conv BN ReLU Maxpool2d
def __init__(self, c1, c2): # ch_in, ch_out
super(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)
def forward(self, x):
return self.maxpool(self.conv(x))
class Shuffle_Block(nn.Module):
def __init__(self, ch_in, ch_out, stride):
super(Shuffle_Block, self).__init__()
if not (1 <= stride <= 2):
raise ValueError('illegal stride value')
self.stride = stride
branch_features = ch_out // 2
assert (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),
)
@staticmethod
def depthwise_conv(i, o, kernel_size, stride=1, padding=0, bias=False):
return nn.Conv2d(i, o, kernel_size, stride, padding, bias=bias, groups=i)
def forward(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
# Parameters
nc: 20 # 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
# YOLOv5 v6.0 backbone
backbone:
# [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 head
head:
[[-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)
]
For more detailed network structure reproduction, please seeShuffleNet v2网络结构复现(Pytorch版)
本人更多Yolov5(v6.1)实战内容导航
1.手把手带你调参Yolo v5 (v6.1)(一)强烈推荐
4.手把手带你Yolov5 (v6.1)添加注意力机制(一)(并附上30多种顶会Attention原理图)
5.手把手带你Yolov5 (v6.1)添加注意力机制(二)(在C3模块中加入注意力机制)
8.Yolov5更换上采样方式( 最近邻 / 双线性 / 双立方 / 三线性 / 转置卷积)
9.Yolov5如何更换EIOU / alpha IOU / SIoU?
10.持续更新中
有问题欢迎大家指正,如果感觉有帮助的话请点赞支持下
!!转载请注明出处!!
边栏推荐
猜你喜欢
随机推荐
C语言指针
Linux之Redis 缓存雪崩,击穿,穿透
将回调函数转为Flow
JMeter 常用的几种断言方法,你会几种呢?
高等代数_证明_两个矩阵乘积为0,则两个矩阵的秩之和小于等于n
从零开始C语言精讲篇6:结构体
Typora_Markdown_图片标题(题注)
【剑指Offer】二分法例题
高等代数_证明_幂等矩阵一定能够相似对角化
Distributed Computing Experiment 3 PRC-based Book Information Management System
卷积神经网络CNN
金仓数据库KingbaseES客户端编程接口指南-JDBC(10. JDBC 读写分离最佳实践)
『递归』递归概念与典型实例
The national vocational skills contest competition of network security emergency response
中职网络安全竞赛C模块MS17-010批量扫描
华为设备配置VRRP与NQA联动监视上行链路
一天学会JDBC03:Statement的用法
dalle:zero-shot text-to-image generation
【JS 逆向百例】某网站加速乐 Cookie 混淆逆向详解
研究性学习专题 3_LL(1)语法分析设计原理与实现