Tensorflowでライオンとネコを検出する

AI

はじめに

人気シリーズ、AIで「ねぎ」と「たまねぎ」を見極めよう!の次の企画を始めます。題して、AIでライオンとネコを検出する!です。

これまではTensorflow, Salesforce Einstein Visionといった、AIのフレームワークを用いて、「ねぎ」と「玉ねぎ」を見極めてきました。これらはImage Classificationと呼ばれる技術でした。今回はもう一段レベルを挙げて画像から特定の物体を検出するObject Detectionをやってみようと思います。

前提

CentOS7

環境構築

まずは環境構築から始めましょう。CentOSの場合、まずはpython3を入れるところからになります。

python3とライブラリの導入

Python3は次のようにすればインストールできます。

 

Python3がインストール出来たらモジュールもインストールしておきます。

 

Protocol Bufferコンパイラの導入

Protocol Bufferが何者であるかはこのWikiをご参照ください。(というか、私もこれで知った。)
Tensorflowで用いるグラフ定義はProtocol Bufferを用いてシリアライズされます。このためのコンパイラを導入する必要があります。
ただ、罠があるので気を付ける必要があります。
普通はyum searchで見つかったらそれを入れちゃいます。しかし、ここでインストールされるver.2xにはバグがあるようです。
なので、自分で正常に動くバイナリを持ってきましょう。

学習データの準備

学習用のデータを準備します。画像を集めるのは大変なので、今回は対象を動画で撮影したものから画像を抽出して学習データとしたいと思います。

1.動画の撮影

2.画像の抽出

3.ラベリング

1についてはスマホなどで動画を撮影してPCに取り込んでください。このiphoneやandroidでさくっっと撮影できると思いますので、説明は割愛します。以下、2と3の説明をします。

画像の抽出

動画から画像を抽出するのはffmpegを用いるのが簡単かと思います。学習用データに適した画像のサイズは使用するモデルによります。今回は’ssd_mobilenet_v2_coco’を用いる予定です。300×300のサイズが適しているようですので、300×300で画像を抽出したいと思います。

ffmpegで下記のコマンドを実行します。

-r で1秒あたりの画像抽出数を指定します。4だと0.25秒に1枚抽出します。また、scaleでアスペクト比を維持したまま高さを300pxにするように指定します。出力ファイル名はprintfフォーマットに似た感じで連番を付けれます。

ラベリング

画像に対してラベル付けをしていきます。いろいろと調べてみるとlabelImgが評判良さそうなので、これを使ってラベリングしていきます。

tzutalin/labelImg
:metal: LabelImg is a graphical image annotation tool and label object bounding boxes in images - tzutalin/labelImg

こんな感じで、さささっとできます。ショートカットは「w」で矩形の作成開始、「ctrl+s」で保存です。次のイメージに進むためのショートカットはなさそうですが、Next Imageボタンで同じディレクトリの次の画像に進むことができます。

モデル生成

モデルの作成を行います。
まずは、各種モデル作成ツールをgitから持ってきてセットアップします。

ProtoclBufferのビルド

cloneしたmodelの下に使用するプロトコルバッファの定義があるのでこれをコンパイルしておきます。

cocoapiのビルド

cocoapiをcloneしてきたら、ビルドします。
Makefileがpython3を使ってくれるよういなっていないので、Makefileのpython呼び出しの部分をpython36等に編集してからmakeします。
ビルドが終わったらcloneしたmodelsの下のresearchフォルダにコピーします。

データ変換ツールの準備

上記のObject Detectionのチュートリアルページのツールが便利なので、cloneしたmodelsのresearch/object_detectionフォルダにコピーしておきます。

モデルの取得

今回はssd_mobilenet_v2_cocoを使用します。
下記の通り、research/object_detection/にモデルを展開します。

学習データの振り分け

画像データとラベルデータを’images/train’と’images/test’に振り分けます。対応するxmlとjpgはimages/testかimages/trainのいずれかの同じフォルダに入れてください。

tfrecordの作成

チュートリアルのツールを使ってtfrecordを作成します。まずはcsvを作成してから、tfrecordを作成するという流れになります。ただし、tfrecord生成ツール(generate_tfrecord.py)はチュートリアル用に作成されているので、一部改変が必要です。具体的にはclass_text_to_int:の部分を検出したいものに変更する必要があります。ライオンと猫の場合は次のような感じ。

 

コマンドは次のように実行します。

トレーニングの設定

トレーニングの設定をします。設定ファイルはtrainingフォルダに置くことにします。
ひな形のconfigをコピーして編集してください。labelmap.pbtxtはtfrecordに記載した情報に合わせて記載してください。ssd_mobilenet_v2_coco.configは後述します。

 

labelmap.pbtxtは次のようになります。

 

ssd_mobilenet_v2_coco.configの設定

基本はクラス数と”PATH_TO_BE_CONFIGURED”書き換えを指示されているところを書き直せばいいです。
  • num_classes: 識別するクラス数。今回は2
  • fine_tune_checkpoint: 今回使うモデルのチェックポイント。今回は/home/xxx/models/research/object_detection/ssd_mobilenet_v2_coco_2018_03_29/model.ckpt
  • train_input_reader->input_path: トレーニング用のtfrecord。今回は/home/xxx/models/research/object_detection/train.record
  • train_input_reader->label_map_path: ラベルへのパス。今回は/home/xxx/models/research/object_detection/training/labelmap.pbtxt
  • eval_input_reader->input_path: エバリュエーション用のtfrecord. 今回は/home/xxx/models/research/object_detection/test.record
  • eval_input_reader->label_map_path: ラベルへのパス。今回は/home/xxx/models/research/object_detection/training/labelmap.pbtxt
以上で大丈夫だと思うが、eval_configはデータ数に応じて変えたほうがいいかもしれない。また、num_stepsも。あとはデータ拡張当たりの設定もできるようだが必須じゃないので、ここでは言及しない。

トレーニング実施

下記のコマンドでトレーニングを実施してください。
いや、とにかく遅い。1ステップあたり10秒以上かかってる。一晩寝かしたくらいではだめなやつかもしれません。
動作確認くらいであれば適当なところで切り上げるのがいいかもしれません。
以上で、モデルの作成は終了です。

検出

モデルが作れたので、実際にライオンと猫を検出してみましょう。
まずはグラフを出力します。

 

あとは、object_detection_tutorial.ipynbを参考に実行します。一応、参考までにほぼコピペですがソースコードも付録につけておきます。

こんな感じのイメージが作られれば成功です。

まとめ

今回は、Tensorflowを使って「ライオン」と「ネコ」の検出を行いました。結構簡単にできてびっくりですね。次はもう少し精度を上げられるようにGPUを使って学習をしてみたいなぁ。(希望)

 

付録

 

コメント