mmdetection中libra rcnn算法简单阐述与libra_faster_rcnn_x101_64x4d_fpn_1x.py参数讲解

一  简介

 在看到CVPR2019 论文 Libra R-CNN时发现这篇论文对一些训练过程中的不平衡进行了处理,从而获得了较高的准确率。

  1.  如何选择具有代表性的region proposal(这个问题很多论文都探讨过,可以认为是样本(proposal)的不平衡问题
  2. 不同level的特征如何融合才能真正地充分利用?(特征融合问题)
  3. 损失函数的设计能不能引导目标检测器更好地收敛?

针对上述三个问题进行一下方法的解决:

  •  IoU-balanced Sampling:OHME和imbalance是挖掘样本的主要流行方法。OHME根据置信度来选择困难样本,这个过程导致了内存和时间的浪费,训练过程膨胀,OHME因为噪声导致训练效果的不好。Focal loss解决了之前的背景类在但阶段检测的不平衡问题,但是对于两阶段检测器的效果就不是特备好。  样本的分布在IOU上并不是均匀分布的,生成侯选框的随机采样,会导致背景框的远大于框中的GT框,背景占据了大部分,IoU大多在0-0.05,60%的hard样本都在0.05的地方,随机采样只有30%,这种不平衡就会将困难样本埋没在简单样本中
  • Balanced Feature Pyramid(特征均衡):与使用横向连接集成多级特征的方法不同,主要使用相同的深度集成均衡语义特征来增强多级特征。一般组成部分是四个,rescaling,integrating,refining,and strengthening。

    获取平衡的语义信息,l层的分辨率特征叫做cl,为了融合多层语义信息和并且同时保存语义特征。使用插值和最大池化将多层的特征图都resize到中间的size,一共有L级特征。mmdetection中libra rcnn算法简单阐述与libra_faster_rcnn_x101_64x4d_fpn_1x.py参数讲解_第1张图片

    每个分辨率都获取到来自其它层的相等的语义信息,这个过程不包含任何的参数,我们观察到这种非参数方法的改进,证明了信息流的有效性。

mmdetection中libra rcnn算法简单阐述与libra_faster_rcnn_x101_64x4d_fpn_1x.py参数讲解_第2张图片

  • Balanced L1 Loss:mmdetection中libra rcnn算法简单阐述与libra_faster_rcnn_x101_64x4d_fpn_1x.py参数讲解_第3张图片

最后根据结果分析:IoU-balanced Sampling提升了0.9个点,BPN提升了0.9个点,Balanced loss 提升了0.8个点。总体提升了2.6个点,提升还是比较大的。

二 py文件中的参数含义

# model settings
model = dict(
    type='FasterRCNN',
    pretrained=None,     #加载预训练权重,没有用None;
    backbone=dict(
        type='ResNeXt',
        depth=101,       #网络层数
        groups=64,       #组数
        base_width=4,    #channel数
        num_stages=4,
        out_indices=(0, 1, 2, 3), #输出stage的序号
        frozen_stages=1,          #冻结的stage数量,即该stage不更新参数,-1表示所有的stage都更新参数
        style='pytorch'),         #语言风格,设置pytorch,stride=2的层卷积层是3x3;设置caffe,s=2的层卷层为1x1
    neck=[
        dict(
            type='FPN',
            in_channels=[256, 512, 1024, 2048], #输入各个stage的通道数
            out_channels=256,                   #输出的特征通道数
            num_outs=5),                        #输出的特征层的数量
        dict(
            type='BFP',                         #特征均衡处理
            in_channels=256,                    #输入的通道数
            num_levels=5,                       #输入特征图层数
            refine_level=2,                     #集成索引和优化中的BSF级别从下到上的多级功能
            refine_type='non_local')            #优化操作的类型,当前支持[None, 'conv', 'non_local']
    ],
    rpn_head=dict(
        type='RPNHead',                        #RPN网络
        in_channels=256,                       #网络输入通道数
        feat_channels=256,                     #特征层的通道数
        anchor_scales=[8],                     #生成的anchor的baselen,baselen = sqrt(w*h),w和h为anchor的宽和高
        anchor_ratios=[0.5, 1.0, 2.0],         #anchor的宽高比
        anchor_strides=[4, 8, 16, 32, 64],     #在每个特征图上的anchor步长
        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='SmoothL1Loss', beta=1.0 / 9.0, loss_weight=1.0)),
    bbox_roi_extractor=dict(
        type='SingleRoIExtractor',             # RoIExtractor类型
        roi_layer=dict(type='RoIAlign', out_size=7, sample_num=2), # ROI具体参数:ROI类型为ROIalign,输出尺寸为7,sample数为2
        out_channels=256,                       # 输出通道数
        featmap_strides=[4, 8, 16, 32]),        # 特征图的步长
    bbox_head=dict(
        type='SharedFCBBoxHead',                #全连接层
        num_fcs=2,                              #全连接层数
        in_channels=256,                        #输入通道数
        fc_out_channels=1024,                   #输出通道数
        roi_feat_size=7,                        #ROI特征层尺寸
        num_classes=21,                         #分类个数+背景
        target_means=[0., 0., 0., 0.],          #均值
        target_stds=[0.1, 0.1, 0.2, 0.2],       #方差
        reg_class_agnostic=False,               #是否采用class_agnostic的方式来预测,class_agnostic表示输出bbox时只考虑其是否为前景,后续分类的时候再根据该bbox在网络中的类别得分来分类,也就是说一个框可以对应多个类别
        loss_cls=dict(
            type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0),
        loss_bbox=dict(
            type='BalancedL1Loss',             #损失均值处理
            alpha=0.5,
            gamma=1.5,
            beta=1.0,
            loss_weight=1.0)))
# model training and testing settings
train_cfg = dict(
    rpn=dict(
        assigner=dict(
            type='MaxIoUAssigner',           #RPN网络的正负样本划分
            pos_iou_thr=0.7,                 #正样本的阈值
            neg_iou_thr=0.3,                 #负样本的阈值
            min_pos_iou=0.3,                 #正样本的iou最小值。如果assign给ground truth的anchors中最大的IOU低于0.3,则忽略所有的anchors,否则保留最大IOU的anchor
            ignore_iof_thr=-1),              #忽略bbox的阈值,当ground truth中包含需要忽略的bbox时使用,-1表示不忽略
        sampler=dict(
            type='RandomSampler',            #正负样本提取器类型
            num=256,                         #正负样本的数量
            pos_fraction=0.5,                #正负样本的比例
            neg_pos_ub=5,                    #最大负样本比例,大于该比例的负样本忽略,-1表示不忽略
            add_gt_as_proposals=False),      #把ground truth加入proposal作为正样本
        allowed_border=-1,                   #不允许/允许(-1/0)在bbox周围外扩一定的像素
        pos_weight=-1,                       #正样本权重,-1表示不改变原始的权重
        debug=False),
    rpn_proposal=dict(
        nms_across_levels=False,            #在所有的fpn层内做nms
        nms_pre=2000,                       #在nms之前保留的的得分最高的proposal数量
        nms_post=2000,                      #在nms之后保留的的得分最高的proposal数量
        max_num=2000,                       #在后处理完成之后保留的proposal数量
        nms_thr=0.7,                        #nms阈值
        min_bbox_size=0),                   #最小bbox尺寸
    rcnn=dict(
        assigner=dict(
            type='MaxIoUAssigner',          #RCNN网络正负样本划分
            pos_iou_thr=0.5,                #正样本的iou阈值
            neg_iou_thr=0.5,                #负样本的iou阈值
            min_pos_iou=0.5,                #正样本的iou最小值。如果assign给ground truth的anchors中最大的IOU低于0.3,则忽略所有的anchors,否则保留最大IOU的anchor
            ignore_iof_thr=-1),             #忽略bbox的阈值,当ground truth中包含需要忽略的bbox时使用,-1表示不忽略
        sampler=dict(
            type='CombinedSampler',         #正负样本提取器类型
            num=512,                        #需提取的正负样本数量
            pos_fraction=0.25,              #正样本比例
            add_gt_as_proposals=True,       #把ground truth加入proposal作为正样本
            pos_sampler=dict(type='InstanceBalancedPosSampler'),
            neg_sampler=dict(
                type='IoUBalancedNegSampler', #均衡IOU处理
                floor_thr=-1,
                floor_fraction=0,
                num_bins=3)),
        pos_weight=-1,                      #正样本权重,-1表示不改变原始的权重
        debug=False))                       #debug模式
test_cfg = dict(
    rpn=dict(                               #测试时的RPN参数
        nms_across_levels=False,            #在所有的fpn层内做nms
        nms_pre=1000,                       #在nms之前保留的的得分最高的proposal数量
        nms_post=1000,                      #在nms之后保留的的得分最高的proposal数量
        max_num=1000,                       #在后处理完成之后保留的proposal数量
        nms_thr=0.7,                        #nms阈值
        min_bbox_size=0),
    rcnn=dict(                            # max_per_img表示最终输出的det bbox数量
        score_thr=0.05, nms=dict(type='nms', iou_thr=0.5), max_per_img=100)
    # soft-nms is also supported for rcnn testing
    # e.g., nms=dict(type='soft_nms', iou_thr=0.5, min_score=0.05)
)
# dataset settings
dataset_type = 'VOCDataset'   #数据类型
#data_root = 'data/coco/'
img_norm_cfg = dict(          #输入图像初始化,减去均值mean并处以方差std,to_rgb表示将bgr转为rgb
    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
data = dict(
    imgs_per_gpu=2,                  #每个gpu计算的图像数量
    workers_per_gpu=2,               #每个gpu分配的线程数
    train=dict(
        type=dataset_type,           #数据类型
        ann_file='/data/maq/DataSet/mmdetection/VOC2012/ImageSets/Main/train.txt', #训练数据地址
        img_prefix='/data/maq/DataSet/mmdetection/VOC2012',                        #训练图片路径
        img_scale=(1333, 800),        #输入图片尺寸(最大边长,最小边长)
        img_norm_cfg=img_norm_cfg,    #图像初始化参数
        size_divisor=32,              #对图像进行resize时的最小单位,32表示所有的图像都会被resize成32的倍数
        flip_ratio=0.5,               #对图像随机翻转
        with_mask=False,              #训练附带mask
        with_crowd=True,              #训练附带困难度
        with_label=True),             #训练附带标签
    val=dict(                         #同上
        type=dataset_type,
        ann_file='/data/maq/DataSet/mmdetection/VOC2012/ImageSets/Main/val.txt',
        img_prefix='/data/maq/DataSet/mmdetection/VOC2012',
        img_scale=(1333, 800),
        img_norm_cfg=img_norm_cfg,
        size_divisor=32,
        flip_ratio=0,
        with_mask=False,
        with_crowd=True,
        with_label=True),
    test=dict(                       #同上
        type=dataset_type,
        ann_file='/data/maq/DataSet/mmdetection/VOC2012/ImageSets/Main/trainval.txt',
        img_prefix='/data/maq/DataSet/mmdetection/VOC2012',
        img_scale=(1333, 800),
        img_norm_cfg=img_norm_cfg,
        size_divisor=32,
        flip_ratio=0,
        with_mask=False,
        with_label=False,
        test_mode=True))
# optimizer           #优化参数,lr为学习率,momentum为动量因子,weight_decay为权重衰减因子
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=dict(max_norm=35, norm_type=2))  #梯度均衡参数
# learning policy
lr_config = dict(
    policy='step',     #优化策略
    warmup='linear',   #初始的学习率增加策略,linear线性增加
    warmup_iters=500,  #初始的500次迭代中学习率逐渐增加
    warmup_ratio=1.0 / 3, #起始学习率
    step=[8, 11])         #在第8和11个epoch时降低学习率
checkpoint_config = dict(interval=1)   #每多少次储存一次模型
# yapf:disable
log_config = dict(
    interval=50,      #每50个batch输出一次信息
    hooks=[
        dict(type='TextLoggerHook'), #控制台输出信息的风格
        #dict(type='TensorboardLoggerHook')
    ])
# yapf:enable
# runtime settings
total_epochs = 12         #最大epoch数
dist_params = dict(backend='nccl')   #分布式参数
log_level = 'INFO'                   #输出信息的完整度级别
work_dir = './work_dirs/libra_faster_rcnn_x101_64x4d_fpn_1x'  #log文件和模型文件存储路径
load_from = None                    #加载模型的路径,None表示从预训练模型加载
resume_from = None                  #恢复训练模型的路径
workflow = [('train', 1)]           #当前工作区名称

三  使用voc数据进行训练

   根据二中的步骤对相关参数进行修改:

   pretrained ;num_class;ann_file;img_prefix  必改参数,剩下可按照自己需求修改

   运行代码python tools/train.py  config/my.py即可

   mmdetection中libra rcnn算法简单阐述与libra_faster_rcnn_x101_64x4d_fpn_1x.py参数讲解_第4张图片

      

你可能感兴趣的:(目标检测)