关于预训练模型,一般的检测都是使用ImageNet预训练的backbone,这是基本配置,官方也支持这种加载方式。
高级一点的的就是针对数据集做一次预训练:即将所有的目标裁剪出来,然后训练一个不错的分类模型,这样的初始化相比ImageNet就要好很多。
最后就是使用coco预训练的完整检测模型权重,这样的效果就是模型收敛速度快,而且效果一般都比较好,也是大家最常用的方法。由于每个任务的类别不同,需要对权重进行微调,这里给出mmdetection修改coco预训练权重类别的脚本。
脚本以cascade rcnn为例,其他模型的修改与之类似。
# for cascade rcnn
import torch
num_classes = 21
model_coco = torch.load("cascade_rcnn_x101_32x4d_fpn_2x_20181218-28f73c4c.pth")
# weight
model_coco["state_dict"]["bbox_head.0.fc_cls.weight"].resize_(num_classes,1024)
model_coco["state_dict"]["bbox_head.1.fc_cls.weight"].resize_(num_classes,1024)
model_coco["state_dict"]["bbox_head.2.fc_cls.weight"].resize_(num_classes,1024)
# bias
model_coco["state_dict"]["bbox_head.0.fc_cls.bias"].resize_(num_classes)
model_coco["state_dict"]["bbox_head.1.fc_cls.bias"].resize_(num_classes)
model_coco["state_dict"]["bbox_head.2.fc_cls.bias"].resize_(num_classes)
#save new model
torch.save(model_coco,"coco_pretrained_weights_classes_%d.pth"%num_classes)
Soft-NMS改进了之前比较暴力的NMS,当IOU超过某个阈值后,不再直接删除该框,而是降低它的置信度(得分),如果得分低到一个阈值,就会被排除;但是如果降低后任然较高,就会保留。
在mmdetection中的设置如下:
test_cfg = dict(
rpn=dict(
nms_across_levels=False,
nms_pre=1000,
nms_post=1000,
max_num=1000,
nms_thr=0.7,
min_bbox_size=0),
rcnn=dict(
score_thr=0.05, nms=dict(type='soft_nms', iou_thr=0.5), max_per_img=100),
keep_all_stages=False)
一般情况下,用GIoULoss代替L1Loss后会涨点。
原版用的配置文件(使用L1Loss)如下:
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, 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', out_size=7, sample_num=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=10,
bbox_coder=dict(
type='DeltaXYWHBBoxCoder',
target_means=[0.0, 0.0, 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))))
添加GIoULoss后的配置文件如下:
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, 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),
reg_decoded_bbox=True, # 使用GIoUI时注意添加
loss_bbox=dict(type='GIoULoss', loss_weight=5.0)),
roi_head=dict(
type='StandardRoIHead',
bbox_roi_extractor=dict(
type='SingleRoIExtractor',
roi_layer=dict(type='RoIAlign', out_size=7, sample_num=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=10,
bbox_coder=dict(
type='DeltaXYWHBBoxCoder',
target_means=[0.0, 0.0, 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),
reg_decoded_bbox=True, # 使用GIoUI时注意添加
loss_bbox=dict(type='GIoULoss', loss_weight=5.0))))
mmdetection在保存模型时,除了保存权重,还保存了原始数据和优化参数。但是,模型在测试时,有些参数是没有用的,怎样去掉这些无用的参数使模型减小(大约减小50%)呢?见下面的代码:
import torch
model_path = "epoch_30.pth"
checkpoint = torch.load(model_path)
checkpoint['meta'] = None
checkpoint['optimizer'] = None
weights = checkpoint['state_dict']
state_dict = {"state_dict":weights}
torch.save(state_dict, './epotch_30_new.pth')
在线难例挖掘:在训练过程中在线的选择困难样本进行训练(选择loss较大的样本)。
思想比较简单,在mmdetection中的应用如下:
以faster rcnn为例子:
_base_ = './faster_rcnn_r50_fpn_1x_coco.py'
train_cfg = dict(rcnn=dict(sampler=dict(type='OHEMSampler')))
第一行为你训练模型的配置文件,第二行把采样方式设置为在线难例挖掘。
todo:
(1). GIoULoss 已经完成
(2). 在线难例挖掘 已经完成
(3). 混合精度训练
(4). 可变形卷积
(5). 多尺度训练
(6). 多尺度测试与数据增强测试
(7). Albu数据增强库的使用
(8). 模型融合
(9). 过分割测试
(10). mosaic数据增强
(11). PAFPN
(12). 样本均衡抑制长尾分布问题