当前位置:网站首页>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
边栏推荐
- Lm10 cosine wave homeopathic grid strategy
- Educational Codeforces Round 22 E. Army Creation
- Niuke Xiaobai month race 7 e applese's super ability
- TCP waves twice, have you seen it? What about four handshakes?
- 多表操作-内连接查询
- 1005 spell it right (20 points) (pat a)
- 线上数据库迁移的几种方法
- Dark horse programmer - software testing - stage 08 2-linux and database-23-30-process port related, modify file permissions, obtain port number information, program and process related operations, Li
- HDU 1097 A hard puzzle
- Detailed explanation of the binary processing function threshold() of opencv
猜你喜欢
Explore the contour drawing function drawcontours() of OpenCV in detail with practical examples
Dark horse programmer - software testing - 09 stage 2-linux and database -31-43 instructions issued by modifying the file permission letter, - find the link to modify the file, find the file command,
JVM系列之对象的创建
Lenovo explains in detail the green smart city digital twin platform for the first time to solve the difficulties of urban dual carbon upgrading
Creation of JVM family objects
华为nova 10系列支持应用安全检测功能 筑牢手机安全防火墙
记一次 .NET 某工控数据采集平台 线程数 爆高分析
多表操作-外连接查询
Actual combat simulation │ JWT login authentication
CANN算子:利用迭代器高效实现Tensor数据切割分块处理
随机推荐
1002. A+b for Polynomials (25) (PAT class a)
Data set division
Niuke Xiaobai month race 7 e applese's super ability
New wizard effect used by BCG
kotlin 继承
HDU 1372 & POJ 2243 Knight moves (breadth first search)
BCG 使用之CBCGPProgressDlgCtrl进度条使用
Kotlin inheritance
1006 Sign In and Sign Out(25 分)(PAT甲级)
Detailed explanation of the binary processing function threshold() of opencv
Explicit random number
Educational Codeforces Round 22 E. Army Creation
HDU 1097 A hard puzzle
HMM隐马尔可夫模型最详细讲解与代码实现
Dark horse programmer - software testing - stage 07 2-linux and database -09-24-linux command learning steps, wildcards, absolute paths, relative paths, common commands for files and directories, file
Multi table operation - external connection query
Creation of JVM family objects
更强的 JsonPath 兼容性及性能测试之2022版(Snack3,Fastjson2,jayway.jsonpath)
【问题】druid报异常sql injection violation, part alway true condition not allow 解决方案
mysql中explain语句查询sql是否走索引,extra中的几种类型整理汇总