Detectron2での転移学習 with カスタムデータ(自作データ)&データ拡張の作業手順

In deep learning tasks, it's essential to define three key components: 'training data', 'data augmentation', and 'training methods'.


設定ファイルDetectron2では,どのモデルやどのパラメータ(重み+バイアス)を使うか+ハイパーパラメータなどをファイル(yamlファイル形式が採用されています.configsディレクトリに実践的なサンプルあり.要するに設定ファイル.)に記載して,それを読み込み学習を実施するための標準的なスクリプト(train_net.py)が用意されています.デフォルトのtrain_net.pyでは,学習データの登録処理が含まれてなかった(どこかにサンプルプログラムを置いてくれてるかもしれません)ので,こちら+これに,その処理過程を加え,学習データの場所を引数で指定可能なスクリプトに改良した.


訓練:train_net.py(学習データの登録(--dataset_rootでの指定.学習データの場所(train,valのディレクトリ(COCOデータセットの構成で)を有す)を指定.valも指定?した方がいい(学習後にvalデータで性能評価するプログラムになっている(train_net.py))+学習環境設定の読み込み(--config-fileでの指定))の実行となります.データ拡張用のtrain_net.pyはこちら.説明はこちら,チュートリアルはこちら.ビルトインのデータ拡張内容はこちら.

python tools/train_net.py --config-file configs/COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x_custom.yaml --dataset_root ./datasets/watanabe/ --output_dir ./output/watanabe

評価:学習済みモデル(重みとバイアス)を指定して性能評価を行う.なお,デフォルトでは,数量的な評価結果(mAPとか)しか出力されないので,推論画像も保存するように改変した(here).評価結果の解釈はこちら

python tools/train_net.py --config-file configs/COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x_custom.yaml --dataset_root datasets/watanabe --eval-only MODEL.WEIGHTS output/watanabe/model_0159999.pth --output_dir output/watanabe/

推論:なお,学習後の重みによる推論は,demo/demo.pyを利用します(configファイル(設定ファイル)は例えばこれに変わる).例えば

python demo/demo.py --config-file configs/COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x_custom_test.yaml --input datasets/val/JPEGImages/out1_0460_s.jpg --output datasets/result --opts MODEL.WEIGHTS output/model_0244999.pth

なお,学習データの登録は,こちらのpythonスクリプトが有効かもしれません.
学習の評価は

tensorboard --logdir=/home/survey/Desktop/detectron2_wkk-local_version/output/SETO_v1

なお,これは,

tensorboard --logdir=/path/to/old_output_dir --port=6007

このようにして指定してもいい. log_tensorboard2.jpg

1. カスタム(自作)データの設定:**

扱うデータのセットの方法(書式,ディレクトリ構成など)についてはここを参考にしてください。
なお,Detectron2の使用では,register_coco_instancesで学習データの登録が前提のようです.
それ用のpythonスクリプト(ここのregister_custom_dataset.py)を作りました.
その前にlabelme(他のアプリでもいいが,われわれの研究室ではlabelmeを使用)で作成したannotaionファイル(jsonファイル)と画像をtrain用,val用,test用に分ける.8:1:1程度か?
trainvaltest2.png
学習させるデータセットが重そうならば,こちら(ここのresize.py(labelme用です))を使って画像サイズを変更しておくといいです.

入力用にCOCOフォーマットへの変換***

上のような構成において,それぞれのディレクトリでlabelme2coco.pyでcocoフォーマットへ変換する.
コマンドは以下のような感じ.labelmeのディレクトリにおいて実行.

python examples/instance_segmentation/labelme2coco.py /mnt/c/Users/keikan2/Desktop/labelme_reconst/train_input /mnt/c/Users/keikan2/Desktop/labelme_reconst/train --labels /mnt/c/Users/keikan2/Desktop/labelme_reconst/labels.txt

なお,labels.txtは,下のような表記.上2つ(__ignore__,_background_)は必ず書くのだと思ってます.

__ignore__
_background_
Hakusenn

下のように処理されていく
lm_pr.png
最終的に下のようになり,目的とするannotaions.jsonができる.同様に,val,testも処理する.Detectron2の学習段階では,testは求められない.
fin_lm.png
なお,datasetsというディレクトリはDetectron2にはない(detectron2/dataにある?)ので作っておく,
tree2.jpg

Cityscapes***

Cityscapesのfineレベルのデータから、poleとbuildingのクラスをインスタンス化するためには、cityscapesscriptsを使用します。以下は一般的な手順です。
cityscapesscriptsのjson2instanceImg.pyでいけるようです.
ただし,helpers/labels.pyでhasInstanceでインスタンス化したい対象(ここではpoleとbuilding)をTrueにしておかねばなりません.
(車や道路などはdefaultでインスタンス化されてます.poleやbuildingはされてません)
Terminalにおいて
PYTHONPATHの設定(export PYTHONPATH="${PYTHONPATH}:/my/new/path" )後に
python json2instanceImg.py /mnt/c/Users/survey/Desktop/CITYSCAPES_DATASET/gtFine_trainvaltest/gtFine/train/aachen/aachen_000000_000019_gtFine_polygons.json /mnt/c/Users/survey/Desktop/CITYSCAPES_DATASET/gtFine_trainvaltest/gtFine/train/aachen/aachen_000000_000019_gtFine_polygons22345.png

	#!/bin/bash
	# Root directory where your json files are stored
	root_dir="/mnt/c/Users/survey/Desktop/CITYSCAPES_DATASET_pole_building/gtFine_trainvaltest/gtFine/"
	# Iterate over train, val and test directories
	for data_split in train val test
	do
	  # Iterate over each city directory in the data split
	  for city in $(ls $root_dir/$data_split)
	  do
		# Get the city directory path
		city_dir="$root_dir/$data_split/$city"
		# Iterate over each json file in the city directory
		for json_file in $city_dir/*_polygons.json
		do
		  # Construct the png filename from the json filename
		  png_file="${json_file%_polygons.json}_instanceIds.png"
		  # If png file already exists, delete it
		  if [ -f "$png_file" ]; then
			rm $png_file
		  fi
		  # Run the python script
		  python json2instanceImg.py $json_file $png_file
		done
	  done
	done

このスクリプトはCityscapesデータセットの全部の画像(というかjsonファイル)に対して適用されます。poleとbuildingのインスタンスだけが訓練データとして扱われ、他のすべてのインスタンスは無視されます。
どうやら,labelTrainIds.pngは,自分で作成する必要があるようです.ここに書いてました.
CITYSCAPES_DATASET=/path/to/abovementioned/cityscapes python cityscapesscripts/preparation/createTrainIdLabelImgs.py
CITYSCAPES_DATASET=datasets/CITYSCAPES_DATASET_pole_building/gtFine_trainvaltest python cityscapesscripts/preparation/createTrainIdLabelImgs.py

Custom data***

Cocoフォーマットにしておく。
labelmeならlabelme2cocoを使うことができるようです.

python ./labelme2coco.py data_annotated data_dataset_coco --labels labels.txt

ただし,デフォルトだとclass idが0になってしまうので,ソースの改変が必要か?
COCOフォーマットのデータセットを登録する際には、アノテーションファイル(annotations.json)と画像が存在するディレクトリ(JPEGImages)のパスが正しいことを確認してください。また、"thing_classes"で指定するクラスの名前は、アノテーションファイル内で使用されているものと一致していなければなりません。

2. 転移学習:**

Mask R-CNN+Cityscapes***

まずは,ここを参考にするべきか
次に、Detectron2のMask R-CNNを使用して転移学習を行います。Cityscapesの学習済みモデルを使用し、上記で作成した教師データに対して学習します。
./train_net.py \ --config-file ../configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml \ --num-gpus 1 SOLVER.IMS_PER_BATCH 2 SOLVER.BASE_LR 0.0025~
Getting Started with Detectron2では,上記のようにかかれているが,cityscapesならばconfigsファイルは
configs/Cityscapes/mask_rcnn_R_50_FPN.yamlを適用するのでは?
そして,yamlファイルにOUTPUT_DIR: "checkpoints/model"を追記.しなければ学習後の重みは保存されない

export CUDA_VISIBLE_DEVICES=0,1 
python train_net.py --config-file ../configs/Cityscapes/mask_rcnn_R_50_FPN_TL.yaml --num-gpus 1 SOLVER.IMS_PER_BATCH 2 SOLVER.BASE_LR 0.0025

この下は転移学習の方法の一例で,実行はしてないです.

	from detectron2.data.datasets import register_coco_instances
	from detectron2.engine import DefaultTrainer
	from detectron2.config import get_cfg
	from detectron2 import model_zoo
	# 教師データセットの登録
	register_coco_instances("my_dataset_train", {}, "path_to_your_dataset.json", "path_to_your_images")
	# 設定の準備
	cfg = get_cfg()
	# Mask R-CNNの設定
	cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))
	# Cityscapesの学習済みモデルを使用
	cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
	# 新たな教師データセットの指定
	cfg.DATASETS.TRAIN = ("my_dataset_train",)
	# 学習の開始
	trainer = DefaultTrainer(cfg)
	trainer.resume_or_load(resume=False)
	trainer.train()

ここでの主なポイントは、設定(cfg)においてCityscapesの学習済みモデル(重み)を指定し、新たに作成した(カスタム)教師データセットを訓練データとして指定することです。

このパイプラインは非常に基本的なものであり、多くの設定や詳細が省略されています。Detectron2とcityscapesscriptsの公式ドキュメンテーションを確認して、より詳細な設定を行ってください。また、データのパス、設定のパラメータ等はあなたの環境に合わせて適宜修正してください。

Faster R-CNN+Custom Data***

Detectron2のFaster R-CNNを利用.
だから,ひとまずはmodel zooを見よう.
config file:configs/COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x.yaml
weights:model_weights/model_final_68b088.pkl
ここはまだ編集中です.

export CUDA_VISIBLE_DEVICES=0,1 
python train_net.py --config-file ../configs/COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x.yaml --num-gpus 1 SOLVER.IMS_PER_BATCH 2 SOLVER.BASE_LR 0.0025 --opts MODEL.WEIGHTS ../checkpoints/model_final_be35db.pkl

panoptic***

ここはまだ編集中です.

export CUDA_VISIBLE_DEVICES=0,1 
python train_net.py --config-file ../configs/Misc/panoptic_fpn_R_101_dconv_cascade_gn_3x.yaml --num-gpus 1 SOLVER.IMS_PER_BATCH 2 SOLVER.BASE_LR 0.0025 --opts MODEL.WEIGHTS ../model_weights/model_final_68b088.pkl

3. データ拡張:**

どうやら,detectron2の訓練での初期設定は,detectron2/data/detection_utils.pyに書かれているようです.そして,水平反転(鉛直反転)の設定をコントロールしているのが,detectron2/data/transforms/augmentation_impl.pyに書かれているclass RandomFlip(Augmentation):のようです(確率は0.5,水平反転が優先).

Cityscapes


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS