当前位置:   article > 正文

[YOLOv7/YOLOv5系列算法改进NO.12]主干网络C3替换为轻量化网络ShuffleNetV2_yolov7 shufflenet

yolov7 shufflenet

 ​前 言:作为当前先进的深度学习目标检测算法YOLOv5,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列文章,将重点对YOLOv5的如何改进进行详细的介绍,目的是为了给那些搞科研的同学需要创新点或者搞工程项目的朋友需要达到更好的效果提供自己的微薄帮助和参考。

需要更多程序资料以及答疑欢迎大家关注——微信公众号:人工智能AI算法工程师 

解决问题:YOLOv5主干特征提取网络采用C3结构,带来较大的参数量,检测速度较慢,应用受限,在某些真实的应用场景如移动或者嵌入式设备,如此大而复杂的模型时难以被应用的。首先是模型过于庞大,面临着内存不足的问题,其次这些场景要求低延迟,或者说响应速度要快,想象一下自动驾驶汽车的行人检测系统如果速度很慢会发生什么可怕的事情。所以,研究小而高效的CNN模型在这些场景至关重要,至少目前是这样,尽管未来硬件也会越来越快。本文尝试将主干特征提取网络替换为更轻量的ShuffleNetV2网络,以实现网络模型的轻量化,平衡速度和精度。

YOLOv5改进之十一:主干网络C3替换为轻量化网络MobileNetV3_人工智能算法工程师0301的博客-CSDN博客https://blog.csdn.net/m0_70388905/article/details/125593267?spm=1001.2014.3001.5502

原理:

文章链接 https://arxiv.org/abs/1807.11164

近来,深度CNN网络如ResNet和DenseNet,已经极大地提高了图像分类的准确度。但是除了准确度外,计算复杂度也是CNN网络要考虑的重要指标,过复杂的网络可能速度很慢,一些特定场景如无人车领域需要低延迟。另外移动端设备也需要既准确又快的小模型。为了满足这些需求,一些轻量级的CNN网络如MobileNet和ShuffleNet被提出,它们在速度和准确度之间做了很好地平衡。今天我们要讲的是ShuffleNetv2,它是旷视最近提出的ShuffleNet升级版本,并被ECCV2018收录。在同等复杂度下,ShuffleNetv2比ShuffleNet和MobileNetv2更准确。下图为整体结构图。

方 法:

第一步修改common.py,增加ShuffleNetV2模块。

  1. def channel_shuffle(x: Tensor, groups: int) -> Tensor:
  2. batchsize, num_channels, height, width = x.size()
  3. channels_per_group = num_channels // groups
  4. # reshape
  5. x = x.view(batchsize, groups,
  6. channels_per_group, height, width)
  7. x = torch.transpose(x, 1, 2).contiguous()
  8. return x
  9. class conv_bn_relu_maxpool(nn.Module):
  10. def __init__(self, c1, c2): # ch_in, ch_out
  11. super(conv_bn_relu_maxpool, self).__init__()
  12. self.conv = nn.Sequential(
  13. nn.Conv2d(c1, c2, kernel_size=3, stride=2, padding=1, bias=False),
  14. nn.BatchNorm2d(c2),
  15. nn.ReLU(inplace=True),
  16. )
  17. self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
  18. def forward(self, x):
  19. return self.maxpool(self.conv(x))
  20. class ShuffleNetV2_InvertedResidual(nn.Module):
  21. def __init__(
  22. self,
  23. inp: int,
  24. oup: int,
  25. stride: int
  26. ) -> None:
  27. super(ShuffleNetV2_InvertedResidual, self).__init__()
  28. if not (1 <= stride <= 3):
  29. raise ValueError('illegal stride value')
  30. self.stride = stride
  31. branch_features = oup // 2
  32. if self.stride > 1:
  33. self.branch1 = nn.Sequential(
  34. self.depthwise_conv(inp, inp, kernel_size=3, stride=self.stride, padding=1),
  35. nn.BatchNorm2d(inp),
  36. nn.Conv2d(inp, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
  37. nn.BatchNorm2d(branch_features),
  38. nn.ReLU(inplace=True),
  39. )
  40. else:
  41. self.branch1 = nn.Sequential()
  42. self.branch2 = nn.Sequential(
  43. nn.Conv2d(inp if (self.stride > 1) else branch_features,
  44. branch_features, kernel_size=1, stride=1, padding=0, bias=False),
  45. nn.BatchNorm2d(branch_features),
  46. nn.ReLU(inplace=True),
  47. self.depthwise_conv(branch_features, branch_features, kernel_size=3, stride=self.stride, padding=1),
  48. nn.BatchNorm2d(branch_features),
  49. nn.Conv2d(branch_features, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
  50. nn.BatchNorm2d(branch_features),
  51. nn.ReLU(inplace=True),
  52. )
  53. @staticmethod
  54. def depthwise_conv(
  55. i: int,
  56. o: int,
  57. stride: int = 1,
  58. padding: int = 0,
  59. bias: bool = False
  60. ) -> nn.Conv2d:
  61. return nn.Conv2d(i, o, kernel_size, stride, padding, bias=bias, groups=i)
  62. def forward(self, x: Tensor) -> Tensor:
  63. if self.stride == 1:
  64. x1, x2 = x.chunk(2, dim=1)
  65. out = torch.cat((x1, self.branch2(x2)), dim=1)
  66. else:
  67. out = torch.cat((self.branch1(x), self.branch2(x)), dim=1)
  68. out = channel_shuffle(out, 2)
  69. return out

第二步:将yolo.py中注册模块ShuffleNetV2。

if m in [Conv,MobileNetV3_InvertedResidual,ShuffleNetV2_InvertedResidual ]:

第三步:修改yaml文件

  1. backbone:
  2. # [from, number, module, args]
  3. [[-1, 1, Focus, [64, 3]], # 0-P2/4
  4. [-1, 1, ShuffleNetV2_InvertedResidual, [128, 2]], # 1-P3/8
  5. [-1, 3, ShuffleNetV2_InvertedResidual, [128, 1]], # 2
  6. [-1, 1, ShuffleNetV2_InvertedResidual, [256, 2]], # 3-P4/16
  7. [-1, 7, ShuffleNetV2_InvertedResidual, [256, 1]], # 4
  8. [-1, 1, ShuffleNetV2_InvertedResidual, [512, 2]], # 5-P5/32
  9. [-1, 3, ShuffleNetV2_InvertedResidual, [512, 1]], # 6
  10. ]

结 果:本人在多个数据集上做了大量实验,针对不同的数据集效果不同,map值有所下降,但是权值模型大小降低,参数量下降。

预告一下:下一篇内容将继续分享网络轻量化方法EfficientNetv2的分享。有兴趣的朋友可以关注一下我,有问题可以留言或者私聊我哦

PS:主干网络的替换不仅仅是适用改进YOLOv5,也可以改进其他的YOLO网络以及目标检测网络,比如YOLOv4、v3等。

需要更多程序资料以及答疑欢迎大家关注——微信公众号:人工智能AI算法工程师 

最后,希望能互粉一下,做个朋友,一起学习交流。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/402565
推荐阅读
相关标签
  

闽ICP备14008679号