11 KiB
How to xxx
本教程收集了任何如何使用 MMYOLO 进行 xxx 的答案。 如果您遇到有关如何做
的问题及答案,请随时更新此文档!
给主干网络增加插件
MMYOLO 支持在 Backbone 的不同 Stage 后增加如 none_local
、dropblock
等插件,用户可以直接通过修改 config 文件中 backbone
的 plugins
参数来实现对插件的管理。例如为 YOLOv5
增加 GeneralizedAttention
插件,其配置文件如下:
_base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py'
model = dict(
backbone=dict(
plugins=[
dict(
cfg=dict(
type='mmdet.GeneralizedAttention',
spatial_range=-1,
num_heads=8,
attention_type='0011',
kv_stride=2),
stages=(False, False, True, True)),
], ))
cfg
参数表示插件的具体配置, stages
参数表示是否在 backbone 对应的 stage 后面增加插件,长度需要和 backbone 的 stage 数量相同。
应用多个 Neck
如果你想堆叠多个 Neck,可以直接在配置文件中的 Neck 参数,MMYOLO 支持以 List
形式拼接多个 Neck 配置,你需要保证上一个 Neck 的输出通道与下一个 Neck 的输入通道相匹配。如需要调整通道,可以插入 mmdet.ChannelMapper
模块用来对齐多个 Neck 之间的通道数量。具体配置如下:
_base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py'
deepen_factor = _base_.deepen_factor
widen_factor = _base_.widen_factor
model = dict(
type='YOLODetector',
neck=[
dict(
type='YOLOv5PAFPN',
deepen_factor=deepen_factor,
widen_factor=widen_factor,
in_channels=[256, 512, 1024],
out_channels=[256, 512, 1024], # 因为 out_channels 由 widen_factor 控制,YOLOv5PAFPN 的 out_channels = out_channels * widen_factor
num_csp_blocks=3,
norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),
act_cfg=dict(type='SiLU', inplace=True)),
dict(
type='mmdet.ChannelMapper',
in_channels=[128, 256, 512],
out_channels=128,
),
dict(
type='mmdet.DyHead',
in_channels=128,
out_channels=256,
num_blocks=2,
# disable zero_init_offset to follow official implementation
zero_init_offset=False)
]
bbox_head=dict(head_module=dict(in_channels=[512,512,512])) # 因为 out_channels 由 widen_factor 控制,YOLOv5HeadModuled 的 in_channels * widen_factor 才会等于最后一个 neck 的 out_channels
)
跨库使用主干网络
OpenMMLab 2.0 体系中 MMYOLO、MMDetection、MMClassification、MMSegmentation 中的模型注册表都继承自 MMEngine 中的根注册表,允许这些 OpenMMLab 开源库直接使用彼此已经实现的模块。 因此用户可以在 MMYOLO 中使用来自 MMDetection、MMClassification 的主干网络,而无需重新实现。
1. 使用其他主干网络时,你需要保证主干网络的输出通道与 Neck 的输入通道相匹配。
2. 下面给出的配置文件,仅能确保训练可以正确运行,直接训练性能可能不是最优的。因为某些 backbone 需要配套特定的学习率、优化器等超参数。后续会在“训练技巧章节”补充训练调优相关内容。
使用在 MMDetection 中实现的主干网络
-
假设想将
ResNet-50
作为YOLOv5
的主干网络,则配置文件如下:_base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py' deepen_factor = _base_.deepen_factor widen_factor = 1.0 channels = [512, 1024, 2048] model = dict( backbone=dict( _delete_=True, # 将 _base_ 中关于 backbone 的字段删除 type='mmdet.ResNet', # 使用 mmdet 中的 ResNet depth=50, num_stages=4, out_indices=(1, 2, 3), frozen_stages=1, norm_cfg=dict(type='BN', requires_grad=True), norm_eval=True, style='pytorch', init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')), neck=dict( type='YOLOv5PAFPN', widen_factor=widen_factor, in_channels=channels, # 注意:ResNet-50 输出的3个通道是 [512, 1024, 2048],和原先的 yolov5-s neck 不匹配,需要更改 out_channels=channels), bbox_head=dict( type='YOLOv5Head', head_module=dict( type='YOLOv5HeadModule', in_channels=channels, # head 部分输入通道也要做相应更改 widen_factor=widen_factor)) )
-
假设想将
SwinTransformer-Tiny
作为YOLOv5
的主干网络,则配置文件如下:_base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py' deepen_factor = _base_.deepen_factor widen_factor = 1.0 channels = [192, 384, 768] checkpoint_file = 'https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_tiny_patch4_window7_224.pth' # noqa model = dict( backbone=dict( _delete_=True, # 将 _base_ 中关于 backbone 的字段删除 type='mmdet.SwinTransformer', # 使用 mmdet 中的 SwinTransformer embed_dims=96, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24], window_size=7, mlp_ratio=4, qkv_bias=True, qk_scale=None, drop_rate=0., attn_drop_rate=0., drop_path_rate=0.2, patch_norm=True, out_indices=(1, 2, 3), with_cp=False, convert_weights=True, init_cfg=dict(type='Pretrained', checkpoint=checkpoint_file)), neck=dict( type='YOLOv5PAFPN', deepen_factor=deepen_factor, widen_factor=widen_factor, in_channels=channels, # 注意:SwinTransformer-Tiny 输出的3个通道是 [192, 384, 768],和原先的 yolov5-s neck 不匹配,需要更改 out_channels=channels), bbox_head=dict( type='YOLOv5Head', head_module=dict( type='YOLOv5HeadModule', in_channels=channels, # head 部分输入通道也要做相应更改 widen_factor=widen_factor)) )
使用在 MMClassification 中实现的主干网络
-
假设想将
ConvNeXt-Tiny
作为YOLOv5
的主干网络,则配置文件如下:_base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py' # 请先使用命令: mim install "mmcls>=1.0.0rc2",安装 mmcls # 导入 mmcls.models 使得可以调用 mmcls 中注册的模块 custom_imports = dict(imports=['mmcls.models'], allow_failed_imports=False) checkpoint_file = 'https://download.openmmlab.com/mmclassification/v0/convnext/downstream/convnext-tiny_3rdparty_32xb128-noema_in1k_20220301-795e9634.pth' # noqa deepen_factor = _base_.deepen_factor widen_factor = 1.0 channels = [192, 384, 768] model = dict( backbone=dict( _delete_=True, # 将 _base_ 中关于 backbone 的字段删除 type='mmcls.ConvNeXt', # 使用 mmcls 中的 ConvNeXt arch='tiny', out_indices=(1, 2, 3), drop_path_rate=0.4, layer_scale_init_value=1.0, gap_before_final_norm=False, init_cfg=dict( type='Pretrained', checkpoint=checkpoint_file, prefix='backbone.')), # MMCls 中主干网络的预训练权重含义 prefix='backbone.',为了正常加载权重,需要把这个 prefix 去掉。 neck=dict( type='YOLOv5PAFPN', deepen_factor=deepen_factor, widen_factor=widen_factor, in_channels=channels, # 注意:ConvNeXt-Tiny 输出的3个通道是 [192, 384, 768],和原先的 yolov5-s neck 不匹配,需要更改 out_channels=channels), bbox_head=dict( type='YOLOv5Head', head_module=dict( type='YOLOv5HeadModule', in_channels=channels, # head 部分输入通道也要做相应更改 widen_factor=widen_factor)) )
-
假设想将
MobileNetV3-small
作为YOLOv5
的主干网络,则配置文件如下:_base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py' # 请先使用命令: mim install "mmcls>=1.0.0rc2",安装 mmcls # 导入 mmcls.models 使得可以调用 mmcls 中注册的模块 custom_imports = dict(imports=['mmcls.models'], allow_failed_imports=False) checkpoint_file = 'https://download.openmmlab.com/mmclassification/v0/mobilenet_v3/convert/mobilenet_v3_small-8427ecf0.pth' # noqa deepen_factor = _base_.deepen_factor widen_factor = 1.0 channels = [24, 48, 96] model = dict( backbone=dict( _delete_=True, # 将 _base_ 中关于 backbone 的字段删除 type='mmcls.MobileNetV3', # 使用 mmcls 中的 MobileNetV3 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', deepen_factor=deepen_factor, widen_factor=widen_factor, in_channels=channels, # 注意:MobileNetV3-small 输出的3个通道是 [24, 48, 96],和原先的 yolov5-s neck 不匹配,需要更改 out_channels=channels), bbox_head=dict( type='YOLOv5Head', head_module=dict( type='YOLOv5HeadModule', in_channels=channels, # head 部分输入通道也要做相应更改 widen_factor=widen_factor)) )
通过 MMClassification 使用 timm
中实现的主干网络
由于 MMClassification 提供了 PyTorch Image Models (timm
) 主干网络的封装,用户也可以通过 MMClassification 直接使用 timm
中的主干网络。假设想将 EfficientNet-B1
作为 YOLOv5
的主干网络,则配置文件如下:
_base_ = './yolov5_s-v61_syncbn_8xb16-300e_coco.py'
# 请先使用命令: mim install "mmcls>=1.0.0rc2",安装 mmcls
# 以及: pip install timm,安装 timm
# 导入 mmcls.models 使得可以调用 mmcls 中注册的模块
custom_imports = dict(imports=['mmcls.models'], allow_failed_imports=False)
deepen_factor = _base_.deepen_factor
widen_factor = 1.0
channels = [40, 112, 320]
model = dict(
backbone=dict(
_delete_=True, # 将 _base_ 中关于 backbone 的字段删除
type='mmcls.TIMMBackbone', # 使用 mmcls 中的 timm 主干网络
model_name='efficientnet_b1', # 使用 TIMM 中的 efficientnet_b1
features_only=True,
pretrained=True,
out_indices=(2, 3, 4)),
neck=dict(
type='YOLOv5PAFPN',
deepen_factor=deepen_factor,
widen_factor=widen_factor,
in_channels=channels, # 注意:EfficientNet-B1 输出的3个通道是 [40, 112, 320],和原先的 yolov5-s neck 不匹配,需要更改
out_channels=channels),
bbox_head=dict(
type='YOLOv5Head',
head_module=dict(
type='YOLOv5HeadModule',
in_channels=channels, # head 部分输入通道也要做相应更改
widen_factor=widen_factor))
)