Configsについて学ぶ¶
MMDetectionおよびその他のOpenMMLabリポジトリは、MMEngineのconfigシステムを使用しています。これはモジュール式で継承設計であり、さまざまな実験を行うのに便利です。
設定ファイルの内容¶
MMDetectionはモジュール設計を使用しており、異なる機能を持つすべてのモジュールを設定を通じて構成できます。Mask R-CNNを例に、異なる機能モジュールに従って設定の各フィールドを紹介します。
モデル設定¶
MMDetectionの設定では、model
を使用して検出アルゴリズムのコンポーネントを設定します。backbone
、neck
などのニューラルネットワークコンポーネントに加えて、data_preprocessor
、train_cfg
、およびtest_cfg
も必要です。data_preprocessor
は、データローダーが出力するバッチデータの処理を担当します。model
設定のtrain_cfg
およびtest_cfg
は、コンポーネントのトレーニングおよびテストのハイパーパラメータを設定します。
model = dict(
type='MaskRCNN', # The name of detector
data_preprocessor=dict( # The config of data preprocessor, usually includes image normalization and padding
type='DetDataPreprocessor', # The type of the data preprocessor, refer to https://mmdetection.dokyumento.jp/en/latest/api.html#mmdet.models.data_preprocessors.DetDataPreprocessor
mean=[123.675, 116.28, 103.53], # Mean values used to pre-training the pre-trained backbone models, ordered in R, G, B
std=[58.395, 57.12, 57.375], # Standard variance used to pre-training the pre-trained backbone models, ordered in R, G, B
bgr_to_rgb=True, # whether to convert image from BGR to RGB
pad_mask=True, # whether to pad instance masks
pad_size_divisor=32), # The size of padded image should be divisible by ``pad_size_divisor``
backbone=dict( # The config of backbone
type='ResNet', # The type of backbone network. Refer to https://mmdetection.dokyumento.jp/en/latest/api.html#mmdet.models.backbones.ResNet
depth=50, # The depth of backbone, usually it is 50 or 101 for ResNet and ResNext backbones.
num_stages=4, # Number of stages of the backbone.
out_indices=(0, 1, 2, 3), # The index of output feature maps produced in each stage
frozen_stages=1, # The weights in the first stage are frozen
norm_cfg=dict( # The config of normalization layers.
type='BN', # Type of norm layer, usually it is BN or GN
requires_grad=True), # Whether to train the gamma and beta in BN
norm_eval=True, # Whether to freeze the statistics in BN
style='pytorch', # The style of backbone, 'pytorch' means that stride 2 layers are in 3x3 Conv, 'caffe' means stride 2 layers are in 1x1 Convs.
init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')), # The ImageNet pretrained backbone to be loaded
neck=dict(
type='FPN', # The neck of detector is FPN. We also support 'NASFPN', 'PAFPN', etc. Refer to https://mmdetection.dokyumento.jp/en/latest/api.html#mmdet.models.necks.FPN for more details.
in_channels=[256, 512, 1024, 2048], # The input channels, this is consistent with the output channels of backbone
out_channels=256, # The output channels of each level of the pyramid feature map
num_outs=5), # The number of output scales
rpn_head=dict(
type='RPNHead', # The type of RPN head is 'RPNHead', we also support 'GARPNHead', etc. Refer to https://mmdetection.dokyumento.jp/en/latest/api.html#mmdet.models.dense_heads.RPNHead for more details.
in_channels=256, # The input channels of each input feature map, this is consistent with the output channels of neck
feat_channels=256, # Feature channels of convolutional layers in the head.
anchor_generator=dict( # The config of anchor generator
type='AnchorGenerator', # Most of methods use AnchorGenerator, SSD Detectors uses `SSDAnchorGenerator`. Refer to https://github.com/open-mmlab/mmdetection/blob/main/mmdet/models/task_modules/prior_generators/anchor_generator.py#L18 for more details
scales=[8], # Basic scale of the anchor, the area of the anchor in one position of a feature map will be scale * base_sizes
ratios=[0.5, 1.0, 2.0], # The ratio between height and width.
strides=[4, 8, 16, 32, 64]), # The strides of the anchor generator. This is consistent with the FPN feature strides. The strides will be taken as base_sizes if base_sizes is not set.
bbox_coder=dict( # Config of box coder to encode and decode the boxes during training and testing
type='DeltaXYWHBBoxCoder', # Type of box coder. 'DeltaXYWHBBoxCoder' is applied for most of the methods. Refer to https://github.com/open-mmlab/mmdetection/blob/main/mmdet/models/task_modules/coders/delta_xywh_bbox_coder.py#L13 for more details.
target_means=[0.0, 0.0, 0.0, 0.0], # The target means used to encode and decode boxes
target_stds=[1.0, 1.0, 1.0, 1.0]), # The standard variance used to encode and decode boxes
loss_cls=dict( # Config of loss function for the classification branch
type='CrossEntropyLoss', # Type of loss for classification branch, we also support FocalLoss etc. Refer to https://github.com/open-mmlab/mmdetection/blob/main/mmdet/models/losses/cross_entropy_loss.py#L201 for more details
use_sigmoid=True, # RPN usually performs two-class classification, so it usually uses the sigmoid function.
loss_weight=1.0), # Loss weight of the classification branch.
loss_bbox=dict( # Config of loss function for the regression branch.
type='L1Loss', # Type of loss, we also support many IoU Losses and smooth L1-loss, etc. Refer to https://github.com/open-mmlab/mmdetection/blob/main/mmdet/models/losses/smooth_l1_loss.py#L56 for implementation.
loss_weight=1.0)), # Loss weight of the regression branch.
roi_head=dict( # RoIHead encapsulates the second stage of two-stage/cascade detectors.
type='StandardRoIHead',
bbox_roi_extractor=dict( # RoI feature extractor for bbox regression.
type='SingleRoIExtractor', # Type of the RoI feature extractor, most of methods uses SingleRoIExtractor. Refer to https://github.com/open-mmlab/mmdetection/blob/main/mmdet/models/roi_heads/roi_extractors/single_level_roi_extractor.py#L13 for details.
roi_layer=dict( # Config of RoI Layer
type='RoIAlign', # Type of RoI Layer, DeformRoIPoolingPack and ModulatedDeformRoIPoolingPack are also supported. Refer to https://mmcv.readthedocs.io/en/latest/api.html#mmcv.ops.RoIAlign for details.
output_size=7, # The output size of feature maps.
sampling_ratio=0), # Sampling ratio when extracting the RoI features. 0 means adaptive ratio.
out_channels=256, # output channels of the extracted feature.
featmap_strides=[4, 8, 16, 32]), # Strides of multi-scale feature maps. It should be consistent with the architecture of the backbone.
bbox_head=dict( # Config of box head in the RoIHead.
type='Shared2FCBBoxHead', # Type of the bbox head, Refer to https://github.com/open-mmlab/mmdetection/blob/main/mmdet/models/roi_heads/bbox_heads/convfc_bbox_head.py#L220 for implementation details.
in_channels=256, # Input channels for bbox head. This is consistent with the out_channels in roi_extractor
fc_out_channels=1024, # Output feature channels of FC layers.
roi_feat_size=7, # Size of RoI features
num_classes=80, # Number of classes for classification
bbox_coder=dict( # Box coder used in the second stage.
type='DeltaXYWHBBoxCoder', # Type of box coder. 'DeltaXYWHBBoxCoder' is applied for most of the methods.
target_means=[0.0, 0.0, 0.0, 0.0], # Means used to encode and decode box
target_stds=[0.1, 0.1, 0.2, 0.2]), # Standard variance for encoding and decoding. It is smaller since the boxes are more accurate. [0.1, 0.1, 0.2, 0.2] is a conventional setting.
reg_class_agnostic=False, # Whether the regression is class agnostic.
loss_cls=dict( # Config of loss function for the classification branch
type='CrossEntropyLoss', # Type of loss for classification branch, we also support FocalLoss etc.
use_sigmoid=False, # Whether to use sigmoid.
loss_weight=1.0), # Loss weight of the classification branch.
loss_bbox=dict( # Config of loss function for the regression branch.
type='L1Loss', # Type of loss, we also support many IoU Losses and smooth L1-loss, etc.
loss_weight=1.0)), # Loss weight of the regression branch.
mask_roi_extractor=dict( # RoI feature extractor for mask generation.
type='SingleRoIExtractor', # Type of the RoI feature extractor, most of methods uses SingleRoIExtractor.
roi_layer=dict( # Config of RoI Layer that extracts features for instance segmentation
type='RoIAlign', # Type of RoI Layer, DeformRoIPoolingPack and ModulatedDeformRoIPoolingPack are also supported
output_size=14, # The output size of feature maps.
sampling_ratio=0), # Sampling ratio when extracting the RoI features.
out_channels=256, # Output channels of the extracted feature.
featmap_strides=[4, 8, 16, 32]), # Strides of multi-scale feature maps.
mask_head=dict( # Mask prediction head
type='FCNMaskHead', # Type of mask head, refer to https://mmdetection.dokyumento.jp/en/latest/api.html#mmdet.models.roi_heads.FCNMaskHead for implementation details.
num_convs=4, # Number of convolutional layers in mask head.
in_channels=256, # Input channels, should be consistent with the output channels of mask roi extractor.
conv_out_channels=256, # Output channels of the convolutional layer.
num_classes=80, # Number of class to be segmented.
loss_mask=dict( # Config of loss function for the mask branch.
type='CrossEntropyLoss', # Type of loss used for segmentation
use_mask=True, # Whether to only train the mask in the correct class.
loss_weight=1.0))), # Loss weight of mask branch.
train_cfg = dict( # Config of training hyperparameters for rpn and rcnn
rpn=dict( # Training config of rpn
assigner=dict( # Config of assigner
type='MaxIoUAssigner', # Type of assigner, MaxIoUAssigner is used for many common detectors. Refer to https://github.com/open-mmlab/mmdetection/blob/main/mmdet/models/task_modules/assigners/max_iou_assigner.py#L14 for more details.
pos_iou_thr=0.7, # IoU >= threshold 0.7 will be taken as positive samples
neg_iou_thr=0.3, # IoU < threshold 0.3 will be taken as negative samples
min_pos_iou=0.3, # The minimal IoU threshold to take boxes as positive samples
match_low_quality=True, # Whether to match the boxes under low quality (see API doc for more details).
ignore_iof_thr=-1), # IoF threshold for ignoring bboxes
sampler=dict( # Config of positive/negative sampler
type='RandomSampler', # Type of sampler, PseudoSampler and other samplers are also supported. Refer to https://github.com/open-mmlab/mmdetection/blob/main/mmdet/models/task_modules/samplers/random_sampler.py#L14 for implementation details.
num=256, # Number of samples
pos_fraction=0.5, # The ratio of positive samples in the total samples.
neg_pos_ub=-1, # The upper bound of negative samples based on the number of positive samples.
add_gt_as_proposals=False), # Whether add GT as proposals after sampling.
allowed_border=-1, # The border allowed after padding for valid anchors.
pos_weight=-1, # The weight of positive samples during training.
debug=False), # Whether to set the debug mode
rpn_proposal=dict( # The config to generate proposals during training
nms_across_levels=False, # Whether to do NMS for boxes across levels. Only work in `GARPNHead`, naive rpn does not support do nms cross levels.
nms_pre=2000, # The number of boxes before NMS
nms_post=1000, # The number of boxes to be kept by NMS. Only work in `GARPNHead`.
max_per_img=1000, # The number of boxes to be kept after NMS.
nms=dict( # Config of NMS
type='nms', # Type of NMS
iou_threshold=0.7 # NMS threshold
),
min_bbox_size=0), # The allowed minimal box size
rcnn=dict( # The config for the roi heads.
assigner=dict( # Config of assigner for second stage, this is different for that in rpn
type='MaxIoUAssigner', # Type of assigner, MaxIoUAssigner is used for all roi_heads for now. Refer to https://github.com/open-mmlab/mmdetection/blob/main/mmdet/models/task_modules/assigners/max_iou_assigner.py#L14 for more details.
pos_iou_thr=0.5, # IoU >= threshold 0.5 will be taken as positive samples
neg_iou_thr=0.5, # IoU < threshold 0.5 will be taken as negative samples
min_pos_iou=0.5, # The minimal IoU threshold to take boxes as positive samples
match_low_quality=False, # Whether to match the boxes under low quality (see API doc for more details).
ignore_iof_thr=-1), # IoF threshold for ignoring bboxes
sampler=dict(
type='RandomSampler', # Type of sampler, PseudoSampler and other samplers are also supported. Refer to https://github.com/open-mmlab/mmdetection/blob/main/mmdet/models/task_modules/samplers/random_sampler.py#L14 for implementation details.
num=512, # Number of samples
pos_fraction=0.25, # The ratio of positive samples in the total samples.
neg_pos_ub=-1, # The upper bound of negative samples based on the number of positive samples.
add_gt_as_proposals=True
), # Whether add GT as proposals after sampling.
mask_size=28, # Size of mask
pos_weight=-1, # The weight of positive samples during training.
debug=False)), # Whether to set the debug mode
test_cfg = dict( # Config for testing hyperparameters for rpn and rcnn
rpn=dict( # The config to generate proposals during testing
nms_across_levels=False, # Whether to do NMS for boxes across levels. Only work in `GARPNHead`, naive rpn does not support do nms cross levels.
nms_pre=1000, # The number of boxes before NMS
nms_post=1000, # The number of boxes to be kept by NMS. Only work in `GARPNHead`.
max_per_img=1000, # The number of boxes to be kept after NMS.
nms=dict( # Config of NMS
type='nms', #Type of NMS
iou_threshold=0.7 # NMS threshold
),
min_bbox_size=0), # The allowed minimal box size
rcnn=dict( # The config for the roi heads.
score_thr=0.05, # Threshold to filter out boxes
nms=dict( # Config of NMS in the second stage
type='nms', # Type of NMS
iou_thr=0.5), # NMS threshold
max_per_img=100, # Max number of detections of each image
mask_thr_binary=0.5))) # Threshold of mask prediction
データセットと評価器の設定¶
データローダーは、ランナーのトレーニング、検証、およびテストに必要です。データローダーを構築するには、データセットとデータパイプラインを設定する必要があります。この部分の複雑さから、中間変数を使用してデータローダーの設定の記述を簡略化します。
dataset_type = 'CocoDataset' # Dataset type, this will be used to define the dataset
data_root = 'data/coco/' # Root path of data
backend_args = None # Arguments to instantiate the corresponding file backend
train_pipeline = [ # Training data processing pipeline
dict(type='LoadImageFromFile', backend_args=backend_args), # First pipeline to load images from file path
dict(
type='LoadAnnotations', # Second pipeline to load annotations for current image
with_bbox=True, # Whether to use bounding box, True for detection
with_mask=True, # Whether to use instance mask, True for instance segmentation
poly2mask=True), # Whether to convert the polygon mask to instance mask, set False for acceleration and to save memory
dict(
type='Resize', # Pipeline that resizes the images and their annotations
scale=(1333, 800), # The largest scale of the images
keep_ratio=True # Whether to keep the ratio between height and width
),
dict(
type='RandomFlip', # Augmentation pipeline that flips the images and their annotations
prob=0.5), # The probability to flip
dict(type='PackDetInputs') # Pipeline that formats the annotation data and decides which keys in the data should be packed into data_samples
]
test_pipeline = [ # Testing data processing pipeline
dict(type='LoadImageFromFile', backend_args=backend_args), # First pipeline to load images from file path
dict(type='Resize', scale=(1333, 800), keep_ratio=True), # Pipeline that resizes the images
dict(
type='PackDetInputs', # Pipeline that formats the annotation data and decides which keys in the data should be packed into data_samples
meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',
'scale_factor'))
]
train_dataloader = dict( # Train dataloader config
batch_size=2, # Batch size of a single GPU
num_workers=2, # Worker to pre-fetch data for each single GPU
persistent_workers=True, # If ``True``, the dataloader will not shut down the worker processes after an epoch end, which can accelerate training speed.
sampler=dict( # training data sampler
type='DefaultSampler', # DefaultSampler which supports both distributed and non-distributed training. Refer to https://mmengine.readthedocs.io/en/latest/api/generated/mmengine.dataset.DefaultSampler.html#mmengine.dataset.DefaultSampler
shuffle=True), # randomly shuffle the training data in each epoch
batch_sampler=dict(type='AspectRatioBatchSampler'), # Batch sampler for grouping images with similar aspect ratio into a same batch. It can reduce GPU memory cost.
dataset=dict( # Train dataset config
type=dataset_type,
data_root=data_root,
ann_file='annotations/instances_train2017.json', # Path of annotation file
data_prefix=dict(img='train2017/'), # Prefix of image path
filter_cfg=dict(filter_empty_gt=True, min_size=32), # Config of filtering images and annotations
pipeline=train_pipeline,
backend_args=backend_args))
val_dataloader = dict( # Validation dataloader config
batch_size=1, # Batch size of a single GPU. If batch-size > 1, the extra padding area may influence the performance.
num_workers=2, # Worker to pre-fetch data for each single GPU
persistent_workers=True, # If ``True``, the dataloader will not shut down the worker processes after an epoch end, which can accelerate training speed.
drop_last=False, # Whether to drop the last incomplete batch, if the dataset size is not divisible by the batch size
sampler=dict(
type='DefaultSampler',
shuffle=False), # not shuffle during validation and testing
dataset=dict(
type=dataset_type,
data_root=data_root,
ann_file='annotations/instances_val2017.json',
data_prefix=dict(img='val2017/'),
test_mode=True, # Turn on the test mode of the dataset to avoid filtering annotations or images
pipeline=test_pipeline,
backend_args=backend_args))
test_dataloader = val_dataloader # Testing dataloader config
評価器は、トレーニング済みモデルの検証およびテストデータセットでのメトリクスを計算するために使用されます。評価器の設定は、1つまたはメトリクス設定のリストで構成されます。
val_evaluator = dict( # Validation evaluator config
type='CocoMetric', # The coco metric used to evaluate AR, AP, and mAP for detection and instance segmentation
ann_file=data_root + 'annotations/instances_val2017.json', # Annotation file path
metric=['bbox', 'segm'], # Metrics to be evaluated, `bbox` for detection and `segm` for instance segmentation
format_only=False,
backend_args=backend_args)
test_evaluator = val_evaluator # Testing evaluator config
テストデータセットにはアノテーションファイルがないため、MMDetectionのtest_dataloaderとtest_evaluatorの設定は通常、valのものと同じです。テストデータセットでの検出結果を保存する場合は、このように設定を記述できます。
# inference on test dataset and
# format the output results for submission.
test_dataloader = dict(
batch_size=1,
num_workers=2,
persistent_workers=True,
drop_last=False,
sampler=dict(type='DefaultSampler', shuffle=False),
dataset=dict(
type=dataset_type,
data_root=data_root,
ann_file=data_root + 'annotations/image_info_test-dev2017.json',
data_prefix=dict(img='test2017/'),
test_mode=True,
pipeline=test_pipeline))
test_evaluator = dict(
type='CocoMetric',
ann_file=data_root + 'annotations/image_info_test-dev2017.json',
metric=['bbox', 'segm'], # Metrics to be evaluated
format_only=True, # Only format and save the results to coco json file
outfile_prefix='./work_dirs/coco_detection/test') # The prefix of output json files
トレーニングとテストの設定¶
MMEngineのランナーは、ループを使用してトレーニング、検証、およびテストプロセスを制御します。ユーザーはこれらのフィールドを使用して、最大のトレーニングエポック数と検証間隔を設定できます。
train_cfg = dict(
type='EpochBasedTrainLoop', # The training loop type. Refer to https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/loops.py
max_epochs=12, # Maximum training epochs
val_interval=1) # Validation intervals. Run validation every epoch.
val_cfg = dict(type='ValLoop') # The validation loop type
test_cfg = dict(type='TestLoop') # The testing loop type
最適化設定¶
optim_wrapper
は、最適化関連の設定を構成するフィールドです。オプティマイザラッパーは、オプティマイザの機能を提供するだけでなく、勾配クリッピング、混合精度トレーニングなどの機能もサポートしています。詳細については、オプティマイザラッパーチュートリアルを参照してください。
optim_wrapper = dict( # Optimizer wrapper config
type='OptimWrapper', # Optimizer wrapper type, switch to AmpOptimWrapper to enable mixed precision training.
optimizer=dict( # Optimizer config. Support all kinds of optimizers in PyTorch. Refer to https://pytorch.org/docs/stable/optim.html#algorithms
type='SGD', # Stochastic gradient descent optimizer
lr=0.02, # The base learning rate
momentum=0.9, # Stochastic gradient descent with momentum
weight_decay=0.0001), # Weight decay of SGD
clip_grad=None, # Gradient clip option. Set None to disable gradient clip. Find usage in https://mmengine.readthedocs.io/en/latest/tutorials/optimizer.html
)
param_scheduler
は、学習率やモーメンタムなどの最適化ハイパーパラメータを調整する方法を構成するフィールドです。ユーザーは、複数のスケジューラーを組み合わせて、目的のパラメータ調整戦略を作成できます。詳細については、パラメータスケジューラチュートリアルおよびパラメータスケジューラAPIドキュメントを参照してください。
param_scheduler = [
# Linear learning rate warm-up scheduler
dict(
type='LinearLR', # Use linear policy to warmup learning rate
start_factor=0.001, # The ratio of the starting learning rate used for warmup
by_epoch=False, # The warmup learning rate is updated by iteration
begin=0, # Start from the first iteration
end=500), # End the warmup at the 500th iteration
# The main LRScheduler
dict(
type='MultiStepLR', # Use multi-step learning rate policy during training
by_epoch=True, # The learning rate is updated by epoch
begin=0, # Start from the first epoch
end=12, # End at the 12th epoch
milestones=[8, 11], # Epochs to decay the learning rate
gamma=0.1) # The learning rate decay ratio
]
フック設定¶
ユーザーは、トレーニング、検証、およびテストループにフックをアタッチして、実行中にいくつかの操作を挿入できます。2つの異なるフックフィールドがあります。1つはdefault_hooks
で、もう1つはcustom_hooks
です。
default_hooks
はフック設定の辞書であり、これらは実行時に必要なフックです。これらには変更すべきでないデフォルトの優先順位があります。設定しない場合、ランナーはデフォルト値を使用します。デフォルトのフックを無効にするには、ユーザーはその設定をNone
に設定できます。詳細については、HOOKを参照してください。
default_hooks = dict(
timer=dict(type='IterTimerHook'), # Update the time spent during iteration into message hub
logger=dict(type='LoggerHook', interval=50), # Collect logs from different components of Runner and write them to terminal, JSON file, tensorboard and wandb .etc
param_scheduler=dict(type='ParamSchedulerHook'), # update some hyper-parameters of optimizer
checkpoint=dict(type='CheckpointHook', interval=1), # Save checkpoints periodically
sampler_seed=dict(type='DistSamplerSeedHook'), # Ensure distributed Sampler shuffle is active
visualization=dict(type='DetVisualizationHook')) # Detection Visualization Hook. Used to visualize validation and testing process prediction results
custom_hooks
は、他のすべてのフック設定のリストです。ユーザーは独自のフックを開発して、このフィールドに挿入できます。
custom_hooks = []
ランタイム設定¶
default_scope = 'mmdet' # The default registry scope to find modules. Refer to https://mmengine.readthedocs.io/en/latest/advanced_tutorials/registry.html
env_cfg = dict(
cudnn_benchmark=False, # Whether to enable cudnn benchmark
mp_cfg=dict( # Multi-processing config
mp_start_method='fork', # Use fork to start multi-processing threads. 'fork' usually faster than 'spawn' but maybe unsafe. See discussion in https://github.com/pytorch/pytorch/issues/1355
opencv_num_threads=0), # Disable opencv multi-threads to avoid system being overloaded
dist_cfg=dict(backend='nccl'), # Distribution configs
)
vis_backends = [dict(type='LocalVisBackend')] # Visualization backends. Refer to https://mmengine.readthedocs.io/en/latest/advanced_tutorials/visualization.html
visualizer = dict(
type='DetLocalVisualizer', vis_backends=vis_backends, name='visualizer')
log_processor = dict(
type='LogProcessor', # Log processor to process runtime logs
window_size=50, # Smooth interval of log values
by_epoch=True) # Whether to format logs with epoch type. Should be consistent with the train loop's type.
log_level = 'INFO' # The level of logging.
load_from = None # Load model checkpoint as a pre-trained model from a given path. This will not resume training.
resume = False # Whether to resume from the checkpoint defined in `load_from`. If `load_from` is None, it will resume the latest checkpoint in the `work_dir`.
イテレーションベースの設定¶
MMEngineのランナーは、エポックベースのトレーニングループに加えて、イテレーションベースのトレーニングループも提供します。イテレーションベースのトレーニングを使用するには、ユーザーはtrain_cfg
、param_scheduler
、train_dataloader
、default_hooks
、およびlog_processor
を変更する必要があります。これは、エポックベースのRetinaNet設定をイテレーションベースに変更する例です。configs/retinanet/retinanet_r50_fpn_90k_coco.py
# Iter-based training config
train_cfg = dict(
_delete_=True, # Ignore the base config setting (optional)
type='IterBasedTrainLoop', # Use iter-based training loop
max_iters=90000, # Maximum iterations
val_interval=10000) # Validation interval
# Change the scheduler to iter-based
param_scheduler = [
dict(
type='LinearLR', start_factor=0.001, by_epoch=False, begin=0, end=500),
dict(
type='MultiStepLR',
begin=0,
end=90000,
by_epoch=False,
milestones=[60000, 80000],
gamma=0.1)
]
# Switch to InfiniteSampler to avoid dataloader restart
train_dataloader = dict(sampler=dict(type='InfiniteSampler'))
# Change the checkpoint saving interval to iter-based
default_hooks = dict(checkpoint=dict(by_epoch=False, interval=10000))
# Change the log format to iter-based
log_processor = dict(by_epoch=False)
設定ファイルの継承¶
config/_base_
の下には、dataset、model、schedule、default_runtimeの4つの基本コンポーネントタイプがあります。Faster R-CNN、Mask R-CNN、Cascade R-CNN、RPN、SSDなど、これらのモデルのいずれかで多くのメソッドを簡単に構築できます。_base_
からのコンポーネントで構成された設定は、プリミティブと呼ばれます。
同じフォルダーの下のすべての設定では、1つのプリミティブ設定のみを持つことをお勧めします。他のすべての設定は、プリミティブ設定から継承する必要があります。このようにすると、継承レベルの最大値は3になります。
理解を容易にするために、コントリビューターが既存の方法から継承することをお勧めします。たとえば、Faster R-CNNに基づいていくつかの変更を加える場合、ユーザーは最初に_base_ = ../faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py
を指定して基本的なFaster R-CNN構造を継承し、次に設定ファイルで必要なフィールドを変更できます。
既存のメソッドのいずれとも構造を共有しないまったく新しいメソッドを構築する場合は、configs
の下にフォルダーxxx_rcnn
を作成できます。
詳細なドキュメントについては、mmengine設定チュートリアルを参照してください。
_base_
フィールドを設定することで、現在の設定ファイルがどのファイルから継承されるかを設定できます。
_base_
がファイルパスの文字列である場合、1つの設定ファイルから内容を継承することを意味します。
_base_ = './mask-rcnn_r50_fpn_1x_coco.py'
_base_
が複数のファイルパスのリストである場合、複数のファイルから継承することを意味します。
_base_ = [
'../_base_/models/mask-rcnn_r50_fpn.py',
'../_base_/datasets/coco_instance.py',
'../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]
設定ファイルの内容を確認したい場合は、python tools/misc/print_config.py /PATH/TO/CONFIG
を実行して、完全な設定を確認できます。
ベース設定の一部のフィールドを無視する¶
場合によっては、ベース設定の一部のフィールドを無視するために _delete_=True
を設定することがあります。簡単な例については、mmengine 設定チュートリアルを参照してください。
例えば、MMDetection では、次の設定で Mask R-CNN のバックボーンを変更するには、
model = dict(
type='MaskRCNN',
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',
init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')),
neck=dict(...),
rpn_head=dict(...),
roi_head=dict(...))
ResNet
と HRNet
は、構築に異なるキーワードを使用します。
_base_ = '../mask_rcnn/mask-rcnn_r50_fpn_1x_coco.py'
model = dict(
backbone=dict(
_delete_=True,
type='HRNet',
extra=dict(
stage1=dict(
num_modules=1,
num_branches=1,
block='BOTTLENECK',
num_blocks=(4, ),
num_channels=(64, )),
stage2=dict(
num_modules=1,
num_branches=2,
block='BASIC',
num_blocks=(4, 4),
num_channels=(32, 64)),
stage3=dict(
num_modules=4,
num_branches=3,
block='BASIC',
num_blocks=(4, 4, 4),
num_channels=(32, 64, 128)),
stage4=dict(
num_modules=3,
num_branches=4,
block='BASIC',
num_blocks=(4, 4, 4, 4),
num_channels=(32, 64, 128, 256))),
init_cfg=dict(type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w32')),
neck=dict(...))
_delete_=True
は、backbone
フィールド内のすべての古いキーを新しいキーで置き換えます。
設定ファイルで中間変数を使用する¶
一部の中間変数は、データセットの train_pipeline
/ test_pipeline
のように、設定ファイルで使用されています。子設定で中間変数を変更する場合、ユーザーは対応するフィールドに中間変数を再度渡す必要があることに注意してください。たとえば、マルチスケール戦略を使用して Mask R-CNN をトレーニングしたいとします。train_pipeline
/ test_pipeline
は、変更したい中間変数です。
_base_ = './mask-rcnn_r50_fpn_1x_coco.py'
train_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations', with_bbox=True, with_mask=True),
dict(
type='RandomResize', scale=[(1333, 640), (1333, 800)],
keep_ratio=True),
dict(type='RandomFlip', prob=0.5),
dict(type='PackDetInputs')
]
test_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='Resize', scale=(1333, 800), keep_ratio=True),
dict(
type='PackDetInputs',
meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',
'scale_factor'))
]
train_dataloader = dict(dataset=dict(pipeline=train_pipeline))
val_dataloader = dict(dataset=dict(pipeline=test_pipeline))
test_dataloader = dict(dataset=dict(pipeline=test_pipeline))
まず、新しい train_pipeline
/ test_pipeline
を定義し、それらをデータローダーフィールドに渡します。
同様に、SyncBN
から BN
または MMSyncBN
に切り替えたい場合は、設定内のすべての norm_cfg
を置き換える必要があります。
_base_ = './mask-rcnn_r50_fpn_1x_coco.py'
norm_cfg = dict(type='BN', requires_grad=True)
model = dict(
backbone=dict(norm_cfg=norm_cfg),
neck=dict(norm_cfg=norm_cfg),
...)
_base_ ファイルで変数を再利用する¶
ベースファイルで変数を再利用したい場合、{{_base_.xxx}}
を使用して対応する変数のコピーを取得できます。例えば
_base_ = './mask-rcnn_r50_fpn_1x_coco.py'
a = {{_base_.model}} # Variable `a` is equal to the `model` defined in `_base_`
スクリプト引数で設定を変更する¶
tools/train.py
または tools/test.py
を使用してジョブを送信するときは、--cfg-options
を指定して設定をその場で変更できます。
辞書チェーンの設定キーを更新します。
設定オプションは、元の設定の辞書キーの順序に従って指定できます。たとえば、
--cfg-options model.backbone.norm_eval=False
は、モデルバックボーン内のすべての BN モジュールをtrain
モードに変更します。設定のリスト内のキーを更新します。
一部の設定辞書は、設定内でリストとして構成されています。たとえば、トレーニングパイプライン
train_dataloader.dataset.pipeline
は通常、[dict(type='LoadImageFromFile'), ...]
のようなリストです。パイプラインで'LoadImageFromFile'
を'LoadImageFromNDArray'
に変更する場合は、--cfg-options data.train.pipeline.0.type=LoadImageFromNDArray
を指定できます。リスト/タプルの値を更新します。
更新する値がリストまたはタプルである場合。たとえば、設定ファイルでは通常、
model.data_preprocessor.mean=[123.675, 116.28, 103.53]
が設定されています。平均値を変更する場合は、--cfg-options model.data_preprocessor.mean="[127,127,127]"
を指定できます。引用符"
は、リスト/タプルデータ型をサポートするために必要であり、指定された値の中に空白は許可されていません。
設定ファイル名のスタイル¶
設定ファイルの名前付けには、以下のスタイルに従います。コントリビューターは同じスタイルに従うことをお勧めします。
{algorithm name}_{model component names [component1]_[component2]_[...]}_{training settings}_{training dataset information}_{testing dataset information}.py
ファイル名は 5 つの部分に分かれています。すべての部分とコンポーネントは _
で接続され、各部分またはコンポーネントの単語は -
で接続される必要があります。
{algorithm name}
: アルゴリズムの名前。これは、faster-rcnn
、mask-rcnn
などの検出器名にすることができます。または、soft-teacher
、lad
などの半教師ありまたは知識蒸留アルゴリズムにすることもできます。{model component names}
: バックボーン、ネックなど、アルゴリズムで使用されるコンポーネントの名前。たとえば、r50-caffe_fpn_gn-head
は、アルゴリズムで caffe スタイルの ResNet50、FPN、および Group Norm を使用した検出ヘッドを使用することを意味します。{training settings}
: バッチサイズ、拡張、損失トリック、スケジューラー、エポック/イテレーションなどのトレーニング設定の情報。たとえば、4xb4-mixup-giou-coslr-100e
は、8-gpus x 4-images-per-gpu、mixup 拡張、GIoU 損失、コサインアニーリング学習率を使用し、100 エポックトレーニングすることを意味します。いくつかの略語{gpu x batch_per_gpu}
: GPU と GPU あたりのサンプル数。bN
は、GPU あたりの N バッチサイズを示します。たとえば、4xb4
は、4-GPUs x 4-images-per-GPU の短縮形です。また、8xb2
は、言及されていない場合はデフォルトで使用されます。{schedule}
: トレーニングスケジュール。オプションは、1x
、2x
、20e
などです。1x
および2x
は、それぞれ 12 エポックと 24 エポックを意味します。20e
は、カスケードモデルで採用されており、20 エポックを示します。1x
/2x
の場合、初期学習率は 8/16th および 11/22th エポックで 10 分の 1 に減衰します。20e
の場合、初期学習率は 16 番目と 19 番目のエポックで 10 分の 1 に減衰します。
{training dataset information}
:coco
、coco-panoptic
、cityscapes
、voc-0712
、wider-face
のようなトレーニングデータセット名。{testing dataset information}
(オプション): 1 つのデータセットでトレーニングされたが、別のデータセットでテストされたモデルのテストデータセット名。言及されていない場合は、モデルが同じデータセットタイプでトレーニングおよびテストされたことを意味します。