[Object Detection] MMDetection
대회 초반 사용했던 라이브러리. config 파일 형식으로 파이썬 스크립트로 구성된 프로젝트인데, 생소했지만 실제로 연구소나 현업에서 딥러닝 프로젝트는 대부분 config 파일의 형식으로 이루어진다고 한다.
https://github.com/open-mmlab/mmdetection
GitHub - open-mmlab/mmdetection: OpenMMLab Detection Toolbox and Benchmark
OpenMMLab Detection Toolbox and Benchmark. Contribute to open-mmlab/mmdetection development by creating an account on GitHub.
github.com
open-mmlab의 mmdetection 공식 레포지토리.
mmdetection
├── configs
│ ├── _base_
│ │ ├── datasets
| │ │ ├── coco_detection.py
| │ │ ├── ...
│ │ ├── models
| │ │ ├── faster_rcnn_r50_fpn.py
| │ │ ├── ...
│ │ ├── schedules
| │ │ ├── schedule_1x.py
| │ │ ├── ...
│ │ ├── default_runtime.py
| |
│ ├── faster_rcnn
| │ ├── faster_rcnn_r50_fpn_1x_coco.py
| │ ├── ...
│ ├── mask_rcnn
│ ├── ...
MMDetection의 config 디렉토리 구조는 다음과 같다.
_base_ 파일 내에 datasets, models, schedules 세 폴더가 존재하며 default_runtime.py 파이썬 파일이 존재한다.
Datasets
datasets 내에는 coco_detection을 비롯한 여러 파일이 존재하는데 datasets의 파이프라인을 지정할 수 있다.
공식 문서에는 datasets의 파이프라인을 다음과 같이 나타내는데, 이 파이프라인 순서를 따른 데이터의 가공 과정이 coco_detection.py를 비롯해 여러 task에 사용될 수 있게끔 만들어져 있다. 자신만의 datasets을 만들고자 하면 이 형식에 맞추어 data_root만 변경하거나, 다른 augmentation을 적용해서 데이터셋을 구성할 수 있다.
dataset_type = 'CocoDataset'
data_root = 'data/coco/'
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
train_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations', with_bbox=True),
dict(type='Resize', img_scale=(1333, 800), 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=(1333, 800),
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']),
])
]
예를 들어 coco_detection.py 파일에서 train data와 test data는 다음과 같이 이루어져 있다. data_root를 기존에 존재하는 data/coco내의 이미지를 가져오고, normalization을 진행할 파라미터를 설정 후 Image, annotation을 로드한 후 Resize, RandomFlip, Normalize, Pad를 진행한다. 여기서 train data에 대한 추가 augmentation을 진행하고 싶다면 train_pipeline 리스트 내에 dict(type = "설정하고자 하는 augmentation" , 설정 인자) 형식으로 추가하면 된다. 사용 가능한 augmentation 종류는 공식 문서에서 확인할 수 있으며 type=" " 형식으로 이루어진다.
사용하고자 하는 데이터 파일들은 data_root에서 파일의 위치를 설정해서 정할 수 있다.
나 같은 경우는 해당 대회의 쓰레기 이미지 파일들이 저장되어 있는 datasets/train 파일 루트를 지정해서 trash_detection.py를 만들고, 적용하고자 하는 내용에 따라 변경하며 사용했다.
Models
models 폴더 내에는 사용할 수 있는 다양한 모델의 파일이 존재한다. 실제로 PyTorch를 통해 구현된 모델이 아닌, configs 형식으로 dict 타입으로 여러 인자를 조정할 수 있다.
다양한 모델들의 파일 이름은
{model}_[model setting]_{backbone}_{neck}_[norm setting]_[misc]_[gpu x batch_per_gpu]_{schedule}_{dataset}
다음과 같이 매우 길게 정해지는데,
{} 중괄호는 필수적으로 적힌 항목이며 [] 대괄호는 선택형이다.
{model} : faster_rcnn과 같은 모델의 이름이다.
[model_setting] : 일부 모델의 세부 설정으로, 선택이다.
{backbone} : 모델의 전신으로 r50 (ResNet50), x101(ResNeXt101) 등으로 정해진다.
{neck} : 모델의 neck으로 fpn, pafpn, c4등이 있다.
[norm_setting] 기본적으로 배치 정규화를 사용한 bn이며 Group Normalization, Synchronized BN 등의 다른 정규화를 사용한 경우 적는다.
[misc] : 다양한 추가사항을 적는다.
[gpu x batch_per_gpu] : GPU의 개수와 GPU당 sample로 8x2가 기본이다.
{schedule} : 1x는 12epoch, 2x는 24epoch이며 lr이 각 8/16번째, 11/22번째에서 1/10으로 줄어드는 스케쥴링을 한다.
{dataset} : 모델을 pre-trained할 때 사용된 데이터셋을 나타내는 부분으로 coco, cityscapes, voc_0712등이 있다.
여기서 한 가지 파일의 예시를 들면
configs/_base_/models/faster_rcnn_r50_fpn.py
이고 이 파일은 faster_rcnn을 사용했고 fpn의 neck를 사용했다.
파일의 예시를 들어보면
# model settings
model = dict(
type='FasterRCNN',
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(
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)),
....
첫 부분이 다음과 같은 형식으로 이루어져 있다.
backbone, neck, rpn_head등과 roi_head, 그리고 train 과정에서 사용할 iou threshold등을 지정할 수 있으며 이는 모두 dict 타입으로 받게 된다.
type : Faster R-CNN의 모델이며
backbone : Batch Normalization으로 PyTorch 형식으로 torchvision의 resnet50의 pre-trained 모델을 가져온다
neck : FPN을 사용했으며 in_channels, out_channels, num_outs를 지정한다.
head : rpn_head, roi_head등을 사용한다.
Schedules
schedule_1x.py
schedule_20e.py
schedule_2x.py
세 가지가 기본적으로 있으며
1x = 12epoch, 2x = 24epoch, 20e = 20epoch를 의미한다.
schedule_1x.py를 보면
# optimizer
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)
# learning policy
lr_config = dict(
policy='step',
warmup='linear',
warmup_iters=500,
warmup_ratio=0.001,
step=[8, 11])
runner = dict(type='EpochBasedRunner', max_epochs=12)
기본적으로 SGD optimizer를 사용하며 lr = 0.02, momentum = 0.9, weight_decay = 0.0001이다.
lr_config를 통해 스케쥴러를 지정할 수 있다. 위 파일에서는 학습 중 동적 learning rate를 step으로 지정했으며 warmup은 linear하게 적용한다.
default_runtime.py
checkpoint_config = dict(interval=1)
# yapf:disable
log_config = dict(
interval=50,
hooks=[
dict(type='TextLoggerHook'),
# dict(type='TensorboardLoggerHook')
])
# yapf:enable
custom_hooks = [dict(type='NumClassCheckHook')]
dist_params = dict(backend='nccl')
log_level = 'INFO'
load_from = None
resume_from = None
workflow = [('train', 1)]
# disable opencv multithreading to avoid system being overloaded
opencv_num_threads = 0
# set multi-process start method as `fork` to speed up the training
mp_start_method = 'fork'
# Default setting for scaling LR automatically
# - `enable` means enable scaling LR automatically
# or not by default.
# - `base_batch_size` = (8 GPUs) x (2 samples per GPU).
auto_scale_lr = dict(enable=False, base_batch_size=16)
default_runtime의 경우 학습을 진행하며 로깅을 지정한다. wandb 로거를 지원해주기에 해당 파일에 wandb 로깅 코드를 따로 적용했고, 그를 통해 실험들을 wandb에 기록할 수 있었다.
Reference
https://greeksharifa.github.io/references/2021/09/05/MMDetection02/
Python, Machine & Deep Learning
Python, Machine Learning & Deep Learning
greeksharifa.github.io
https://mmdetection.readthedocs.io/en/latest/
Welcome to MMDetection’s documentation! — MMDetection 3.0.0 documentation
Docs > Welcome to MMDetection’s documentation! 以中文阅读 Shortcuts
mmdetection.readthedocs.io