ディープラーニングによる物体検出(「Faster RNN」「Yolo」「SSD」)に関して調べて実践してみた

f:id:karaage:20180321230444j:plain:w640

物体検出をやってみる前に検出と認識の違い

 これまで、ディープラーニングを使って画像の認識を何度かやってきました(以下参照)。

 画像認識の次は、物体検出に手を出して見たいなということで、ディープラーニングを使った物体検出に関して調べて試してみることにしました。

 そもそも、物体検出って何で、認識と何が違うのかというと、そもそも認識という言うと結構広い意味になってしまって、画像のそのものが何かを判別するのは画像分類というのが正しそうです。つまり、私がやった上記の例は基本的には画像分類となります。それに対して、物体検出は対象がどこにあるかを探す行為になります。ただ、検出の場合は、検出したものが何かを分類するところまで含む場合もあるようですね。

 例えば以下の写真で、ロンスタさんだ!というのが認識で

f:id:karaage:20150430163115j:plain:w640
 フリー素材

 以下のように、ロンスタさんの位置を示すのが物体検出というイメージです(多分)。

f:id:karaage:20180307170648p:plain:w640

 ちなみに、上記写真はバウンディングボックス(bounding box)と呼ばれる枠で物体の位置を示していますが、これをピクセル単位で領域を指定できると、セマンティックセグメンテーションと呼ばれる技術になるそうです。難しそうですね。

 一番有名な物体検出は、顔検出でしょうか。Harrlike(ハールライク)という顔を検出するのに有利な特徴量を用いて検出するのが代表的な方法です。顔検出に関して詳細は、以下記事参照ください。

 と、ここまでだらだら書いてきましたが、もう少し詳しく知りたい方は以下の記事を見るのが分かりやすいです。ここまで書いてから下記記事の存在気づきました。

 認識、分類、検出、セグメンテーションなどは、結構定義をごっちゃにして使っちゃう場合が多いので、正しい使い分けを心がけたいですね。

ディープラーニングを使った物体検出

 顔検出のような、特殊な特徴量を使った検出は、性能や速度で有利なのですが、顔以外には使えないという欠点があります。そんな欠点をカバーするために最近注目を浴びている技術がディープラーニングを使った物体検出です。

 ディープラーニングによる物体検出の研究の流れに関しては、以下スライドが分かりやすかったです。

 上記のスライドや他の資料などみて、物体検出の技術の発展を自分なりの理解を簡単にまとめた図が以下です。

f:id:karaage:20180307173924j:plain:w640

 大きく3つの段階に分かれていて、「領域探索」して、検出する物体に合わせて「特徴量抽出」して、適切な「機械学習手法」を選択して、と物体検出を3つのアルゴリズムに分けて実現していたのが初期の段階です。特徴量も、基本は検出する対象に合わせた専用設計になるため、特定の対象(顔とか)しか検出できないのが基本です。

 第2段階では、ディープラーニングを使うことで特徴量抽出を自動で実現できるようになり、データに応じて色々な物体を分類できるようブレイクスルーが起こりました。やったね!

 ただ、それでも「領域探索のところが遅いよね」という問題があったので、「じゃあそれもディープラーニングでやっちゃえば良いじゃん!」というのが第3段階。そう今は、ディープラーニングで最初から最後まで出来ちゃうようになったのです。そして、その進歩がこの数年というね。恐ろしい世界です。

 このように、データ入力したら後はディープラーニングだけで最後(出力結果)までいってしまうことを、端から端までという意味でEnd-to-Endと言うようです。

 ディープラーニングでEnd-to-Endで物体検出できる有名なソフトウェアとしては「Faster RNN」「Yolo」「SSD」等があります。

 「Faster RNN」に関しては、以下記事がわかりやすかったです。名前の通り、Fast RNNより早いのでFasterのようです。

 そして、そのFaster RNNより更に早いと衝撃を与えたのが「Yolo」です。Yoloに関しては、以前取り合げた「Darknet」というディープラーニングのフレームワークで用いられている技術です。ちょっとだけ検出も試しているので、使い方や概略などは以下参照下さい。

 Yolo v2は、以下のようなKeras + TensorFlowでの実装が結構あるので、簡単に試せそうな雰囲気もありますね。

GitHub - allanzelener/YAD2K: YAD2K: Yet Another Darknet 2 Keras

 そして、そのYoloに匹敵する速度で精度も高い(ドラゴンボール並みのインフレ)と言われているのが、「SSD(Single Shot MultiBox Detector)」らしいです。

SSDでの物体検出を試してみる

 というわけで、今回は今まで試したことのない「SSD」を試してみることにしました。以下の記事が動画を検出する方法を紹介して下さっていたので、基本的には以下のサイトを参考に、少しだけ使い勝手良くしたものを使いました。

 プログラムのベースは、以下のTensorFlow実装のSSDをforkしています。

事前準備

 Pythonで環境をセットアップしましょう。詳細は以下記事など参照下さい。

 代表的なライブラリなどのバージョン情報は以下です。

  • Anaconda3==4.4.0
  • tensorflow==1.3.0
  • opencv-python==3.3.0.10

 環境がセットアップできたら、以下コマンドでファイルのダウンロードと、学習モデルの解凍を実施します。

$ git clone https://github.com/karaage0703/SSD-Tensorflow
$ cd SSD-Tensorflow/checkpoints
$ unzip ssd_300_vgg.ckpt.zip
$ cd ..

SSD実行

 MacBookの場合は、以下コマンドを実行するとMacBook内蔵カメラの画像でリアルタイムに検出が走ります。Core i5のMacBook Proで2秒程度で検出できます。

$ python ssd_camera.py

 output.aviというファイルに、検出結果が書き出されます。

 カメラの代わりに、動画を使用することも可能です。例えば、好きなカメラで動画を撮ってsample.movというファイル名で保存した場合は、以下のように第一引数に動画ファイル名を入れてコマンドの実行すると動画から検出できます。動画は、人が写っていると結果が分かりやすいです。

$ python ssd_video.py sample.mov

 結果は、output.aviというファイルに保存されます。もし、既にoutput.aviというファイルがある場合は、予め消すか別の名前にしておきましょう。

 今回は、いつものようにフリー素材のロンスタ(id:lonestartx)さんの、スリットスキャン写真を作るために撮影した動画を使用しました。フリー素材の再利用です。とってもエコですね。

 SSDで検出した結果は以下です。ロンスタさんの動きにPerson(人間)というバウンディングボックスが完全に追従しています。ロンスタさん、完全に人間として検出されています。ロンスタさんは人間でした!

f:id:karaage:20180321151526g:plain:w640

まとめ

 ディープラーニングによる物体検出に関して、簡単にまとめて「SSD」に関して実践してみました。

 そして、この記事を書いて公開するまでの間(2週間くらい)に、Yoloの新しいバージョンである「Yolo V3」なんてヤバいものが出てきてしまったり、SSDを改良して漫画の画像から物体検出できるようにする研究発表が出てきたりと、相変わらずこの分野の発展速度は凄いです。ついていくのも大変です。

 というわけで、Yolo V3の生かしたデモ動画を見ながら今日はお別れしたいと思います、さよなら、さよなら、さよなら。

参考リンク

SSD: Single Shot MultiBox Detector · Issue #659 · arXivTimes/arXivTimes · GitHub

YOLOv2(Keras/TensorFlow)でディープラーニングによる画像の物体検出を行う - Qiita

関連記事