一歩進んだ物体認識を行うためのSelective SearchのPython版オープンソースの提供とLabellioを組み合わせた活用方法
AlpacaはSelective Searchと呼ばれる物体認識の候補領域を切り出すためのアルゴリズムのPython実装を提供します。本ブログエントリーにおいてSelective Searchの基本的な説明とLabellio(https://www.labell.io/ja/)を組み合わせた活用方法について説明します。
はじめに
物体認識に関するニーズは多様ですが、そのタスクは大きく以下に分類できます。
- 写真一枚に一つの物体が写っていると仮定して認識するObject Classification
- 複数の物体が写っている可能性も考慮してそれぞれを個別に認識&画像中での位置(矩形)までも絞り込むLocalization
- ピクセル単位で物体のラベル付を行うSegmentation
- 近年ではImage Captioningと呼ばれるCNNで抽出された特徴量をRNNにつなげることでセンテンスによる表現まで学習させる手法(Deep Visual-Semantic Alignments for Generating Image Descriptions)もあります。
Labellioを用いて作成した画像認識モデルを利用するための環境構築とコマンドライン上における利用方法 - Alpaca JP Blogで紹介したlabellio_cliのAPIはこの中で一番シンプルなObject Classificationを行うものです。Alpacaでは、そこからさらに一歩踏み込んだLocalizationを実現する方法を提供します。また、その中で利用しているSelective Searchのオープン実装も合わせてGitHubで提供し、Caffe以外の様々なツールでも同様のことを実現可能とします。
Selective Searchとは
Localizationを行う最も愚直な方法はスライディングウィンドウでひたすら舐めるExhaustive Searchです。しかし、それでは処理対象となる領域が多くなりすぎる上に、対応できる形状やサイズに制限が発生します。
解決策として、ピクセルレベルで類似する領域をグルーピングしていくことで候補領域を選出するSelective Searchというアルゴリズムが有用です。
Selective SearchとCNNの組み合わせる手法はR-CNN([1311.2524] Rich feature hierarchies for accurate object detection and semantic segmentation)と呼ばれ、GoogleNet(http://arxiv.org/pdf/1409.4842.pdf)でも同様のパイプラインが利用されていたりする非常にメジャーなものです。
しかし、実際にSelective Searchを使おうと思うとオープンな実装は余り見つからず、caffeのサンプル(https://github.com/BVLC/caffe/blob/master/python/caffe/detector.py)で参照されているモジュールも実行するためにMATLABが必要だったりします。MATLABのランタイムを設定する事自体、なかなか骨の折れる作業です。このような現状の解決策として、AlpacaはLocalizationを実現するための方法としてSelective Serachのオープン実装をPythonモジュールとして提供します。
なお、上記モジュールのインターフェースは、特にLabellioを前提としたものではなく、またその中身もPython実装ですので、Labellioで利用しているCaffe以外のDeep Learningライブラリ(最近Alpacaでも人気のChainerなど)からの利用も容易であり、物体認識の汎用ソリューションとしてもご利用いただけます。
蛇足ですが、Localizationのタスクに対する他のアプローチとしてOverFeat(http://arxiv.org/pdf/1312.6229v4.pdf)と名付けられたネットワークで、CNNにローカリゼーション用のリグレッションまで組み合わせた手法も提案されています。
Selective Serachの活用例: Labellioでケーキ分類器を学習し、Selective Searchによる候補領域を切り出す物体認識を行う
Selective Serachの活用例として、お皿に複数の種類のケーキがある状況で、皿の上のケーキをそれぞれ認識してみます。
まずは、Labellio(https://www.labell.io/ja/)でケーキ分類器を作りましょう。モンブランとチーズケーキとショートケーキをBing検索による検索結果で引っ張ってくることにしました。
画像検索では必ずしも正しい結果が返ってくるとは限らないため、念のため手動でラベル付を行います。案の定、Mt.Blanc等ケーキ以外の写真も検索結果に入っていました。
トレーニングが完了するまでコーヒーでも飲んで待ちましょう。
トレーニングが完了したらモデルをダウンロードします。
以上でモデルの作成は完了です。精度は96%に到達しており、本デモに活用できる水準に達しています。
次に、本題のSelective SearchによるLocalizationを行います。入力画像として、以下の2つのケーキの写った写真を使います。
Selective Searchでは、まず既存のアルゴリズムで小領域への分割を行い、その小領域同士をお互いの類似に応じて結合するという操作を繰り返し、最終的に一つになるまで徐々に大きな領域としていきます。元の論文ではFelzenswalbのアルゴリズムが初期領域の決定に使われています。抽出された少領域ごとに色付けしたイメージは以下の様になります。
これらの領域同士を色のヒストグラムやテクスチャ等の類似度で数値化した混合メトリクスで類似度の高いものから結合していき、最終的に一つの領域になるまで繰り返せばSelective Searchによる候補領域抽出の完了です。これらはAlpacaのselectivesearchモジュール(https://pypi.python.org/pypi/selectivesearch/0.1)によってAPI一発で行えます。簡易実装ながらそれなりの結果が得られます。なお、高速化等のプルリクエストは大歓迎です。
Selective Searchのモジュールのインストールは、pythonのモジュール管理ソフトウェアであるpipがインストールされている環境であれば、
pip install selectivesearch
で一発です。ライブラリで提供するAPIはselective_search()一つだけで、読み込んだ画像とパラメーターを渡すだけで矩形のリストが得られます。サンプルは https://github.com/AlpacaDB/selectivesearchを参照して下さい。
Selective Searchの結果をバウンディングボックスで表示したものは以下の様になります。
あとはこれらの領域に対してCNNによる判定を行うだけです。判定結果に切り取った画像をそれぞれLabellio CLIに渡して、結果は以下の様になりました。分類結果の確からしさをしきい値でフィルターすることで領域外のノイズを排除しています。
このように、Selective SearchとCNNを組み合わせることで、Localizationも含めた物体認識が可能になります。AlpacaのSelective Searchを活用して、Labellioの活用の道がより広がれば幸いです。
追記
いくつかAlpacaJPN Twitterアカウントで情報を発信しておりますので、まとめます。
AlpacaのSelective Search(https://t.co/TShHRaB3Uv)が結構ご利用いただいており、その中で高速化についての疑問があるようなので、情報共有したいとおもいます: https://t.co/yXAXkB2E71
— Alpaca Japan (@AlpacaJPN) November 17, 2015
Selective Searchの高速化には投入する画像サイズを小さくすることが一番効きます。そもそも画像認識のためにDeepLearningの認識器に投入する画像のサイズが200x200などに正規化されていることを考え、上手く調整するのがよいかとおもいます。
— Alpaca Japan (@AlpacaJPN) November 17, 2015
また、AlpacaからのForkで高速化されたブランチもあるようです。https://t.co/ml7shgsNxI パラメータを調整するのであれば、min_sizeサイズを調整して計算を打ち切るのを早めにするのも効果があります。
— Alpaca Japan (@AlpacaJPN) November 17, 2015