LoginSignup
4
5

More than 3 years have passed since last update.

DeepLabv3+を自前のデータセットで学習させる

Last updated at Posted at 2020-10-10

DeepLabv3+をオリジナルデータセットでトレーニングできます。
TensorFlow公式モデルをつかいます。
DeepLabの使い方は基本的に公式リポジトリに書いてあります。
わからないところがあったらこの記事など読んでください。

2011_002953.jpg 2011_002953.png
画像はPASCAL VOCデータセットですが、自分のデータセットでもちゃんとトレーニングできます。

手順

1、モデル、モジュールを設定

1、公式モデルリポジトリをクローン

git clone https://github.com/tensorflow/models
2、researchディレクトリで作業します。
cd models/research
3、Colabで作業する場合はTensorFlow1を選択。

%tensorflow_version 1.x
4、tf_slimをインストール。

pip install tf_slim

必要なモジュールは、
Numpy
Pillow 1.0
tf Slim (which is included in the "tensorflow/models/research/" checkout)
Jupyter notebook
Matplotlib
Tensorflow
です。入れてない場合はインストールしてください。

5、tensorflow / models / research /ディレクトリをPYTHONPATHに追加して、ライブラリを使えるようにする。

# tensorflow/models/research/ から実行
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim

*ちなみに、Colabのパスの通し方がわからなかったので、僕はスクリプトのfrom deeplab.。。。import 。。。のdeeplabの部分を全部消しました。。。
あと、research/slimからnetをdeeplabに移動させました。。。

2、データを用意する

以下を用意します。

1、元画像

2011_002997.jpg

2、ラベル画像

2011_002997.png
輪郭線はあってもなくてもかまいません。

・画像要件

・それぞれディレクトリにまとめる。
 元画像のディレクトリ名:JPEGImage
 ラベル画像のディレクトリ名:SegmetationClass
・元画像とラベル画像の数と名前(拡張子抜きの名前)は同じにする
・画像サイズは任意。トレーニング時に513,513にクロップされることを念頭に。
(画像全体を収めたい場合は513,513以下を推奨)

セグメンテーションデータ作りにはlabelmeなどのツールが使えるそうです。

3、データを前処理する

1、ラベル画像がカラーの場合は白黒のラベル画像にします。

input_dir = "{データセットのパス}/SegmentationClass"
mkdir "{データセットのパス}/SegmentationClassRaw"
output_dir = "{データセットのパス}/SegmentationClassRaw" # SegmentationClassRawディレクトリを作っておく

python deeplab/datasets/remove_gt_colormap.py \
 --original_gt_folder=input_dir \
 --output_dir=output_dir

SegmentationClassRawディレクトリに白黒に変換した画像が保存されます。
小さなラベル値の白黒画像になるので、ほぼ真っ黒です。

2、画像ファイル名一覧のテキストファイルを作ります。

image0
image1
image3

という拡張子抜きの形式で、ファイル名一覧のテキストファイルを作ります。
以下の3テキストファイルを作ります。
1、trainval.txt :全画像ファイル名
2、train.txt :trainval.txtのうち、トレーニング用セット(全ファイルの9割くらいを割り当てる?)
3、val.txt :trainval.txtのうち、内検証用セット(全ファイルの1割くらいを割り当てる?)

トレーニングと検証の割り振りは、最適なバランスは諸説あるようです。

テキストの抜き出し方はこちらの記事など参考にしてください。
ファイル名一覧をテキスト(.txt)ファイルに書き込む【Python】

3、データセットをTFRecord形式にします。

TensorFlowでのトレーニングで効率的に読み込めるTFRcord形式にします。


python deeplab/datasets/build_voc2012_data.py \
  --image_folder="{データセットのパス}/JPEGImages" \
  --semantic_segmentation_folder="{データセットのパス}/SegmentationClassRaw" \
  --list_folder="{データセットのパス}//ImageSets/Segmentation" \
  --image_format="jpg" \
  --output_dir="{データセットのパス}/tfrecord/"

4、トレーニングの設定をする

1、deeplab/datasets/data_generator.pyを自前データに合わせて書き換えます。
data_generator.py

_PASCAL_VOC_SEG_INFORMATION = DatasetDescriptor(
    splits_to_sizes={
        'train': 4552, # トレーニングイメージファイル数に書き換える
        'train_aug': 10582, # そのままでOK
        'trainval': 5088, # 全イメージファイル数に書き換える
        'val': 536, # 検証イメージファイル数に書き換える
    },
    num_classes=21, # そのままでOK
    ignore_label=255, # そのままでOK
)
2、事前学習済みモデルをダウンロードします。

転移学習のために事前学習済みモデルの重みを使います。
公式リポジトリのリンクから好みのチェックポイントをダウンロードします。
MobileNetv2ベース(22MB)とXceptionベース(439MB)があります。

5、トレーニング

1、MobileNetv2バックボーンの場合

python deeplab/train.py --logtostderr \
   --training_number_of_steps=30000 \
   --train_split="train" \
   --model_variant="mobilenet_v2" \
   --output_stride=16 \
   --decoder_output_stride=4 \
   --train_crop_size="513,513" \
   --train_batch_size=1 \
   --dataset="pascal_voc_seg" \
   --tf_initial_checkpoint="{チェックポイントのパス}/deeplabv3_mnv2_pascal_train_aug/model.ckpt-30000" \
   --train_logdir="{データセットのパス}/checkpoint" \ # 先にチェックポイント書き込み先ディレクトリを作っておきます
   --dataset_dir="{データセットのパス}/tfrecord" \
   --fine_tune_batch_norm=false \ # CPUのみの場合は”true”
   --initialize_last_layer=true \
   --last_layers_contain_logits_only=false
2、Xception_65バックボーンの場合

python deeplab/train.py --logtostderr \
   --training_number_of_steps=30000 \
   --train_split="train" \
   --model_variant="xception_65" \
   --atrous_rates=6 \
   --atrous_rates=12 \
   --atrous_rates=18 \
   --output_stride=16 \
   --decoder_output_stride=4 \
   --train_crop_size="513,513" \
   --train_batch_size=1 \
   --dataset="pascal_voc_seg" \
   --tf_initial_checkpoint="{チェックポイントのパス}/deeplabv3_pascal_train_aug/model.ckpt" \
   --train_logdir="{データセットのパス}/checkpoint" \ # 先にチェックポイント書き込み先ディレクトリを作っておきます
   --dataset_dir="{データセットのパス}/tfrecord" \
   --fine_tune_batch_norm=false \ # CPUのみの場合は”true”
   --initialize_last_layer=true \
   --last_layers_contain_logits_only=false

1200秒(20分)に一回、チェックポイントが保存されます。save_interval_secsで保存インターバルを指定できます。トレーニング終了後も保存されます。

*参考結果

5000画像、30000エポック、MobileNetv2バックボーン、ColabGPUでトレーニングしたところ、1時間ぐらいでした。
セグメントしたい物体が一つ(2ラベル)だったせいか、結果は大満足でした。

6、テスト

検証セットを使ってテストします。

元画像とカラーセグメンテーションマップ画像がログディレクトリに保存されます。

python deeplab/vis.py --logtostderr \
  --vis_split="val" \
  --model_variant="mobilenet_v2" \
  --output_stride=16 \
  --decoder_output_stride=4 \
  --vis_crop_size="513,513" \
  --dataset="pascal_voc_seg" \
  --checkpoint_dir="{チェックポイントのパス}/checkpoint" \
  --vis_logdir="{結果画像の書き込み先ディレクトリパス(作っておく)}" \
  --dataset_dir="{データセットのパス}/tfrecord" \
  --max_number_of_iterations=1 --eval_interval_secs=0

vis3.png

凍結グラフにして保存する


python export_model.py --model_variant="mobilenet_v2" --checkpoint_path="{チェックポイントを保存したディレクトリ}/model.ckpt-30000" --export_path="{凍結グラフを保存するディレクトリ}/frozen_graph.pb"

🐣


お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

Twitter
Medium

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5