目次
Detectron2
- 設定ファイルベースで学習とかやるフレームワーク?
- 決定的?
- DDP の抽象化?
- Colab Tutorial をやっていくのが一番早い
概要
- 設定の作成
- コマンドライン引数
- 設定ファイル
- 設定をもとに実行
- どの順で関数が実行されるか?
- 学習インスタンスの生成
- Trainer
設定ファイルについて
以下のライブラリを順に継承して CfgNode クラスが作成されており、それをベースにしている。
CfgNodeの継承ツリー |
|
|---|---|
| yacs | yacs/yacs/config.py |
| fvcore | fvcore/fvcore/common/config.py |
| detectron2 | detectron2/detectron2/config/config.py |
設定内容(CfgNodeの中身)については
その後、
.merge_from_file().merge_from_list()
で調整して設定を作成する。
DDP の抽象化
- DDP をうまくやってくれる
detectron2.engine.launchからtorch.multiprocessingをいじってやってくれる。
コマンドライン引数について
以下のやつは argparse.ArgumentParser と同じ
from detectron2.engine import default_argument_parser default_argument_parser().parse_args()
子プロセス
detectron2/detectron2/utils/comm.py → で定義されている関数を使って子プロセスの諸々の情報を知ることができる。
import
from detectron2.utils import comm
GPU の ID を知る
comm.get_local_rank()
学習
学習インスタンス Trainer
detectron2/engine/defaults.pyのDefaultTrainerから始まる。
こいつに config を渡して.train()でやっていく。from detectron2.engine import DefaultTrainer
DefaultTrainer |
|
|---|---|
detectron2/detectron2/engine/train_loop.py → | class TrainerBase |
detectron2/detectron2/engine/defaults.py → | class DefaultTrainer |
DefaultTrainer の持っている .build_model() からモデルが作成される。
この .build_model() は detectron2/modeling/meta_arch/build.py の build_model() 関数の拡張。
コンストラクタ呼び出し時のふるまい
global : trainer = DefaultTrainer(config) DefaultTrainer: super().__init__() TrainerBase : self._hooks = [] TrainerBase : self.iter = 0 TrainerBase : self.start_iter = 0 DefaultTrainer: ... DefaultTrainer: model = self.build_model(cfg) ... DefaultTrainer: model = create_ddp_model(model, broadcast_buffer=False)
TrainerBase |
||
|---|---|---|
__init__ | inst. | superlly called |
register_hooks | inst. | |
before_train | inst. | |
after_train | inst. | |
before_step | inst. | |
after_step | inst. | |
train | inst. | superlly called |
run_step | inst. | just to be overrided |
state_dict | inst. | superlly called |
load_state_dict | inst. | superlly called |
DefaultTrainer |
||
__init__ | inst. | override |
resume_or_load | inst. | |
build_hooks | inst. | |
build_writers | inst. | |
train | inst. | override |
run_step | inst. | override |
state_dict | inst. | override |
load_state_dict | inst. | override |
build_model | class | |
build_optimizer | class | |
build_lr_scheduler | class | |
build_train_loader | class | |
build_test_loader | class | |
build_evaluator | class | |
test | class | |
auto_scale_workers | static | |
Trainer の重要メンバ
DefaultTrainer のメンバ。
_trainerは SimpleTrainerクラス。
TrainerBase を継承して DefaultTrainer が作成されている。
同じように SimpleTrainer も TrainerBase を継承して作成されている。
なので DefaultTrainer と SimpleTrainer は親子関係はないが、DefaultTrainer の _trainer というメンバは
SimpleTrainer なことがある。
- SimpleTrainer のメンバが直接触るべきモデル
model:GeneralizedRCNNとかmodel.backbone:
モデルデータベース Registry
Registry に登録されているモデルから拡張して作るのが普通っぽい。
# import from detectron2.modeling.meta_arch.build import META_ARCH_REGISTRY
Registry |
|
|---|---|
detectron2/detectron2/utils/registry.py → | Registry |
fvcore/fvcore/common/registry.py → | Registry |
detectron2/detectron2/modeling/meta_arch/ にあるモジュールで @META_ARCH_REGISTRY.register() というデコレータを使用して
いろいろなモデルアーキテクチャを登録している。
コードから登録されているアーキテクチャを追跡することは面倒だが、 @META_ARCH_REGISTRY デコレータが付いているものを確認すると以下のようになっている。
detectron2/modeling/meta_arch/retinanet.py RetinaNet
detectron2/modeling/meta_arch/panoptic_fpn.py PanopticFPN
detectron2/modeling/meta_arch/semantic_seg.py SemanticSegmentor
detectron2/modeling/meta_arch/rcnn.py GeneralizedRCNN
ProposalNetwork
BACKBONE_REGISTRY
detectron2/modeling/backbone/resnet.py build_resnet_backbone
detectron2/modeling/backbone/fpn.py build_resnet_fpn_backbone
build_retinanet_resnet_fpn_backbone
モデルが生成される過程
# detectron2/detectron2/engine/defaults.py # class DefaultTrainer method __init__ model = self.build_model( cfg ) # CfgNode # detectron2/detectron2/engine/defaults.py # class DefaultTrainer method build_model model = build_model(cfg) # detectron2/detectron2/modeling/metar_arch/build.py # detectron2.modeling function build_model meta_arch = cfg.MODEL.META_ARCHITECTURE model = META_ARCH_REGISTRY.get(meta_arch)(cfg) # detectron2/detectron2/utils/registry.py : redirect # detectron2.utils.registry class Registry : redirect # fvcore/fvcore/common/registry.py # fvcore.common.registry class Registry method get ret = self._obj_map.get(name) # _obj_map はただの dict、 ret は nn.Module # detectron2/detectron2/modeling/meta_arch/rcnn.py # class GeneralizedRCNN method __init__ with @configurable # detectron2/detectron2/config/config.py # detectron2.config function configurable from_config_func = type(self).from_config explicit_args = _get_args_from_config(from_config_func, *args, **kwargs) # detectron2/detectron2/config/config.py # function _get_args_from_config ret = from_config_func(*args, **kwargs) # detectron2/detectron2/modeling/meta_arch/rcnn.py # class GeneralizedRCNN method from_config backbone = build_backbone(cfg) # detectron2/detectron2/modeling/backbone/build.py # function build_backbone backbone_name = cfg.MODEL.BACKBONE.NAME backbone = BACKBONE_REGISTRY.get(backbone_name)(cfg, input_shape)
R-CNN
detectron2/modeling/meta_arch/rcnn.py の forward を見る。
だいたいこんな感じ
GeneralizedRCNN
images <- self.preprocess_image( batched_inputs )
features <- self.backbone( images.tensor )
proposals, proposal_losses <- self.proposal_generator( images, features, gt_instances )
_, detector_losses <- self.roi_heads( images, features, proposals, gt_instances )
データセット
自作データセット定義方法
完全自作の形式
from detectron2.data import DatasetCatalog DatasetCatalog.register('MyDataset', my_function )
特定の形式で登録する
detectron2.data.datasets にある関数
register_coco_instancesregister_coco_panopticregister_coco_panoptic_separatedregister_lvis_instancesregister_pascal_voc
取り出し
detectron2.data.common.AspectRatioGroupedDataset の __iter__ を見るべし
カスタムなデータローダーの定義
デフォルトでは detectron2/data/dataset_mapper.py の DatasetMapper が使われるため画像はファイルから読み込むしかできない。
データセットに合った特定の読み込み方を指定するには custom dataloader を作成する必要がある。
これらを見る限り、 DefaultTrainer の build_train_loader などのメソッドをオーバーライドするのが正攻法。
