当前位置:网站首页>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
边栏推荐
- Educational Codeforces Round 22 E. Army Creation
- BCG 使用之CBCGPProgressDlgCtrl进度条使用
- 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
- BCG 使用之CBCGPProgressDlg进度条使用
- Cbcgptabwnd control used by BCG (equivalent to MFC TabControl)
- QT realizes interface sliding switching effect
- BCG 使用之新建向导效果
- Actual combat simulation │ JWT login authentication
- Introduction to ACM combination counting
- Kotlin basic data type
猜你喜欢
"Only one trip", active recommendation and exploration of community installation and maintenance tasks
Swagger suddenly went crazy
C# 使用StopWatch测量程序运行时间
Comment utiliser async awati asynchrone Task Handling au lieu de backgroundworker?
上线首月,这家露营地游客好评率高达99.9%!他是怎么做到的?
Stream stream
BCG 使用之CBCGPProgressDlg进度条使用
Cbcgptabwnd control used by BCG (equivalent to MFC TabControl)
实战模拟│JWT 登录认证
Euler function
随机推荐
Reflection (I)
如何使用Async-Awati异步任務處理代替BackgroundWorker?
Jetpack Compose 教程
BCG 使用之CBCGPTabWnd控件(相当于MFC TabControl)
There are multiple divs in the large div, which are displayed on the same line. After overflow, scroll bars are generated without line breaks
Allure of pytest visual test report
Add namespace declaration
Actual combat simulation │ JWT login authentication
Lenovo explains in detail the green smart city digital twin platform for the first time to solve the difficulties of urban dual carbon upgrading
需求开发思考
abc229 总结(区间最长连续字符 图的联通分量计数)
C # use stopwatch to measure the running time of the program
Lm10 cosine wave homeopathic grid strategy
ACM组合计数入门
Introduction to ACM combination counting
kotlin 类和对象
勾股数规律(任意三个数能够满足勾股定理需要满足的条件)
[problem] Druid reports exception SQL injection violation, part always true condition not allow solution
Kotlin condition control
FTP, SFTP file transfer