检索目录
MMDetection是一个强大的开源目标检测工具箱,由商汤科技和香港中文大学共同研发维护,它基于PyTorch深度学习框架构建,提供了丰富的目标检测、实例分割、全景分割算法以及相关的组件和模块。
本文从深度学习目标检测新手视角出发,基于MMDetection官方文档,对文档中的步骤加以详细解释,还会介绍一些好用的小工具,完成对MMDetection项目的部署工作以及初步学会使用公开数据集进行模型测试的小目标!
一、创建MMDetection所需要的环境依赖
步骤1. 创建并激活一个conda环境
conda create --name openmmlab python=3.8 -y
conda activate openmmlab # 有的版本要先用source activate XXX激活操作
步骤2. 基于PyTorch官方说明安装PyTorch
点击这里查看PyTorch往期版本
根据Linux系统的CUDA版本安装对应的PyTorch:
# CUDA 11.7
pip install torch==2.0.0 torchvision==0.15.1 torchaudio==2.0.1
查看Linux服务器上CUDA版本的方法:
watch nvidia-smi
检验GPU版本的PyTorch是否安装成功
python # 从终端进入python解释器
>>> import torch
>>> print(torch.__version__)
2.0.0
>>> print(torch.cuda.is_available())
True
>>> print(torch.version.cuda)
11.7
>>>
二、安装流程
步骤 0. 使用MIM安装MMENGINE和MMCV
pip install -U openmim
mim install mmengine
mim install "mmcv>=2.0.0" # 或者直接mim install "mmcv=2.0.0"
步骤 1. 安装 MMDetection
git clone https://github.com/open-mmlab/mmdetection.git # 从github克隆源码仓库
cd mmdetection # 一定要记住先进入mmdetection文件
pip install -v -e .
# "-v" 指详细说明,或更多的输出
# "-e" 表示在可编辑模式下安装项目,因此对代码所做的任何本地修改都会生效,从而无需重新安装。
在安装过程中可能会报错ImportError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29‘ not found,可参考该文章
下载各种模块包的过程中,如果服务器下载速度比较慢,可考虑清华镜像源https://pypi.tuna.tsinghua.edu.cn/simple
pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple # 例如下载numpy包
记得科学上网和换源不能双开,否则会出现报错!
三、验证安装
步骤 1. 我们需要下载配置文件和模型权重文件
mim download mmdet --config rtmdet_tiny_8xb32-300e_coco --dest .
下载将需要几秒钟或更长时间,这取决于你的网络环境。完成后,你会在当前文件夹中发现两个文件
rtmdet_tiny_8xb32-300e_coco.py
和rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth
。
步骤 2. 推理验证
python demo/image_demo.py demo/demo.jpg rtmdet_tiny_8xb32-300e_coco.py --weights rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth --device cpu
你会在当前文件夹中的
outputs/vis
文件夹中看到一个新的图像demo.jpg
,图像中包含有网络预测的检测框。
四、使用已有模型在标准数据集上进行推理
在mmdetection文件夹下的demo/inference_demo.ipynb中,我们就可以通过jupyternotebook进行实时编译与结果展示,可以将demo文件夹下的demo.jpg替换成自己图片感受一下单张图片预测效果
在该代码中,使用DetInferencer
,只需 3 行代码就可以获得推理结果。
from mmdet.apis import DetInferencer
# 初始化模型
inferencer = DetInferencer('rtmdet_tiny_8xb32-300e_coco')
# 推理示例图片
inferencer('demo/demo.jpg', show=True)
五、数据集准备
MMDetection 支持多个公共数据集,包括COCO,Pascal VOC,Cityscapes和其他更多数据集。
在下载数据集的过程中,官方推荐通过开源数据平台OpenDataLab来下载数据,以获得更好的下载体验。
cd mmdetection
mkdir data # 创建data文件夹
例如官方提供了下载COCO等数据集的脚本,可以运行python tools/misc/download_dataset.py --dataset-name coco2017
下载 COCO2017数据集,不过此数据集较为庞大,作为初学者的我们可以换成COCO2014数据集(约为26GB),下载后在data文件夹下进行Linux系统下文件解压缩。
cd mmdetection # 进入mmdetection文件夹
python tools/misc/download_dataset.py --dataset-name coco2014
cd data # 进入data文件夹
unzip coco2014.zip # 解压缩zip类型文件夹
在CV目标检测领域,有三种常用的数据集格式:
datasets | annotations | bbox |
---|---|---|
voc | .xml | xmin, ymin, xmax, ymax: 左上角(xmin, ymin)&右下角(xmax, ymax)的坐标 |
coco | .json | x, y, w, h: 左上角坐标(x, y)以及宽(w)&高(h) |
yolo | .txt | xcenter, ycenter, w, h: bbox的中心x坐标(xcenter)、y坐标(ycenter)以及宽度(w)和高度(h) |
转换后的数据集文件夹结构应该如下:
mmdetection
├── mmdet
├── tools
├── configs
├── data
│ ├── coco
│ │ ├── annotations
│ │ ├── train2014
│ │ ├── val2014
│ │ ├── test2014
六、测试现有模型
mmdetection提供了测试脚本,能够测试一个现有模型在所有数据集(COCO,Pascal VOC,Cityscapes 等)上的性能。它支持在如下环境下测试:
- 单 GPU 测试
- CPU 测试
- 单节点多 GPU 测试
- 多节点测试
根据以上测试环境,选择合适的脚本来执行测试过程。
注意以下只是模板,需要自己根据实际情况进行替换
# 单 GPU 测试
python tools/test.py \
${CONFIG_FILE} \
${CHECKPOINT_FILE} \
[--out ${RESULT_FILE}] \
[--show]
# CPU 测试:禁用 GPU 并运行单 GPU 测试脚本
export CUDA_VISIBLE_DEVICES=-1
python tools/test.py \
${CONFIG_FILE} \
${CHECKPOINT_FILE} \
[--out ${RESULT_FILE}] \
[--show]
# 单节点多 GPU 测试
bash tools/dist_test.sh \
${CONFIG_FILE} \
${CHECKPOINT_FILE} \
${GPU_NUM} \
[--out ${RESULT_FILE}]
可选参数:
RESULT_FILE
: 结果文件名称,需以 .pkl 形式存储。如果没有声明,则不将结果存储到文件。--show
: 如果开启,检测结果将被绘制在图像上,以一个新窗口的形式展示。它只适用于单 GPU 的测试,是用于调试和可视化的。请确保使用此功能时,你的 GUI 可以在环境中打开。否则,你可能会遇到这么一个错误cannot connect to X server
。--show-dir
: 如果指明,检测结果将会被绘制在图像上并保存到指定目录。它只适用于单 GPU 的测试,是用于调试和可视化的。即使你的环境中没有 GUI,这个选项也可使用。--cfg-options
: 如果指明,这里的键值对将会被合并到配置文件中。
七、样例
假设你已经下载了checkpoint文件到mmdetection/checkpoints/
文件下了。
测试RTMDet并可视化其结果。按任意键继续下张图片的测试。配置文件和checkpoint文件在此
python tools/test.py \
configs/rtmdet/rtmdet_l_8xb32-300e_coco.py \
checkpoints/rtmdet_l_8xb32-300e_coco_20220719_112030-5a0be7c4.pth \
--show
该样例中的配置文件已经在你的部署的文件夹mmdetection/configs/rtmdet/
下
而checkpoint权重文件需要自己手动下载,下载在windows下可以通过xftp上传到Linux服务器上
我根据自己的实际情况下载了其他的checkpoint权重文件,最终测试指令如下:
CUDA_VISIBLE_DEVICES=9\
python tools/test.py \
configs/queryinst/queryinst_r50_fpn_1x_coco.py \
checkpoints/queryinst_r50_fpn_1x_coco_20210907_084916-5a8f1998.pth\
--out results.pkl \
--show
成功运行后terminal会显示如下的数据集测试日志:
测试完成,结果被保存在指令指定的mmdetection/results.pkl
文件中:
上述截图显示的是一个深度学习模型的评估结果。具体来说,它是在评估一个目标检测(Object Detection)模型,该模型使用了平均精度(Average Precision, AP)和平均召回率(Average Recall, AR)等指标来衡量其性能:
bbox_mAP
:这是模型在所有类别上的平均精确度(mAP),即所有类别平均的平均精度。bbox_mAP_50
:这是模型在IoU阈值为0.5时的平均精确度(mAP@0.5)。
IoU(Intersection over Union)是指两个区域交集与并集的比值,用于衡量预测框和真实框的重合程度。
bbox_mAP_75
:这是模型在IoU阈值为0.75时的平均精确度(mAP@0.75)。bbox_mAP_s
:这是模型在小目标(small objects)上的平均精确度。bbox_mAP_m
:这是模型在中等大小的目标(mediumobjects)上的平均精确度。bbox_mAP_l
:这是模型在大目标(large objects)上的平均精确度。segm_mAP
:这是模型在所有类别上的实例分割(Instance Segmentation)平均精确度(mAP)。segm_mAP_50
:这是模型在IoU阈值为0.5时的实例分割平均精确度(mAP@0.5)。segm_mAP_75
:这是模型在IoU阈值为0.75时的实例分割平均精确度(mAP@0.75)。segm_mAP_s
:这是模型在小目标上的实例分割平均精确度。segm_mAP_m
:这是模型在中等大小的目标上的实例分割平均精确度。segm_mAP_l
:这是模型在大目标上的实例分割平均精确度。
此外,还有其他一些信息:
data_time
:这是数据加载和预处理的时间。
time
:这是整个评估过程所花费的时间。
这些指标可以帮助我们了解模型在不同场景下的表现,例如在不同大小的目标上、不同的IoU阈值下以及在实例分割任务中的表现。通过比较这些指标,可以确定模型是否需要进一步优化或调整。
再回过头来解释一下我的测试指令是如何对应到具体问题的:
1. CUDA_VISIBLE_DEVICES=9为指定GPU命令,意思是我们实验室服务器3090的第10块GPU,选择合适的空闲GPU,最好不要和别人共用一块!
推荐一款查看GPU的工具:nvitop: 史上最强GPU性能实时监测工具
我选择使用pip3安装
pip3 install --upgrade nvitop
然后直接在终端输入nvitop即可
nvitop
- MEM:GPU内存使用情况
- UTL:显卡计算单元使用率
开启nvitop后会占用整个terminal,此时应该开一个new terminal继续完成接下来的项目部署
2. queryinst模型也是一种目标检测算法模型,旨在解决传统方法的限制,并提高目标检测的准确性和效率,不过我当时选择的时候是为了测试COCO2014数据集中的instance实例分割,使用instances_train/val2014.json文件作为标签信息。
COCO数据集中图像都是一样的,标注信息annotations的不同,表示不同的任务。分为:
-
instances——实例分割
-
person_keypoints——关键点分割
-
captions——图片的配文,是一句话
每个类别分别包含train,val。COCO数据集详细介绍戳这
3. 然后就去文件夹mmdetection/configs/
下找能够做COCO数据集instance实例分割的配置文件,于是我找到了mmdetection/configs/queryinst/queryinst_r50_fpn_1x_coco.py
。
修改mmdetection/configs/_base_/datasets/coco_instance.py
文件中的dataloader和evaluator路径,与自己的数据文件夹结构保持一致,我已经将需要修改的部分注释到下列python代码(coco_instance.py)中:
# dataset settings
dataset_type = 'CocoDataset'
data_root = 'data/coco/' # 数据集根路径要和你的项目文件保持一致
# Example to use different file client
# Method 1: simply set the data root and let the file I/O module
# automatically infer from prefix (not support LMDB and Memcache yet)
# data_root = 's3://openmmlab/datasets/detection/coco/'
# Method 2: Use `backend_args`, `file_client_args` in versions before 3.0.0rc6
# backend_args = dict(
# backend='petrel',
# path_mapping=dict({
# './data/': 's3://openmmlab/datasets/detection/',
# 'data/': 's3://openmmlab/datasets/detection/'
# }))
backend_args = None
train_pipeline = [
dict(type='LoadImageFromFile', backend_args=backend_args),
dict(type='LoadAnnotations', with_bbox=True, with_mask=True),
dict(type='Resize', scale=(1333, 800), keep_ratio=True),
dict(type='RandomFlip', prob=0.5),
dict(type='PackDetInputs')
]
test_pipeline = [
dict(type='LoadImageFromFile', backend_args=backend_args),
dict(type='Resize', scale=(1333, 800), keep_ratio=True),
# If you don't have a gt annotation, delete the pipeline
dict(type='LoadAnnotations', with_bbox=True, with_mask=True),
dict(
type='PackDetInputs',
meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',
'scale_factor'))
]
train_dataloader = dict(
batch_size=2,
num_workers=2,
persistent_workers=True,
sampler=dict(type='DefaultSampler', shuffle=True),
batch_sampler=dict(type='AspectRatioBatchSampler'),
dataset=dict(
type=dataset_type,
data_root=data_root,
ann_file='annotations/instances_train2014.json', # 修改为你的coco数据集训练标注文件路径
data_prefix=dict(img='train2014'), # 修改为你的coco数据集训练图片路径
filter_cfg=dict(filter_empty_gt=True, min_size=32),
pipeline=train_pipeline,
backend_args=backend_args))
val_dataloader = dict(
batch_size=1,
num_workers=2,
persistent_workers=True,
drop_last=False,
sampler=dict(type='DefaultSampler', shuffle=False),
dataset=dict(
type=dataset_type,
data_root=data_root,
ann_file='annotations/instances_val2014.json', # 修改为你的coco数据集验证标注文件路径
data_prefix=dict(img='val2014/'), # 修改为你的coco数据集验证图片路径
test_mode=True,
pipeline=test_pipeline,
backend_args=backend_args))
test_dataloader = val_dataloader
val_evaluator = dict(
type='CocoMetric',
ann_file=data_root + 'annotations/instances_val2014.json', # 修改为你的coco数据集验证标注文件路径
metric=['bbox', 'segm'],
format_only=False,
backend_args=backend_args)
test_evaluator = val_evaluator
# inference on test dataset and
# format the output results for submission.
# test_dataloader = dict(
# batch_size=1,
# num_workers=2,
# persistent_workers=True,
# drop_last=False,
# sampler=dict(type='DefaultSampler', shuffle=False),
# dataset=dict(
# type=dataset_type,
# data_root=data_root,
# ann_file=data_root + 'annotations/image_info_test-dev2017.json',
# data_prefix=dict(img='test2017/'),
# test_mode=True,
# pipeline=test_pipeline))
# test_evaluator = dict(
# type='CocoMetric',
# metric=['bbox', 'segm'],
# format_only=True,
# ann_file=data_root + 'annotations/image_info_test-dev2017.json',
# outfile_prefix='./work_dirs/coco_instance/test')
倘若数据集与配置文件匹配不成功将会出现data[‘category_id‘] = self.cat_ids[label]IndexError: list index out of range等错误
后续博主会持续更新MMDetection的使用教程,欢迎大家在评论区提出修改意见!
探讨更多问题可以戳戳官方:https://github.com/open-mmlab/mmdetection/issues/