ショートカット

単一ステージ検出器をRPNとして使用する

領域提案ネットワーク (RPN) は、Faster R-CNN のサブモジュールであり、Faster R-CNN の第2ステージの提案を生成します。MMDetection のほとんどの2ステージ検出器は、RPNHead を使用してRPNとして提案を生成します。ただし、単一ステージ検出器は、そのバウンディングボックスの予測も領域の提案と見なすことができ、R-CNN で絞り込むことができるため、RPN として機能できます。したがって、MMDetection v3.0 はそれをサポートしています。

プロセス全体を説明するために、ここでは、アンカーフリーの単一ステージモデル FCOSFaster R-CNN で RPN として使用する方法の例を示します。

このチュートリアルの概要は次のとおりです

  1. Faster R-CNN で FCOSHeadRPNHead として使用する

  2. 提案を評価する

  3. 事前トレーニング済み FCOS を使用してカスタマイズされた Faster R-CNN をトレーニングする

Faster R-CNN で FCOSHeadRPNHead として使用する

Faster R-CNN で FCOSHeadRPNHead として設定するには、configs/faster_rcnn/faster-rcnn_r50_fpn_fcos-rpn_1x_coco.py という名前の新しい設定ファイルを作成し、rpn_head の設定を configs/fcos/fcos_r50-caffe_fpn_gn-head_1x_coco.pybbox_head の設定に置き換える必要があります。また、ストライドが [8, 16, 32, 64, 128] の FCOS のネック設定を引き続き使用し、bbox_roi_extractorfeatmap_strides[8, 16, 32, 64, 128] に更新します。損失が NAN になるのを防ぐため、最初の 500 イテレーションではなく、最初の 1000 イテレーションでウォームアップを適用します。つまり、学習率はよりゆっくりと増加します。設定は次のとおりです

_base_ = [
    '../_base_/models/faster-rcnn_r50_fpn.py',
    '../_base_/datasets/coco_detection.py',
    '../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]

model = dict(
    # copied from configs/fcos/fcos_r50-caffe_fpn_gn-head_1x_coco.py
    neck=dict(
        start_level=1,
        add_extra_convs='on_output',  # use P5
        relu_before_extra_convs=True),
    rpn_head=dict(
        _delete_=True,  # ignore the unused old settings
        type='FCOSHead',
        num_classes=1,  # num_classes = 1 for rpn, if num_classes > 1, it will be set to 1 in TwoStageDetector automatically
        in_channels=256,
        stacked_convs=4,
        feat_channels=256,
        strides=[8, 16, 32, 64, 128],
        loss_cls=dict(
            type='FocalLoss',
            use_sigmoid=True,
            gamma=2.0,
            alpha=0.25,
            loss_weight=1.0),
        loss_bbox=dict(type='IoULoss', loss_weight=1.0),
        loss_centerness=dict(
            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0)),
    roi_head=dict(  # update featmap_strides due to the strides in neck
        bbox_roi_extractor=dict(featmap_strides=[8, 16, 32, 64, 128])))

# learning rate
param_scheduler = [
    dict(
        type='LinearLR', start_factor=0.001, by_epoch=False, begin=0,
        end=1000),  # Slowly increase lr, otherwise loss becomes NAN
    dict(
        type='MultiStepLR',
        begin=0,
        end=12,
        by_epoch=True,
        milestones=[8, 11],
        gamma=0.1)
]

次に、次のコマンドを使用して、カスタマイズしたモデルをトレーニングできます。トレーニングコマンドの詳細については、こちら を参照してください。

# training with 8 GPUS
bash tools/dist_train.sh configs/faster_rcnn/faster-rcnn_r50_fpn_fcos-rpn_1x_coco.py \
    8 \
    --work-dir ./work_dirs/faster-rcnn_r50_fpn_fcos-rpn_1x_coco

提案を評価する

提案の質は検出器の性能に大きく影響するため、提案を評価する方法も提供しています。上記と同様に、configs/rpn/fcos-rpn_r50_fpn_1x_coco.py という名前の新しい設定ファイルを作成し、rpn_head の設定を configs/fcos/fcos_r50-caffe_fpn_gn-head_1x_coco.pybbox_head の設定に置き換えます。

_base_ = [
    '../_base_/models/rpn_r50_fpn.py', '../_base_/datasets/coco_detection.py',
    '../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]

val_evaluator = dict(metric='proposal_fast')
test_evaluator = val_evaluator

model = dict(
    # copied from configs/fcos/fcos_r50-caffe_fpn_gn-head_1x_coco.py
    neck=dict(
        start_level=1,
        add_extra_convs='on_output',  # use P5
        relu_before_extra_convs=True),
    rpn_head=dict(
        _delete_=True,  # ignore the unused old settings
        type='FCOSHead',
        num_classes=1,  # num_classes = 1 for rpn, if num_classes > 1, it will be set to 1 in RPN automatically
        in_channels=256,
        stacked_convs=4,
        feat_channels=256,
        strides=[8, 16, 32, 64, 128],
        loss_cls=dict(
            type='FocalLoss',
            use_sigmoid=True,
            gamma=2.0,
            alpha=0.25,
            loss_weight=1.0),
        loss_bbox=dict(type='IoULoss', loss_weight=1.0),
        loss_centerness=dict(
            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0)))

トレーニング後にチェックポイント ./work_dirs/faster-rcnn_r50_fpn_fcos-rpn_1x_coco/epoch_12.pth があるとします。次のコマンドで提案の質を評価できます。

# testing with 8 GPUs
bash tools/dist_test.sh \
    configs/rpn/fcos-rpn_r50_fpn_1x_coco.py \
    ./work_dirs/faster-rcnn_r50_fpn_fcos-rpn_1x_coco/epoch_12.pth \
    8

事前トレーニング済み FCOS を使用してカスタマイズされた Faster R-CNN をトレーニングする

事前トレーニングは、トレーニングの収束を高速化するだけでなく、検出器の性能も向上させます。したがって、ここでは、事前トレーニング済み FCOS を RPN として使用してトレーニングを高速化し、精度を向上させる方法の例を示します。 FCOSHead を Faster R-CNN の rpn ヘッドとして使用し、事前トレーニング済み fcos_r50-caffe_fpn_gn-head_1x_coco でトレーニングするとします。 configs/faster_rcnn/faster-rcnn_r50-caffe_fpn_fcos-rpn_1x_coco.py という名前の設定ファイルの内容は次のとおりです。 fcos_r50-caffe_fpn_gn-head_1x_coco は caffe バージョンの ResNet50 を使用しているため、data_preprocessor のピクセル平均と標準偏差を更新する必要があることに注意してください。

_base_ = [
    '../_base_/models/faster-rcnn_r50_fpn.py',
    '../_base_/datasets/coco_detection.py',
    '../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]

model = dict(
    data_preprocessor=dict(
        mean=[103.530, 116.280, 123.675],
        std=[1.0, 1.0, 1.0],
        bgr_to_rgb=False),
    backbone=dict(
        norm_cfg=dict(type='BN', requires_grad=False),
        style='caffe',
        init_cfg=None),  # the checkpoint in ``load_from`` contains the weights of backbone
    neck=dict(
        start_level=1,
        add_extra_convs='on_output',  # use P5
        relu_before_extra_convs=True),
    rpn_head=dict(
        _delete_=True,  # ignore the unused old settings
        type='FCOSHead',
        num_classes=1,  # num_classes = 1 for rpn, if num_classes > 1, it will be set to 1 in TwoStageDetector automatically
        in_channels=256,
        stacked_convs=4,
        feat_channels=256,
        strides=[8, 16, 32, 64, 128],
        loss_cls=dict(
            type='FocalLoss',
            use_sigmoid=True,
            gamma=2.0,
            alpha=0.25,
            loss_weight=1.0),
        loss_bbox=dict(type='IoULoss', loss_weight=1.0),
        loss_centerness=dict(
            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0)),
    roi_head=dict(  # update featmap_strides due to the strides in neck
        bbox_roi_extractor=dict(featmap_strides=[8, 16, 32, 64, 128])))

load_from = 'https://download.openmmlab.com/mmdetection/v2.0/fcos/fcos_r50_caffe_fpn_gn-head_1x_coco/fcos_r50_caffe_fpn_gn-head_1x_coco-821213aa.pth'

トレーニングのコマンドは次のとおりです。

bash tools/dist_train.sh \
    configs/faster_rcnn/faster-rcnn_r50-caffe_fpn_fcos-rpn_1x_coco.py \
    8 \
    --work-dir ./work_dirs/faster-rcnn_r50-caffe_fpn_fcos-rpn_1x_coco