第七讲 MMDetection代码课

介绍

以 MMDetection 团队自研的 RTMDet 算法为例,结合一个简单的 cat 数据集来描述整个训练推理可视化过程。一共包括如下流程:

  1. 数据集准备和可视化
  2. 自定义配置文件
  3. 训练前可视化验证
  4. 模型训练
  5. 模型测试和推理
  6. 可视化分析

环境检测脚本

from mmengine.utils import get_git_hash
from mmengine.utils.dl_utils import collect_env as collect_base_env

import mmdet


def collect_env():
    """Collect the information of the running environments."""
    env_info = collect_base_env()
    env_info['MMDetection'] = f'{mmdet.__version__}+{get_git_hash()[:7]}'
    return env_info


if __name__ == '__main__':
    for name, val in collect_env().items():
        print(f'{name}: {val}')

RTMDet

在这里插入图片描述
RTMDet 是一个高性能低延时的检测算法,目前已经实现了目标检测、实例分割和旋转框检测任务。其简要描述为:为了获得更高效的模型架构,MMDetection 探索了一种具有骨干和 Neck 兼容容量的架构,由一个基本的构建块构成,其中包含大核深度卷积。MMDetection 进一步在动态标签分配中计算匹配成本时引入软标签,以提高准确性。结合更好的训练技巧,得到的目标检测器名为 RTMDet,在 NVIDIA 3090 GPU 上以超过 300 FPS 的速度实现了 52.8% 的 COCO AP,优于当前主流的工业检测器。RTMDet 在小/中/大/特大型模型尺寸中实现了最佳的参数-准确度权衡,适用于各种应用场景,并在实时实例分割和旋转对象检测方面取得了新的最先进性能。

配置文件

config_cat = """
_base_ = 'configs/rtmdet/rtmdet_tiny_8xb32-300e_coco.py'

data_root = 'cat_dataset/'

# 非常重要
metainfo = {
    # 类别名,注意 classes 需要是一个 tuple,因此即使是单类,
    # 你应该写成 `cat,` 很多初学者经常会在这犯错
    'classes': ('cat',),
    'palette': [
        (220, 20, 60),
    ]
}
num_classes = 1

# 训练 40 epoch
max_epochs = 40
# 训练单卡 bs= 12
train_batch_size_per_gpu = 12
# 可以根据自己的电脑修改
train_num_workers = 4

# 验证集 batch size 为 1
val_batch_size_per_gpu = 1
val_num_workers = 2

# RTMDet 训练过程分成 2 个 stage,第二个 stage 会切换数据增强 pipeline
num_epochs_stage2 = 5

# batch 改变了,学习率也要跟着改变, 0.004 是 8卡x32 的学习率
base_lr = 12 * 0.004 / (32*8)

# 采用 COCO 预训练权重
load_from = 'https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_tiny_8xb32-300e_coco/rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth'  # noqa

model = dict(
    # 考虑到数据集太小,且训练时间很短,我们把 backbone 完全固定
    # 用户自己的数据集可能需要解冻 backbone
    backbone=dict(frozen_stages=4),
    # 不要忘记修改 num_classes
    bbox_head=dict(dict(num_classes=num_classes)))

# 数据集不同,dataset 输入参数也不一样
train_dataloader = dict(
    batch_size=train_batch_size_per_gpu,
    num_workers=train_num_workers,
    pin_memory=False,
    dataset=dict(
        data_root=data_root,
        metainfo=metainfo,
        ann_file='annotations/trainval.json',
        data_prefix=dict(img='images/')))

val_dataloader = dict(
    batch_size=val_batch_size_per_gpu,
    num_workers=val_num_workers,
    dataset=dict(
        metainfo=metainfo,
        data_root=data_root,
        ann_file='annotations/test.json',
        data_prefix=dict(img='images/')))

test_dataloader = val_dataloader

# 默认的学习率调度器是 warmup 1000,但是 cat 数据集太小了,需要修改 为 30 iter
param_scheduler = [
    dict(
        type='LinearLR',
        start_factor=1.0e-5,
        by_epoch=False,
        begin=0,
        end=30),
    dict(
        type='CosineAnnealingLR',
        eta_min=base_lr * 0.05,
        begin=max_epochs // 2,  # max_epoch 也改变了
        end=max_epochs,
        T_max=max_epochs // 2,
        by_epoch=True,
        convert_to_iter_based=True),
]
optim_wrapper = dict(optimizer=dict(lr=base_lr))

# 第二 stage 切换 pipeline 的 epoch 时刻也改变了
_base_.custom_hooks[1].switch_epoch = max_epochs - num_epochs_stage2

val_evaluator = dict(ann_file=data_root + 'annotations/test.json')
test_evaluator = val_evaluator

# 一些打印设置修改
default_hooks = dict(
    checkpoint=dict(interval=10, max_keep_ckpts=2, save_best='auto'),  # 同时保存最好性能权重
    logger=dict(type='LoggerHook', interval=5))
train_cfg = dict(max_epochs=max_epochs, val_interval=10)
"""

with open('rtmdet_tiny_1xb12-40e_cat.py', 'w') as f:
    f.write(config_cat)

需要注意几个问题:

  1. 自定义数据集中最重要的是 metainfo 字段,用户在配置完成后要记得将其传给 dataset,否则不生效(有些用户在自定义数据集时候喜欢去 直接修改 coco.py 源码,这个是强烈不推荐的做法,正确做法是配置 metainfo 并传给 dataset)

  2. 如果用户 metainfo 配置不正确,通常会出现几种情况:(1) 出现 num_classes 不匹配错误 (2) loss_bbox 始终为 0 (3) 出现训练后评估结果为空等典型情况

  3. MMDetection 提供的学习率大部分都是基于 8 卡,如果你的总 bs 不同,一定要记得缩放学习率,否则有些算法很容易出现 NAN,具体参考https://mmdetection.readthedocs.io/zh_CN/latest/user_guides/train.html#id3

训练前可视化验证

可以采用 mmdet 提供的 tools/analysis_tools/browse_dataset.py 脚本来对训练前的 dataloader 输出进行可视化,确保数据部分没有问题。考虑到我们仅仅想可视化前几张图片,因此下面基于 browse_dataset.py 实现一个简单版本即可

from mmdet.registry import DATASETS, VISUALIZERS
from mmengine.config import Config
from mmengine.registry import init_default_scope

cfg = Config.fromfile('rtmdet_tiny_1xb12-40e_cat.py')

init_default_scope(cfg.get('default_scope', 'mmdet'))

dataset = DATASETS.build(cfg.train_dataloader.dataset)
visualizer = VISUALIZERS.build(cfg.visualizer)
visualizer.dataset_meta = dataset.metainfo

plt.figure(figsize=(16, 5))

# 只可视化前 8 张图片
for i in range(8):
   item=dataset[i]

   img = item['inputs'].permute(1, 2, 0).numpy()
   data_sample = item['data_samples'].numpy()
   gt_instances = data_sample.gt_instances
   img_path = osp.basename(item['data_samples'].img_path)

   gt_bboxes = gt_instances.get('bboxes', None)
   gt_instances.bboxes = gt_bboxes.tensor
   data_sample.gt_instances = gt_instances

   visualizer.add_datasample(
            osp.basename(img_path),
            img,
            data_sample,
            draw_pred=False,
            show=False)
   drawed_image=visualizer.get_image()

   plt.subplot(2, 4, i+1)
   plt.imshow(drawed_image[..., [2, 1, 0]])
   plt.title(f"{osp.basename(img_path)}")
   plt.xticks([])
   plt.yticks([])

plt.tight_layout()

可视化分析

可视化分析包括特征图可视化以及类似 Grad CAM 等可视化分析手段。不过由于 MMDetection 中还没有实现,我们可以直接采用 MMYOLO 中提供的功能和脚本。MMYOLO 是基于 MMDetection 开发,并且此案有了统一的代码组织形式,因此 MMDetection 配置可以直接在 MMYOLO 中使用,无需更改配置。

检测新趋势

随着 ChatGPT 等的 LLM 飞速发展,传统的目标检测也逐渐发展为传统的封闭类别集合检测和自然语言相结合的开放类别检测(当然还有其他非常多结合检测的新方向)。典型的方向如:

  1. Open-Vocabulary Object Detection,即开放词汇目标检测,给定图片和类别词汇表,检测所有物体
  2. Grounding Object Detection,即给定图片和文本描述,预测文本中所提到的在图片中的物体位置
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
mmdetection代码修改可以通过以下步骤完成: 1. 首先,你可以根据自己的需求,修改mmdetection中的共性结构文件two_stage.py。这个文件抽象了模型的共性结构,并提供了一些基本的属性和方法。 2. 接下来,你可以通过修改cfg文件中的字段来增加模型的具体属性。比如,如果你想要修改faster-rcnn模型,可以在cfg文件中相应的字段中增加属性。 3. 为了增加属性,你需要创建一个新的类,并继承共性结构two_stage.py。在这个类中,你可以定义新的属性和方法,以满足你的需求。 4. 为了让新的属性得以调用,你还需要修改当前文件夹下的__init__.py文件。在__init__.py文件中,你可以将新的类添加到__all__列表中。 通过以上步骤,你可以很方便地对mmdetection进行代码修改。如果你需要修改共性结构,直接修改two_stage.py文件即可。如果你需要增加属性,只需创建一个新的类并继承共性结构,然后在__init__.py文件中添加该类即可。这样的设计使得代码结构清晰,方便书写。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [对mmdetection代码设计的简单理解及代码修改](https://blog.csdn.net/chenxi1900/article/details/122590855)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值