如有错误,恳请指出。
这篇博客记录安装mmdetection的过程,以及记录对公共数据集进行推理测试与训练的简单使用。
conda create --name openmmlab python=3.9 -y
conda activate openmmlab
pip install torch==1.11.0+cu102 torchvision==0.12.0+cu102 torchaudio==0.11.0 --extra-index-url https://download.pytorch.org/whl/cu102
在官方资料中写者,10.2版本的cuda有更好的兼容性,所以选择安装cuda10.2版本
对于基于 Ampere 的 NVIDIA GPU,例如 GeForce 30 系列和 NVIDIA A100,CUDA 11 是必须的。
对于较旧的 NVIDIA GPU,CUDA 11 向后兼容,但 CUDA 10.2 提供更好的兼容性并且更轻量级。
pip install -U openmim
pip install mmcv-full=={mmcv_version} -f https://download.openmmlab.com/mmcv/dist/cu102/torch1.11.0/index.html
# 我使用的安装命令:
pip install mmcv-full==1.5.3 -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.11.0/index.html
这里的cuda101与torch1.11.0需要与安装pytorch时匹配
git clone https://github.com/open-mmlab/mmdetection.git
cd mmdetection
pip install -v -e .
pip install mmdet==2.24.0
这里需要注意,本地下载的mmdet需要与pip install安装的mmdet版本一直,比如我本地下载的源码的2.24.0版本的,那么这里pip install就需要指定安装mmdet==2.24.0版本
mim download mmdet --config yolov3_mobilenetv2_320_300e_coco --dest .
# 输出:
(openmmlab) [fs@localhost mmdetection-2.24.0]$ mim download mmdet
--config yolov3_mobilenetv2_320_300e_coco --dest . /home/fs/anaconda3/envs/openmmlab/lib/python3.9/site-packages/_distutils_hack/__init__.py:30: UserWarning: Setuptools is replacing distutils. warnings.warn("Setuptools is replacing distutils.") processing yolov3_mobilenetv2_320_300e_coco... downloading ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 14.5/14.5 MiB 9.9 MB/s eta 0:00:00 Successfully downloaded yolov3_mobilenetv2_320_300e_coco_20210719_215349-d18dff72.pth to /home/fs/LLC/Detection/mmdetection/mmdetection-2.24.0 Successfully dumped yolov3_mobilenetv2_320_300e_coco.py to /home/fs/LLC/Detection/mmdetection/mmdetection-2.24.0
python demo/image_demo.py demo/demo.jpg yolov3_mobilenetv2_320_300e_coco.py yolov3_mobilenetv2_320_300e_coco_20210719_215349-d18dff72.pth --device cpu --out-file result.jpg
# 输出:
(openmmlab) [fs@localhost mmdetection-2.24.0]$ python demo/image_demo.py demo/demo.jpg yolov3_mobilenetv2_320_300e_coco.py yolov3_mobilenetv2_320_300e_coco_20210719_215349-d18dff72.pth --device cpu --out-file result.jpg
load checkpoint from local path: yolov3_mobilenetv2_320_300e_coco_20210719_215349-d18dff72.pth
/home/fs/anaconda3/envs/openmmlab/lib/python3.9/site-packages/mmdet/models/dense_heads/yolo_head.py:269: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at ../torch/csrc/utils/tensor_new.cpp:210.)
flatten_bboxes /= flatten_bboxes.new_tensor(
此时,就可以在目录下看见result.jpg
图像,至此mmdet
安装成功。如果推理过程中出现任何形如 undefined symbol
或者 ImportError
的错误,都是因为没有正确安装mmdet。
需要注意的就是mmcv-full需要与torch相匹配,然后pip install mmdet需要与下载的源码相匹配。
更多测试例子(具体的参数配置可以查看相应的demo代码):
python demo/image_demo.py demo/demo.jpg configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py checkpoints/faster_rcnn/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth --device cpu
python demo/video_demo.py demo/demo.mp4 configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py checkpoints/faster_rcnn/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth --device cpu --out result.mp4
python demo/webcam_demo.py configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py checkpoints/faster_rcnn/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth --device cpu
export CUDA_VISIBLE_DEVICES='-1'
python tools/test.py configs/pascal_voc/faster_rcnn_r50_fpn_1x_voc0712.py checkpoints/faster_rcnn/faster_rcnn_r50_fpn_1x_voc0712_20220320_192712-54bef0f3.pth --eval mAP
# 输出:
load checkpoint from local path: checkpoints/faster_rcnn/faster_rcnn_r50_fpn_1x_voc0712_20220320_192712-54bef0f3.pth
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] 4952/4952, 0.9 task/s, elapsed: 5806s, ETA: 0s
---------------iou_thr: 0.5---------------
+-------------+------+-------+--------+-------+
| class | gts | dets | recall | ap |
+-------------+------+-------+--------+-------+
| aeroplane | 285 | 806 | 0.944 | 0.857 |
| bicycle | 337 | 1050 | 0.938 | 0.872 |
| bird | 459 | 1054 | 0.891 | 0.797 |
| boat | 263 | 1315 | 0.875 | 0.709 |
| bottle | 469 | 1421 | 0.802 | 0.700 |
| bus | 213 | 694 | 0.939 | 0.859 |
| car | 1201 | 3284 | 0.957 | 0.878 |
| cat | 358 | 881 | 0.969 | 0.892 |
| chair | 756 | 4236 | 0.868 | 0.649 |
| cow | 244 | 883 | 0.963 | 0.852 |
| diningtable | 206 | 2077 | 0.942 | 0.743 |
| dog | 489 | 1294 | 0.982 | 0.878 |
| horse | 348 | 1034 | 0.945 | 0.860 |
| motorbike | 325 | 990 | 0.932 | 0.849 |
| person | 4528 | 11747 | 0.940 | 0.862 |
| pottedplant | 480 | 1984 | 0.788 | 0.554 |
| sheep | 242 | 716 | 0.938 | 0.822 |
| sofa | 239 | 1344 | 0.950 | 0.783 |
| train | 282 | 994 | 0.936 | 0.848 |
| tvmonitor | 308 | 975 | 0.909 | 0.808 |
+-------------+------+-------+--------+-------+
| mAP | | | | 0.804 |
+-------------+------+-------+--------+-------+
OrderedDict([('mAP', 0.8035303354263306), ('AP50', 0.804)])
但是,可以现在只验证了VOC2007的数据集部分,没有验证VOC2012的数据集部分,要想两个部分都进行验证,需要重新配置数据集的脚本文件。不过,在VOC2012原本的数据集中本身的Main目录下就没有test.txt,这里就以val.txt来替换,更改如下:
data = dict(
samples_per_gpu=2,
workers_per_gpu=2,
train=dict(
type='RepeatDataset',
times=3,
dataset=dict(
type=dataset_type,
ann_file=[
data_root + 'VOC2007/ImageSets/Main/trainval.txt',
data_root + 'VOC2012/ImageSets/Main/trainval.txt'
],
img_prefix=[data_root + 'VOC2007/', data_root + 'VOC2012/'],
pipeline=train_pipeline)),
val=dict(
type=dataset_type,
ann_file=[
data_root + 'VOC2007/ImageSets/Main/test.txt',
data_root + 'VOC2012/ImageSets/Main/test.txt',
],
img_prefix=[data_root + 'VOC2007/', data_root + 'VOC2012/'],
pipeline=test_pipeline),
test=dict(
type=dataset_type,
ann_file=[
data_root + 'VOC2007/ImageSets/Main/test.txt',
data_root + 'VOC2012/ImageSets/Main/val.txt',
],
img_prefix=[data_root + 'VOC2007/', data_root + 'VOC2012/'],
pipeline=test_pipeline))
evaluation = dict(interval=1, metric='mAP')
_base_ = [
'../_base_/models/faster_rcnn_r50_fpn.py',
'../_base_/datasets/voc0712_val.py', # 只更改了这个voc数据集的配置文件
'../_base_/default_runtime.py'
]
model = dict(roi_head=dict(bbox_head=dict(num_classes=20)))
# optimizer
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)
# learning policy
# actual epoch = 3 * 3 = 9
lr_config = dict(policy='step', step=[3])
# runtime settings
runner = dict(
type='EpochBasedRunner', max_epochs=4) # actual epoch = 4 * 3 = 12
输出:
load checkpoint from local path: checkpoints/faster_rcnn/faster_rcnn_r50_fpn_1x_voc0712_20220320_192712-54bef0f3.pth
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] 10775/10775, 38.5 task/s, elapsed: 280s, ETA: 0s
Evaluateing data/VOCdevkit/VOC2007/ImageSets/Main/test.txt with 4952 images now
---------------iou_thr: 0.5---------------
+-------------+------+-------+--------+-------+
| class | gts | dets | recall | ap |
+-------------+------+-------+--------+-------+
| aeroplane | 285 | 805 | 0.944 | 0.857 |
| bicycle | 337 | 1049 | 0.938 | 0.872 |
| bird | 459 | 1054 | 0.891 | 0.797 |
| boat | 263 | 1315 | 0.875 | 0.709 |
| bottle | 469 | 1419 | 0.804 | 0.701 |
| bus | 213 | 694 | 0.939 | 0.857 |
| car | 1201 | 3284 | 0.957 | 0.878 |
| cat | 358 | 882 | 0.969 | 0.892 |
| chair | 756 | 4232 | 0.868 | 0.648 |
| cow | 244 | 885 | 0.963 | 0.852 |
| diningtable | 206 | 2078 | 0.942 | 0.743 |
| dog | 489 | 1293 | 0.982 | 0.878 |
| horse | 348 | 1033 | 0.945 | 0.860 |
| motorbike | 325 | 991 | 0.932 | 0.849 |
| person | 4528 | 11745 | 0.940 | 0.862 |
| pottedplant | 480 | 1983 | 0.788 | 0.554 |
| sheep | 242 | 715 | 0.938 | 0.822 |
| sofa | 239 | 1343 | 0.950 | 0.783 |
| train | 282 | 997 | 0.936 | 0.848 |
| tvmonitor | 308 | 975 | 0.909 | 0.808 |
+-------------+------+-------+--------+-------+
| mAP | | | | 0.804 |
+-------------+------+-------+--------+-------+
Evaluateing data/VOCdevkit/VOC2012/ImageSets/Main/val.txt with 5823 images now
---------------iou_thr: 0.5---------------
+-------------+------+-------+--------+-------+
| class | gts | dets | recall | ap |
+-------------+------+-------+--------+-------+
| aeroplane | 433 | 1150 | 0.970 | 0.950 |
| bicycle | 358 | 1087 | 0.958 | 0.929 |
| bird | 559 | 1099 | 0.987 | 0.975 |
| boat | 424 | 1750 | 0.972 | 0.905 |
| bottle | 630 | 1759 | 0.957 | 0.913 |
| bus | 301 | 901 | 0.990 | 0.968 |
| car | 1004 | 2780 | 0.976 | 0.953 |
| cat | 612 | 1246 | 0.993 | 0.985 |
| chair | 1176 | 5215 | 0.946 | 0.861 |
| cow | 298 | 999 | 0.987 | 0.957 |
| diningtable | 305 | 2261 | 0.885 | 0.734 |
| dog | 759 | 1649 | 0.997 | 0.989 |
| horse | 360 | 963 | 0.981 | 0.965 |
| motorbike | 356 | 1094 | 0.986 | 0.959 |
| person | 4372 | 11152 | 0.978 | 0.955 |
| pottedplant | 489 | 1977 | 0.957 | 0.869 |
| sheep | 413 | 1010 | 0.964 | 0.950 |
| sofa | 285 | 1353 | 0.951 | 0.812 |
| train | 315 | 997 | 0.987 | 0.967 |
| tvmonitor | 392 | 1123 | 0.954 | 0.926 |
+-------------+------+-------+--------+-------+
| mAP | | | | 0.926 |
+-------------+------+-------+--------+-------+
{'0_mAP': 0.8035119771957397, '0_AP50': 0.804, '1_mAP': 0.9260713458061218, '1_AP50': 0.926}
# runtime settings = 训练重复次数times x 最大批次次数max_epochs
runner = dict(
type='EpochBasedRunner', max_epochs=10) # actual epoch = 4 * 3 = 12
log_config = dict(
interval=500, # 每50个迭代就打印一次训练信息
hooks=[
dict(type='TextLoggerHook'),
# dict(type='TensorboardLoggerHook')
])
data = dict(
samples_per_gpu=16, # 每个gpu分配16张图像
workers_per_gpu=2, # 分配两个gpu
train=dict(
type='RepeatDataset',
times=3, # 重复训练3次
...
)
)
设置完成后,直接就可以进行python tools/train.py ,进行训练。可以自行进行相关的配置,比如--gpu-id
等等。
参考资料:
官方的文档手册:https://mmdetection.readthedocs.io/en/latest/