MMDetection教程(二)训练数据集并分析
MMDetection(二)训练数据集并分析
训练
查找模型配置文件
以Faster RCNN
为例,讲解如何找到模型的配置文件和权重文件
首先找到模型的配置文件
mmdetection/configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py
,这里以ResNet50
作为backbone, 使用FPN
为多层特征提取的网络配置文件.打开配置文件得到以下信息:
_base_ = [ '../_base_/models/faster_rcnn_r50_fpn.py', '../_base_/datasets/coco_detection.py', '../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py' ]
这里可以看到四个文件:
../_base_/models/faster_rcnn_r50_fpn.py
为模型的源码,配置文件.../_base_/datasets/coco_detection.py
为训练模型使用的数据集的一些配置,比如数据集的预处理,缩放,数据集路径等信息.../_base_/schedules/schedule_1x.py
为模型训练方式,其中包含优化器,学习率修改测率和训练的轮回数.../_base_/default_runtime.py
为默认的训练运行时,其中包含保存断点权重的间隔数等.一般不需要修改.
得到这些
configs
后,可以对这些文件进行修改了,也可以创建新的文件
准备数据
修改配置文件
定义数据种类,需要修改的地方在
mmdetection/mmdet/datasets/coco.py
。把CLASSES的那个tuple改为自己数据集对应的种类tuple即可。例如:CLASSES = ('0B', '1B', '2B')
接着在
mmdetection/mmdet/core/evaluation/class_names.py
修改coco_classes数据集类别,这个关系到后面test的时候结果图中显示的类别名称。例如:def coco_classes(): return ['0B', '1B', '2B']
修改
configs/_base_/datasets/coco_detection.py
中train_pipeline
和test_pipeline
中的img_scale
:dataset_type = 'CocoDataset' data_root = 'data/coco/' img_norm_cfg = dict( mean=[0.471,0.448,0.408], std=[0.234,0.239,0.242], to_rgb=True) train_pipeline = [ dict(type='LoadImageFromFile'), dict(type='LoadAnnotations', with_bbox=True), dict(type='Resize', img_scale=(400, 300), keep_ratio=True), dict(type='RandomFlip', flip_ratio=0.5), dict(type='Normalize', **img_norm_cfg), dict(type='Pad', size_divisor=32), dict(type='DefaultFormatBundle'), dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']), ] test_pipeline = [ dict(type='LoadImageFromFile'), dict( type='MultiScaleFlipAug', # 图像大小尺寸缩放 img_scale=(400, 300), flip=False, transforms=[ dict(type='Resize', keep_ratio=True), dict(type='RandomFlip'), dict(type='Normalize', **img_norm_cfg), dict(type='Pad', size_divisor=32), dict(type='ImageToTensor', keys=['img']), dict(type='Collect', keys=['img']), ]) ] data = dict( samples_per_gpu=2, workers_per_gpu=2, train=dict( type=dataset_type, # 标记文件路径 和 数据集路径 ann_file=data_root + 'annotations/instances_train2017.json', img_prefix=data_root + 'train2017/', pipeline=train_pipeline), val=dict( type=dataset_type, ann_file=data_root + 'annotations/instances_val2017.json', img_prefix=data_root + 'val2017/', pipeline=test_pipeline), test=dict( type=dataset_type, ann_file=data_root + 'annotations/instances_test2017.json', img_prefix=data_root + 'test2017/', pipeline=test_pipeline)) evaluation = dict(interval=1, metric='bbox')
修改
models/faster_rcnn_r50_fpn.py
中的num_classes
:model = dict( type='FasterRCNN', pretrained='torchvision://resnet50', backbone=dict( type='ResNet', depth=50, num_stages=4, out_indices=(0, 1, 2, 3), frozen_stages=1, norm_cfg=dict(type='BN', requires_grad=True), norm_eval=True, style='pytorch'), neck=dict( type='FPN', in_channels=[256, 512, 1024, 2048], out_channels=256, num_outs=5), rpn_head=dict( type='RPNHead', in_channels=256, feat_channels=256, anchor_generator=dict( type='AnchorGenerator', scales=[8], ratios=[0.5, 1.0, 2.0], strides=[4, 8, 16, 32, 64]), bbox_coder=dict( type='DeltaXYWHBBoxCoder', target_means=[.0, .0, .0, .0], target_stds=[1.0, 1.0, 1.0, 1.0]), loss_cls=dict( type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0), loss_bbox=dict(type='L1Loss', loss_weight=1.0)), roi_head=dict( type='StandardRoIHead', bbox_roi_extractor=dict( type='SingleRoIExtractor', roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0), out_channels=256, featmap_strides=[4, 8, 16, 32]), bbox_head=dict( type='Shared2FCBBoxHead', in_channels=256, fc_out_channels=1024, roi_feat_size=7, #类别数 num_classes=3, bbox_coder=dict( type='DeltaXYWHBBoxCoder', target_means=[0., 0., 0., 0.], target_stds=[0.1, 0.1, 0.2, 0.2]), reg_class_agnostic=False, loss_cls=dict( type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0), loss_bbox=dict(type='L1Loss', loss_weight=1.0)))) # model training and testing settings .........
修改
_base_/schedules/schedule_1x.py
中的配置:optimizer = dict(type='SGD', lr=0.0025, momentum=0.9, weight_decay=0.0001) #当gpu数量为8时,lr=0.02;当gpu数量为8时,lr=0.01;我只要一个gpu,所以设置lr=0.0025
还可以修改训练的周期数.
- 在
mmdetection
的目录下新建work_dirs
文件夹
使用单GPU训练
python tools/train.py ${CONFIG_FILE} [optional arguments]
如果您想在命令中指定工作目录(保存训练过程日志等信息), 你可以添加参数 --work-dir ${YOUR_WORK_DIR}
.
使用多GPU训练
./tools/dist_train.sh ${CONFIG_FILE} ${GPU_NUM} [optional arguments]
可选参数:
--work-dir ${WORK_DIR}
: 指定工作目录(保存训练过程日志等信息)--resume-from ${CHECKPOINT_FILE}
: 从之前的断点文件中继续训练
例如:
python tools/train.py configs/cascade_rcnn/cascade_rcnn_r101_fpn_20e_coco.py --work-dir cascade_rcnn
测试
测试数据集
可以使用单GPU和多GPU对测试数据进行测试,使用如下命令:
# 单GPU测试
python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] [--eval ${EVAL_METRICS}] [--show] [--cfg-options]
# 多GPU测试
./tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${GPU_NUM} [--out ${RESULT_FILE}] [--eval ${EVAL_METRICS}] [--cfg-options]
可选参数:
RESULT_FILE
: 输出结果保存为pickle格式在指定目录下,如果不指定该参数,输出结果不保存。EVAL_METRICS
: 评价结果的标准。根据数据集可选择的评价标准有:proposal_fast
,proposal
,bbox
,segm
可用在COCO数据集上;mAP
,recall
可用在PASCAL VOC数据集上。--show
: 如果指定,检测结果将绘制在图像上并显示在一个新窗口中。仅适用于单GPU测试,用于调试和可视化。请确保GUI在你的环境中可用,否则您可能会遇到类似“无法连接到X服务器”的错误。--show-dir
: 如果指定,检测结果将绘制在图像上并保存到指定的目录中。仅适用于单GPU测试,用于调试和可视化。使用此选项时,环境中可以不需要可用的GUI。--show-score-thr
: 如果指定,则将删除分数低于此阈值的检测。
测试Faster R-CNN模型,并将结果可视化展示在窗口中,按任意键切换下一张图片:
python tools/test.py configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py save/epoch_9.pth --show detection_results --eval bbox
测试Faster R-CNN模型,不将结果可视化展示在窗口中,保存在文件中,为方便后续的可视化:
python tools/test.py configs/grid_rcnn/grid_rcnn_x101_64x4d_fpn_gn-head_2x_coco.py grid_rcnn/epoch_25.pth --show-dir detection_results --eval bbox
测试单张图片
python demo/image_demo.py ${IMAGE_FILE} ${CONFIG_FILE} ${CHECKPOINT_FILE} [--device ${GPU_ID}] [--score-thr ${SCORE_THR}]
例如使用Faster R-CNN模型测试demo.jpg
图片,输入如下命令:
python demo/image_demo.py demo/demo.jpg configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py \
checkpoints/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth --device cpu
分析训练日志
通过训练生成的log文件可以画出loss/mAP曲线。首先需要安装pip install seaborn
依赖。
python tools/analyze_logs.py plot_curve [--keys ${KEYS}] [--title ${TITLE}] [--legend ${LEGEND}] [--backend ${BACKEND}] [--style ${STYLE}] [--out ${OUT_FILE}]
绘制分类损失:
python tools/analyze_logs.py plot_curve faster_rcnn_1x_res50/20200928_120614.log.json --keys loss_cls loss_bbox --legend loss_cls loss_bbox
绘制分类损失和边界框损失:
python tools/analyze_logs.py plot_curve log.json --keys loss_cls loss_bbox
计算平均训练时间:
python tools/analyze_logs.py cal_train_time log.json
输出的格式如下:
-----Analyze train time of save/20200927_095440.log.json-----
slowest epoch 6, average time is 0.1322
fastest epoch 7, average time is 0.1202
time std over epochs is 0.0033
average iter time: 0.1271 s/iter
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!