概要
Deep learningを使って、画像中にあるオブジェクトの数を数える試みをしてみました。
少し古いですが、論文はこちらを参照しています:
Learning to count with deep object features
- この中では、NNを使って、手書き画像中の偶数の数や、カメラ画像中の人間の出現数を推定させる課題を行っています。比較的浅いNNでも精度よく推定できるとのこと
- NNの学習能力から言って決して驚くほどのことでは無いはずですが、それでも、数字に対応するラベルなしに、単に「この画像の中に、偶数はXX個含まれているよ」と教えてもらうだけで、どの数字が偶数なのかを学んでいくNNを見るにつけ、NNの能力の高さを思い知らされます
上記論文の中では、数を数えるだけではなく、具体的にどの位置を見て、数をカウントしていたかということの可視化にも挑戦しています。ただ、使っているテクニックが比較的古典的なこともあり、その部分は最新の技術で置き換えたいと思いました。そこで今回は、下記のGrad-CAMというテクニックを使ってみています:
Grad-CAM:
Visual Explanations from Deep Networks via Gradient-based Localization
convolution中の各feature layerが、最終的な分類結果にどう効くのかを微分係数より判定します。それを重みにしてfeature layerの出力を足し合わせると、最終分類結果に影響を与える「場所」を推定できる、というテクニックです
コード
今回は、一つ目の論文と似たような課題にトライしています。
NMISTの手書き文字データを複数貼り合わせて作った人工的な画像データから、奇数の数を答えるという課題です。
詳細コードは、Gitへ上げていますのでそちらを御覧ください:
GitHub:imageCounting
結果
学習データは、例えば以下のようになります:
一つ目ならば奇数は3つ、二つ目ならば奇数は5つとなり、それをNNに予測させます。
learnRate=1e-5で80k回 x 64batch ほど学習させた結果、精度は80%に到達しました。きちんと学習できているようです。
赤色に近い部分がより注目している部分になり、奇数と偶数が区別して色分けされていることがわかります。
ただ、画像ごとに奇数が着目されるか偶数が着目されるかは一定していません。この画像を作る際、文字数はかならず5個にするように設定しているのですが、その結果として奇数をカウントするのと、奇数=5-偶数 として計算する2つの方法があり得てしまうため、どちらか一方にのみ色がつくということはなくなっています。
大まかな規則性はあるようで、1つの画像の中に出現している数が多い方を積極的に注目している様子は見られます。
そのような具体的な「解釈」にまで踏み込めることこそが、可視化の最大の強みといえるでしょう。
最後に、いくつかGrad-CAMに関する技術的な要素をメモしておきます:
- lossの定義: Grad-CAMの勾配を計算する際に使用するlossの定義の仕方には複数があり得る。例えば、labelからone-hot vectorを作り、それをsoftmaxの入力/出力に掛け算することで、ある分類項目に対応するlossを構築する事もできるし、全labelとsoftmax入力/出力のRMSをとることで、全labelの影響を考慮に入れている実装もある。 双方実験してみたが、結果はほぼ同じ。個人的には前者が美しいと感じる
- 対象とするLayer: Convolution直後のReLUの出力を用いるよりも、その後の max-poolingが終わった後 の微分係数を使用してGrad-CAMをかけた方がきれいに作れる様子。また、できるだけオブジェクトとしての認識力が高まっている 後段の方が望ましい