venvで作った仮想環境で、TensorFlowのObject Detection APIを試してみた(学習 ~ 検出迄)

こんにちは。技術研究所の910です。
今回は少々今更感がありますが、TensorFlowに実装されたTensorFlow Object Detection APIを試してみようと思います。

…とは言ったものの、How to train your own Object Detector with TensorFlow’s Object Detector APIに丁寧に手順がまとめられていますので、詳細なやり方についてはこちらの記事をご覧になるのが良いかと思います。
なのでこの記事では、このAPIを使うことで、どれだけ簡単に物体検出を試せるのかをご覧いただければと思います。

作業環境

前準備

Quick Start: Jupyter notebook for off-the-shelf inferenceにも書いてある通り、先にinstallationを済ませておく必要があります。

また、本記事の題名にもある通り、私はvenvで仮想環境を作って利用しております。
しかしvenvで作った仮想環境を使う場合、activateの度にPYTHONPATHを追加せねばならず、非常に面倒です。
そこで、こちらを参考にして、bin/activate内にPYTHONPATHの切り替え処理を追加しました。

これでactivate、deactivateの度にPYTHONPATHが切り替えられるようになりました。

データセットの作成

参考記事で紹介されているRaccoon Datasetを使い、TFRecords形式のデータセットを作成しました。
データの数こそ少ないですが、アライグマの可愛い画像がたくさん入っていますのでオススメです。笑

ちなみに、こちらのリポジトリでは画像データやアノテーションデータ(物体の位置やクラスラベルなどのメタデータ)の他、変換済みのTFRecords形式のデータセット、ckptファイルも公開されていますので、すぐに検出を行うこともできます。
しかし、今回は学習から検出まで全て試してみたかったので、敢えてTFRecordsファイルの作成から行いました。

また、データセットの作成にはデータセットの公開元が公開しているスクリプトを利用しました。

ファイル名 処理概要
xml_to_csv.py 指定ディレクトリ内のxmlを全件読み取り→単一のcsvとして吐き出し
generate_tfrecord.py csvの各行をExampleオブジェクトに詰めてTFRecordsファイルに書き込み

中身を見ると分かりますが、これらのスクリプトで行っていることは非常にシンプルなので、任意のデータを使いたい場合にも特に困ることはなさそうです。

設定ファイルと学習済みモデルの準備

学習を行う際に最低限必要なファイルは、モデルの構造や学習方法などを指定する為のconfigファイルと、クラスとIDを対応付けるファイルの2つとなります。
また上記のファイルに加え、転移学習させる為に、記事でオススメされているssd_mobilenet_v1_cocoも用意しました。

クラスとIDを対応付けるファイルの内容は参考記事に記載されている通り、以下のように設定しました。

configファイルも記事に従いssd_mobilenet_v1_pets.configを微修正して利用しました。
修正するに当たってはconfigファイルの概要protoファイルを見て、どんな設定ができるのか確認しながら進めていました。

configファイルを書換えた箇所は以下の通りです。元のconfigファイルと照らし合わせてご覧いただければと思います。

ちなみにprotoファイルを見る限り、評価の間隔やckptの吐き出しの間隔は時間単位でのみ指定できるようです。
本当はstep数で指定したかったので、ここだけはちょっと残念なところでした。。

学習

ファイルが用意できたら、以下のコマンドを叩けば学習が開始されます。
私はGPUを使わないで学習させたので、途中経過をTensorBoardで見ながら待ちました。
時間の都合上、ミニバッチサイズ24で100step回すという設定にしましたが、それでも35分ほど掛かりました。

学習が終わればそのままckptファイルを使って検出することも可能ですが、単一ファイルにまとまっていた方が何かと取り回しがし易いので、こちらに従ってpbファイルに固めました。

作成した学習済みモデルでの検出

pb形式に固めた学習済みモデルで検出を試してみました。
学習のstep数やデータの数の少なさから精度は期待できないと思いましたので、今回はCPU環境でどれだけの検出速度が出せるのかをチェックすることにしました。

検出に使用した動画データはNHKクリエイティブライブラリーで公開されているアライグマの動画となります。
当該動画の詳細はこんな感じです。

上記のログにも出ておりますが、この動画は1885フレームで構成されています。
FPSが29.97であるのに対し、1885フレーム / 309秒 = 6.100324フレーム/秒で検出を行えているので、検出する間隔を1/5に間引けば疑似的にリアルタイム処理が行えるということになります。
検出の間隔をある程度間引いてしまっていい場合ならば、充分実用に耐えるレベルの速度が出ているのではないでしょうか。

また、検出結果の動画を確認してみましたが、やはり全体的に検出の精度は悪くなってしまっていました。
以下の画像は最も良く検出できたフレームになりますが、他のフレームでは誤検出が多発していました。

しかし、結果を見た感じでは、データやstep数を増やせばまだまだ精度の向上が見込めるのではないかと考えています。

まとめ

ご覧いただいた通り、お試しレベルであれば非常に簡単に物体検出用の学習済みモデルを作ることができました。
これだけ簡単に試せてしまうとなると、やはり学習させる為の大量のデータをどう確保するのかが重要だな、と身に染みて感じました。

画像データならばスクレイピング等で集められますが、アノテーションデータはまだ人間の手で作る必要がありますので、今後アノテーションデータの作成の段階から試してみようと思います。