計量学習を用いた画像検索エンジンとアニメ顔類似検索v3について

まだgithubにはpushしていないのですが、さいきょうの組み込み型画像検索エンジンotamaに計量学習を用いて与えられたデータにあった画像間の距離関数を学習してそれを使って検索するというドライバを入れたので、先行的なデモとしてアニメ顔類似検索v3を作ってみました。
計量学習は、ベクトル間の距離の計り方を機械学習で決めるみたいな分野です。

アニメ顔類似検索v3

AnimeFace Search v3 - Otama LMCA_VLAD_HSV Driver

https://raw.github.com/nagadomi/misc-image/master/otama/animeface-1.png

randomボタンを押すと顔画像がランダムに出るのでどれかクリックするとそれをクエリに検索します。color weightは色の重みを調節するパラメーターで、1にすると色だけで検索します。0にすると形状やテクスチャだけで検索します。結果画像の上の数字は類似度的なもので、その横のgglは元画像をGoogle Search by Imageを使って検索するためのリンクです。
上のほうに例として見栄えのよさそうなクエリへのリンクを張っているので、それらをクリックすると大体の雰囲気が分かると思います。
検索中に変な領域に入ってしまうと、どれ選んでも変な感じになるので、全然ダメジャン!!と思ったら、一度randomをクリックしてリセットしてみてください。
あと、Chromeを使っている方は、翻訳バーが出てうざいかもしれません。ドメインに対して無効にしましょう。

今回のバージョンは汎用的な画像特徴量だけ使ってユーザーが主観で作ったラベル付きデータに合う画像検索エンジンを自動構築するという汎用的なもので、このウェブアプリケーションもotamaに添付しているexample-webappというサンプルプログラムを使っているだけなので、前のバージョンのような髪の色で検索できたり髪を強調する前処理を入れたりのアニメ顔専用の機能は入れていません。
データは前回(http://anime.udp.jp/face-search-v1/)と同じく、animeface-character-datasetで学習して、それとは全く関係のない 4chan /a/ をクロールして得た画像からImager::AnimeFaceを使って自動で切り取った顔画像約10万件が入っています。

花類似検索

それと、アニメ顔以外でも使えますよという例として花類似検索も作ってみた。

102flowers - Otama LMCA_VLAD_HSV Driver

https://raw.github.com/nagadomi/misc-image/master/otama/flowers-1.png

こっちは102 Category Flower Datasetというデータを半分使って学習して、全部を入れています。アニメ顔類似検索と違って学習に使ったクラス(花の種類)しか入っていないので、こっちのほうがうまくいっていると思うし正しい使い方です。

他に Stanford Dogs Dataset を使って犬類似検索も作ってみたけど、難しすぎてやばかったので公開は控えます(死

あらまし

表紙を写すと本のレビューが読めたりするHTML5アプリを作ってみた - デーで開発中の画像検索エンジンライブラリを紹介しました。
この記事は僕の書き方が悪かったというものあるけど、JavaScriptで動画が扱えてすごい!!みたいな反応が多かったのですが、これがやっていることはスマホで適当に本を撮影すると100万件を超える本のデータベースから該当の本を1秒くらいで検索できる(さくらVPS2G 1台で!!)というもので、100万件あればここ20年くらいに発売された本はだいたいカバーできるので(表紙だけに)、本を扱うアプリケーションの革命だ!!という事が言いたかったのです。ただこれは特定物体認識という分野で、真面目に研究している企業なども多いから、趣味ライブラリで対抗するのは無理ある感じするし、データもアレなので、これ以上深入りしないほうがいいかなと思って、じゃあ今後はどういう方向で開発していこうかなーと考えたところ、やはりここは僕の持ちネタであるところのアニメ顔類似検索しかない!!と思ったものの、アニメ顔類似検索専用ドライバみたいなの入れるとネタ色が強すぎるので、もう少し真面目な感じで、汎用的な特徴量から与えれたラベル付きデータに適した画像検索エンジンを作れるようにすれば、与えたデータによってアニメ顔類似検索にも花類似検索にも犬類似検索にもなる!! 今入っている汎用的な類似検索用ドライバ(sim)が適当な感じなのでこれを置きかえることもできる!! 最高!! と思ってこの機能を入れることにしました。

それで去年の10月には大体できていたんだけど、いろいろあって放置してたのを今年中にまとめよう!!と12/29日くらいから思い始めて、まだまとめている最中です。
あまりにやることが多いので先にデモでも置いとくかという考えにいたった。近いうちにまとめて公開します。
それでこのライブラリでやりたかったことは大体終わる気がする(えっ

使っているアルゴリズムについて

詳しくは学習プログラムの説明にでも書こうと思っているけど、気になる人もいると思うので、単語だけでも並べておきます。
まず元になる画像特徴量にはVLADと領域分割を使ったHSVヒストグラムを使っています。VLADで使っている特徴点検出器と記述子はBOVWドライバ用に書いていたものを使っています。
VLAD、HSVそれぞれの特徴量から教師データにあった検索用の空間への変換関数を線形のLMCAをベースにしたアルゴリズムで学習して、検索では変換した後の空間で距離が近いデータを表示します。画面上にあるcolor weightは、VLADとHSVの重みを決めるパラメーターで、それぞれの距離を重み付けて足したものを最終的な画像間の距離にしています。
LMCAはk近傍識別器の精度を上げるための手法ですが、単純な画像検索システムではクエリベクトルのk近傍を検索結果として表示するだけなので、k近傍識別器の精度がよくなるような空間に変換したあとで距離が近いデータを表示すれば類似検索としてもよい感じになっているだろうという考えで作っています。

感想

実は前のバージョン(v2)も計量学習という分野を知らなかった頃の俺が考えたさいきょうのけいりょうがくしゅうを使っているので、考え方は前のバージョンと同じで、実装が異るだけです。v2は、多クラス線形分類器(one-versus-the-rest)の精度がよくなるような空間への変換関数を教師ありで学習すれば(階層ニューラルネットワークは1層目で非線形変換したベクトルを2層目で線形分類する)、全てのキャラにおいて各キャラとそれ以外のキャラをできるだけ線形分離できるようになるからきっと同じキャラのベクトルが似てきているので似た顔も集まってきて(このへんがすごくテキトウ)いける!というものでした。今回使っているLMCAは 変換後の空間でk近傍識別器の精度がよくなるようにするというそのまんまな目標を持っているので、妙な妄想を挟まずとも僕が本当にやりたかったことをきちんと学習してくれる感じです。ただこれめちゃくちゃ重い式で、1万次元(VLADがそれくらいある)1万データ(animeface-character-datasetがそれ以上ある)から学習するのは無理だろという感じだったので、色々計算を工夫したりテキトウに端折ったりSIMDOpenMPでゴリ押ししたりして、うちの家庭用パソコンでも爆速(2日間くらい)で学習できるような実装にしたので、LMCAをベースにしたものと書かざるおえなくなった。LMCAはあまりメジャーではないようですが、計量学習と次元削減が同時にできるのと(元の次元が高いので次元削減は必須だった)、目的関数が直感的で分かりやすく自分でもいじりやすそうだったので選びました。
類似検索としては、前は(これは仕方がないことだけど)教師データになかったクラス(キャラクタ)の精度がきわめて悪かったのが、教師データになかったクラスもアニメ絵であればなんかそれっぽくなっている場合が多い気がします。あと前のは結局髪の色で検索しているだけだろと言われていたので、色の重みを調節できるようにしたけど、色なしでも西又絵とかちゃんと検索できるし、色以外もある程度使えていると思います。ただアニメ絵じゃない細い線の集合で書かれたようなイラストは色以外ではうまくいっていないように思います。顔というより髪の塗り方とかキャラデザが学習されている感じがする(だから描く人のやり方が強く出ているイラストはうまくいかないのかなとか)。
検索速度は、前はクソみたいなSQL検索だったのが、僕が本気で書いた超ゴリ押し並列全検索になったので、桁違いに速くなっています(計算量は同じです)。

自分としては全てにおいて前作を超えた……と思ってますが、どうだろうか……
超えたからといって何もないし、まだまだダメな感じするし、というか、もはやなんのためにアニメ顔類似検索なんてものを作ろうとしていたのか忘れてしまったのだが――