ShuffleNetV1
ShuffleNetV1是一种轻量级卷积神经网络架构,由Megvii (Face++)提出,旨在通过高效的计算和低内存占用来加速移动和嵌入式设备上的神经网络推理。ShuffleNetV1于2017年发布,其主要贡献在于提出了两种创新技术:组卷积 (group convolution) 和 通道洗牌 (channel shuffle),以显著减少计算复杂度和参数量。
ShuffleNetV1的优势
-
高效的组卷积:ShuffleNetV1采用组卷积,将输入通道分成多个组,并在每个组内独立进行卷积操作。这样做大大减少了计算量,因为组卷积减少了每个卷积核需要处理的输入通道数。
-
通道洗牌:组卷积在减少计算量的同时也引入了通道之间的信息隔离问题。ShuffleNetV1通过“通道洗牌”操作来解决这个问题,即在每次组卷积之后重新排列通道,使得不同组之间的信息能够相互混合,从而增强网络的表达能力。
-
轻量级和高性能:通过结合组卷积和通道洗牌,ShuffleNetV1在保持高精度的同时极大地减少了参数量和计算复杂度,使其非常适合在移动设备和嵌入式系统中部署。
-
高效的模型结构:ShuffleNetV1采用了瓶颈结构(bottleneck structure)和逐点卷积(pointwise convolution),进一步优化了网络的计算效率和参数利用率。
ShuffleNetV1作为YOLO主干网络的可行性分析
YOLO(You Only Look Once)是一种广泛使用的实时目标检测算法,其主干网络(backbone network)对模型的整体性能(包括精度和速度)起着关键作用。将ShuffleNetV1作为YOLO的主干网络具有以下可行性和优势:
-
轻量化和高效性:YOLO的实时性要求其主干网络必须具有高效的计算能力和低延迟。ShuffleNetV1通过组卷积和通道洗牌大幅减少计算量和参数量,非常适合作为YOLO的主干网络以提升推理速度。
-
准确性:尽管是轻量级网络,ShuffleNetV1在ImageNet等标准数据集上的表现仍然相当出色。作为YOLO的主干网络,它能够在保持检测精度的同时提供更快的处理速度。
-
模块化和易集成:ShuffleNetV1的结构设计具有高度模块化的特点,可以方便地与YOLO等目标检测框架集成。此外,其通道洗牌机制能够增强特征混合效果,提高检测网络的特征表达能力。
-
移动设备部署:随着移动和嵌入式设备上目标检测需求的增加,ShuffleNetV1由于其高效性和低资源需求,非常适合在这些设备上部署YOLO模型,实现实时目标检测。
替换ShuffleNetV1(基于MMYOLO)
如果想要使用在 MMPretrain 中实现的主干网络,需要先安装 MMPretrain
##官方提供的安装命令
##如果安装不成功的可以考虑直接把压缩包下载下来进行安装
git clone https://github.com/open-mmlab/mmpretrain.git
cd mmpretrain
mim install -e .
OpenMMLab 2.0 体系中 MMYOLO、MMDetection、MMClassification、MMSelfsup 中的模型注册表都继承自 MMEngine 中的根注册表,允许这些 OpenMMLab 开源库直接使用彼此已经实现的模块。 因此用户可以在 MMYOLO 中使用来自 MMDetection、MMClassification、MMSelfsup 的主干网络,而无需重新实现。
假设想将'ShuffleNetV1'作为 'yolov5' 的主干网络,则配置文件如下:
_base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py'
# 导入 mmcls.models 使得可以调用 mmcls 中注册的模块
custom_imports = dict(imports=['mmpretrain.models'], allow_failed_imports=False)
# checkpoint_file = 'https://download.openmmlab.com/mmclassification/v0/mobilenet_v3/convert/mobilenet_v3_small-8427ecf0.pth' # noqa
widen_factor = 1.0
channels = [240, 480, 960]
model = dict(
backbone=dict(
_delete_=True, # 将 _base_ 中关于 backbone 的字段删除
type='mmpretrain.ShuffleNetV1', # 使用 mmcls 中的 ShuffleNetV1
groups=3,
out_indices=(0,1,2) ##调整backbone输出的stage
# arch='small',
# out_indices=(3, 8, 11), # 修改 out_indices
# init_cfg=dict(
# type='Pretrained',
# # checkpoint=checkpoint_file,
# prefix='backbone.')
), # MMCls 中主干网络的预训练权重含义 prefix='backbone.',为了正常加载权重,需要把这个 prefix 去掉。
neck=dict(
type='YOLOv5PAFPN',
widen_factor=widen_factor,
in_channels=channels, # 注意:ShuffleNetV1 输出的3个通道是 [240, 480, 960],和原先的 yolov5-s neck 不匹配,需要更改
out_channels=channels),
bbox_head=dict(
type='YOLOv5Head',
head_module=dict(
type='YOLOv5HeadModule',
in_channels=channels, # head 部分输入通道也要做相应更改
widen_factor=widen_factor))
)