今回の記事はTensorFlowでアノテーション付けした訓練データのTFRecordを既存モデル(今回はMobileNet)に転移学習させて、pbモデルを出力する手順に関しての記事です。初心者でもわかるように簡単に解説していきますので是非参考にして見て下さい。
TFRecordを既存モデルに転移学習させる環境構築
まずは転移学習を行う環境の構築をおこないます。「Object Detection API」の環境がすでにあることを前提に話を進めていきますのでまだ「Object Detection API」の環境構築が済んでいない方は下記記事を参考にローカルPC、またはDocker上などに環境の構築をして下さい。
「「Object Detection API」の環境構築をローカルPCに行う方法。」
「「Object Detection API」の環境構築をDocker上に行う方法。」
また、合わせてTFRecord形式の訓練データを作成する手順に関しても下記記事でアノテーションツールの使い方と共に記載しているので是非そちらも参考にして下さい。
「アノテーションツールVoTTでTFRecordを作成する手順ご紹介。」
「Object Detection API」の環境構築が済んでいる方は「/models/research/」のディレクトリで下記を実行してください。
git clone https://github.com/karaage0703/object_detection_tools
作成されたobject_detection_toolsに入ってみます。
cd object_detection_tools
中身の確認
tree
.
├── Dockerfile
├── LICENSE
├── README.md
├── colab_tutorials
│ ├── inference_from_saved_model.ipynb
│ └── inference_tf2_colab.ipynb
├── config
│ ├── centernet_hg104_512x512_coco17_tpu-8.config
│ ├── faster_rcnn_resnet101_pets.config
│ ├── ssd_inception_v2_coco.config
│ └── ssdlite_mobilenet_v2_coco.config
├── data
│ ├── change_tfrecord_filename.sh
│ ├── train
│ └── val
├── models
│ ├── get_centernet_hg104_512x512_coco17_tpu-8.sh
│ ├── get_efficientdet_d0_coco17_tpu-32.sh
│ ├── get_ssd_inception_v2_coco_model.sh
│ ├── get_ssd_mobilenet_v1_coco_model.sh
│ └── get_ssdlite_mobilenet_v2_coco_model.sh
└── scripts
├── convert_pbtxt_label.py
├── convert_rt_model.py
├── data_augmentation.ipynb
├── object_detection.py
└── object_detection_tf2.py
ずらっと格納されているようです。
「data」フォルダに注目します。下記記載の箇所にtfrecordを9:1くらいの割合で分けて入れます。
├── data
│ ├── change_tfrecord_filename.sh
│ ├── train 9対
│ └── val 1くらいで画像入れる
まずはTf-Recordの名前を変換してくれるスクリプトがシェルスクリプトが用意されているのでそれを利用します。
cd data
./change_tfrecord_filename.sh
名前編集された結果がずらっと表示されます。
これで環境構築は終了です。次に実際に学習させる工程に進んでいきます。
TFRecordを既存モデルに転移学習
次に転移学習する元の学習モデルを読み込みます。
cd .. && cd models
ls
coco-labels-paper.txt get_ssdlite_mobilenet_v2_coco_model.sh
get_ssd_inception_v2_coco_model.sh get_ssd_mobilenet_v1_coco_model.sh
中身はこんな感じです。
./get_ssd_inception_v2_coco_model.sh
inception_v2をインストールします。
もしかしたらmobilenetもあるようなのでそちらの方が携帯用にはいいのかもしれません。
気になる方は比較してみてください。
結構時間かかったのちに完了すれば確認しましょう。増えています。
ls
coco-labels-paper.txt get_ssdlite_mobilenet_v2_coco_model.sh
get_ssd_inception_v2_coco_model.sh ssd_inception_v2_coco_2018_01_28
get_ssd_mobilenet_v1_coco_model.sh
使用するconfigファイルssd_inception_v2_coco.configを必要に応じて修正して下さい。特にnum_classesはクラス数になるので、アノテーションしたラベルの数に合わせて修正して下さい。
model {
ssd {
num_classes: 1 今回はexitかどうかのみなのでクラス(ラベル)は1で設定
box_coder {
(以下省略)
これで準備は完了です。
以下のコードで学習を開始してください。
長いので貼り付けちゃってください。
saved_model_01というフォルダが作成されるのでその中に学習モデル入ってます。
cd /models/research
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
python object_detection/model_main.py --pipeline_config_path="./object_detection_tools/config/ssd_inception_v2_coco.config" --model_dir="./saved_model_01" --num_train_steps=10000 --alsologtostderr
ここで沼にはまりました。画像に関しては80枚程度あり学習に時間はかかることは分かっていたのですが学習最中のcheckpoint生成時に下記のようなerrorに引っかかっていました。どうやらメモリー要領が足りていないようでした。
(省略)
] Allocation of 138240000 exceeds 10% of system memory.
2020-07-18 22:05:49.332164: W tensorflow/core/framework/cpu_allocator_impl.cc:81] Allocation of 138240000 exceeds 10% of system memory.
Killed
このエラーがでていてもフォルダ内にファイルがいくつか生成されているのですがこのまま次のコードに進むとエラーになります。
解決方法は私の場合はDockerで作業していたのでDockerに付与しているメモリを上げて実行しました。Dockerのメモリを上げる方法は下記記事を参考ください。
ではエラーなく上記のコードを完了できたということで次に進みます。作成した「ckptファイル」をpb形式のtensorflowグラフに変換します。
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
python object_detection/export_inference_graph.py --input_type image_tensor --pipeline_config_path object_detection_tools/config/ssd_inception_v2_coco.config --trained_checkpoint_prefix saved_model_01/model.ckpt-[最新の番号記載] --output_directory exported_graphs
saved_model_01以下のmodel.ckptに関しては自身の生成されているckptファイルの後ろに共通して生成されている最新のものを記述ください。
これが成功すればexported_graphのフォルダにpbグラフが保存されています。後はアノテーションフォルダに一緒にはいっていたtf_label_map_pbtxtのファイルも同じフォルダに持っておけば便利なので持ってきました。
こちらで作成されたものは実はTensorFlow Liteに変換はできませんでした。TensorFlow Liteに変換する為のpbモデルを作成するためには別の変換用グラフ作成ファイルがあります。そのファイル実行が下記です。
そのため、下記にtfliteに変換する様のコードを記載しておきます。ckptの作成までは上記のコードと同じですのでそれをご参照ください。
models/research#python object_detection/export_tflite_ssd_graph.py --input_type image_tensor --pipeline_config_path [pipelineのpath] --trained_checkpoint_prefix [ckptのpath] --output_directory [出力先フォルダ] -add_postprocessing_op=true
これでTensorFlowLiteの形式に変換できるpbモデルの作成が完了しました。
2種類のpbファイルと作成用Pythonファイルまとめ
「export_inference_graph.py」
TensorFlow Lite変換非対応グラフ、Pythonコードでは動く。
「export_tflite_ssd_graph」
TensorFlow Lite変換対応グラフ、Pythonコードでは動かない・
要は今後の処理としてTensorFlow Liteに変換してエッジデバイスに組み込むなどの考えがある方とPythonのみで完結させる方によって使い分ける必要があります。学習で生成される「ckptファイル」も訓練データのTFRecordも使いまわせますので再度学習を行う必要はございません。その為、学習させた「ckptファイル」はしっかり保存しておきましょう。
では今回の記事は以上です。他にも多数の機械学習関連の記事を記載しているので是非興味があればサイト内をご確認ください。
コメント
[…] […]
[…] 【Python】TFRecord形式のデータをtflite形式用モデルに転移学習する方法。(pyth… […]
[…] […]
[…] […]