当前位置:网站首页>YOLOv5s-ShuffleNetV2
YOLOv5s-ShuffleNetV2
2022-07-04 19:56:00 【Master Ma】
Yes YOLOV5 Lightweight :
One 、backbone part
yaml The configuration file :
backbone:
# [from, number, module, args]
[[-1, 1, conv_bn_relu_maxpool, [32]], # 0-P2/4
[-1, 1, Shuffle_Block, [116, 2]], # 1-P3/8
[-1, 3, Shuffle_Block, [116, 1]], # 2
[-1, 1, Shuffle_Block, [232, 2]], # 3-P4/16
[-1, 7, Shuffle_Block, [232, 1]], # 4
[-1, 1, Shuffle_Block, [464, 2]], # 5-P5/32
[-1, 1, Shuffle_Block, [464, 1]], # 6
]
1.1、Focus Replace
The original YOLOv5s-5.0 Of stem It's a Focus Slicing operation , and v6 It's a 6x6Conv, Here is a copy v6 Yes Focus Improvement , Change it to 1 individual 3x3 Convolution ( Because my task itself is not complicated , Change it to 3x3 The parameters can be reduced after )
class conv_bn_relu_maxpool(nn.Module):
def __init__(self, c1, c2): # ch_in, ch_out
super(conv_bn_relu_maxpool, 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))
1.2、 all Conv+C3 Replace with Shuffle_Block
def channel_shuffle(x, groups):
batchsize, num_channels, height, width = x.data.size() # bs c h w
channels_per_group = num_channels // groups
# reshape
x = x.view(batchsize, groups, channels_per_group, height, width) # [bs,c,h,w] to [bs,group,channels_per_group,h,w]
x = torch.transpose(x, 1, 2).contiguous() # channel shuffle [bs,channels_per_group,group,h,w]
# flatten
x = x.view(batchsize, -1, height, width) # [bs,c,h,w]
return x
class Shuffle_Block(nn.Module):
def __init__(self, inp, oup, stride):
super(Shuffle_Block, self).__init__()
if not (1 <= stride <= 3):
raise ValueError('illegal stride value')
self.stride = stride
branch_features = oup // 2 # channel split to 2 feature map
assert (self.stride != 1) or (inp == branch_features << 1)
# stride=2 chart d The left branch =3x3DW Conv + 1x1Conv
if self.stride > 1:
self.branch1 = nn.Sequential(
self.depthwise_conv(inp, inp, kernel_size=3, stride=self.stride, padding=1),
nn.BatchNorm2d(inp),
nn.Conv2d(inp, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
nn.BatchNorm2d(branch_features),
nn.ReLU(inplace=True),
)
# Right branch =1x1Conv + 3x3DW Conv + 1x1Conv
self.branch2 = nn.Sequential(
nn.Conv2d(inp 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):
# x/out: [bs, c, h, w]
if self.stride == 1:
x1, x2 = x.chunk(2, dim=1) # channel split to 2 feature map
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
1.3、 Cut off SPP
Cut off SPP Structure and the one behind C3 structure , because SPP Parallel operation will affect the speed .
Two 、head part
head:
[[-1, 1, Conv, [96, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[ -1, 4 ], 1, Concat, [1]], # cat backbone P4
[-1, 1, DWConvblock, [96, 3, 1]], # 10
[-1, 1, Conv, [96, 1, 1 ]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 2], 1, Concat, [1]], # cat backbone P3
[-1, 1, DWConvblock, [96, 3, 1]], # 14 (P3/8-small)
[-1, 1, DWConvblock, [96, 3, 2]],
[[-1, 11], 1, ADD, [1]], # cat head P4
[-1, 1, DWConvblock, [96, 3, 1]], # 17 (P4/16-medium)
[-1, 1, DWConvblock, [ 96, 3, 2]],
[[-1, 7], 1, ADD, [1]], # cat head P5
[-1, 1, DWConvblock, [96, 3, 1]], # 20 (P5/32-large)
[[14, 17, 20], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
2.1、 All layer structure inputs and outputs channel equal
2.2、 all C3 Replace all structures with DWConv
2.3、PAN Of the two Concat Change it to ADD
3、 ... and 、、 summary
ShuffleNeckV2 Four criteria for designing lightweight networks are proposed :
G1、 Input characteristics of convolution layer channel And output characteristics channel Try to be equal ;
G2、 Try not to use group convolution , Or convolution group g As small as possible ;
G3、 Network branches should be as few as possible , Avoid parallel structures ;
G4、 Element-Wise The operation should be as few as possible , Such as :ReLU、ADD、 Point by point convolution, etc ;
YOLOv5s-ShuffleNetV2 Summary of improvement points :
backbone Of Focus Replace with a 3x3Conv(c=32), because v5-6.0 Just replace it with a 6x6Conv, Here, in order to further reduce the amount of parameters , Replace with 3x3Conv;
backbone all Conv and C3 Replace with Shuffle Block;
Cut off SPP And the one behind C3 structure ,SPP There are too many parallel operations (G3)
head Input and output of all layers channel=96(G1)
head all C3 Change it to DWConv
PAN Of the two Concat Change it to ADD(channel Too big , Too much computation , Although it violates G4, But the amount of calculation is smaller )
Four 、 experimental result
GFLOPs= value /10^9
Parameter quantity (M)= value *4/1024/1024
Parameter quantity 、 Amount of computation 、 The weight file size is compressed to YOLOv5s Of 1/10, precision [email protected] It fell off 1% about (96.7%->95.5%),[email protected]~0.95 It fell off 5 A p.m. (88.5%->84%).
reference :https://blog.csdn.net/qq_38253797/article/details/124803531
边栏推荐
- 公司要上监控,Zabbix 和 Prometheus 怎么选?这么选准没错!
- An example of multi module collaboration based on NCF
- 实战模拟│JWT 登录认证
- Cbcgpprogressdlgctrl progress bar used by BCG
- Multi table operation inner join query
- kotlin 基本数据类型
- HDU 1372 & POJ 2243 Knight Moves(广度优先搜索)
- Comment utiliser async awati asynchrone Task Handling au lieu de backgroundworker?
- Stream stream
- 1006 sign in and sign out (25 points) (PAT class a)
猜你喜欢
English语法_名词 - 使用
Introduction to polyfit software
New wizard effect used by BCG
How to use async Awati asynchronous task processing instead of backgroundworker?
Comment utiliser async awati asynchrone Task Handling au lieu de backgroundworker?
西门子HMI下载时提示缺少面板映像解决方案
如何使用Async-Awati异步任務處理代替BackgroundWorker?
Lenovo explains in detail the green smart city digital twin platform for the first time to solve the difficulties of urban dual carbon upgrading
Cbcgptabwnd control used by BCG (equivalent to MFC TabControl)
Pythagorean number law (any three numbers can meet the conditions of Pythagorean theorem)
随机推荐
多表操作-外连接查询
黑马程序员-软件测试--07阶段2-linux和数据库-09-24-linux命令学习步骤,通配符,绝对路径,相对路径,文件和目录常用命令,文件内容相关操作,查看日志文件,ping命令使用,
1005 spell it right (20 points) (pat a)
HDU 1097 A hard puzzle
[graduation season] green ant new fermented grains wine, red mud small stove. If it snows late, can you drink a cup?
Chrome development tool: what the hell is vmxxx file
Utilisation de la barre de progression cbcggprogressdlgctrl utilisée par BCG
Introduction to polyfit software
Add namespace declaration
Multi table operation inner join query
1007 Maximum Subsequence Sum(25 分)(PAT甲级)
Oracle with as ora-00903: invalid table name multi report error
1006 Sign In and Sign Out(25 分)(PAT甲级)
1008 Elevator(20 分)(PAT甲级)
牛客小白月赛7 E Applese的超能力
1007 maximum subsequence sum (25 points) (PAT class a)
TCP两次挥手,你见过吗?那四次握手呢?
Online data migration scheme encountered in the project 1 - general idea sorting and technical sorting
Comment utiliser async awati asynchrone Task Handling au lieu de backgroundworker?
Thinking on demand development