KaiNDを作っていくぞ会 第2回 --AI改善--
こんにちは。
開発メンバー、AI担当のKです。
テレワークが続いているので重度の運動不足です。
ここ最近、簡易的なエアロバイクをGETしたので、毎日使っています。
これで少しでも運動不足を解消したいです。
目次
0. 前回まで
↓前回のブログ
tottorisnow33.hatenablog.com
前回からKaiNDシリーズを拡張・改善しています。一緒にやっているメンバーで以下のように分担しています。
松原: KaiND Web
K : AI自体の改善
Y :スマホアプリのUIの改善
前回は松原くんがWebアプリについてブログに載せてくれました。今回は私KによるAI自体の改善について書いていきます。
1. AIがどこを注目しているか可視化したい
リリースしたアプリ(KaiNDシリーズ -Pug or Bulldog-)は、スマホのカメラでかざしたものがパグなのかブルドッグなのかその他なのかを識別するものです。
play.google.com
これからもっと性能を上げたいと思っています。
性能を上げるためには、学習データセットを増やす、Data Augmentationをもっとかける、もっと良いネットワークを使う(今はMobilnetV2を使用)などがあると思います。
何から試すべきか決めるためにも、まずはAIが画像上のどこに注目して、パグ or ブルドッグと判定しているのかを可視化することにしました。
可視化のために、Grad-CAMという論文の手法を使いました。
https://openaccess.thecvf.com/content_ICCV_2017/papers/Selvaraju_Grad-CAM_Visual_Explanations_ICCV_2017_paper.pdf
Grad-CAMは、"grad"という名前がついているように勾配を使います。
最終出力と最後のConv layerの出力で勾配を取る(微分する)ことで、conv layerの特徴マップのどの辺が最終出力に寄与しているかを計算しています。
"最終出力"と言っているのは、パグとかブルドッグとかの結果を出すクラス識別結果の部分です。
一方、"最後のConv layer"というのは、全結合層を適用する前(CNN部分のおしり)の部分です。
Grad-CAMの詳細は、論文や、以下のサイトを参考にしていただけると良いかと思います。
以下のサイトではGrad-CAMの手法を、図を使いながら説明しています。
dajiro.com
2. 参考にしたソース
私たちは Tensorflow の2系を使っています。
同じくtfの2系を使っていてGrad-CAMを実装している人はいないかなと探したところ、見つけました。
Grad CAM implementation with Tensorflow 2 · GitHub
↑こちらのソースを参考にGrad-CAMを実装しました。
ただ、実装するにあたり、アプリで使っているMobileNetV2のソースではうまくいかなそうなので、以前自作したResNetを使いました。
tottorisnow33.hatenablog.com
なぜMobileNetV2のソースではうまくいかなかったのか。
私たちのMobileNetV2のソースでは、以下のブログで書いたようにtensorflow hubを利用しています。
Section 1で書いたように、Grad-CAMではConv layerの出力が必要となります。
しかし、tensorflow hubで引っ張ってきたモデルは、画像の入力から全結合層による出力まで1つの箱のようになっているみたいでなのです。
私はtensorflow hubで引っ張ってきたモデルからconv layerのところだけ取り出せないかと試しましたが、ちょっとダメそうでした。
一方で、自作したResNetなら各layerを1つ1つ書いていて、conv layerの出力を取り出すのは容易だったのでResNetのソースでGrad-CAMを試しました。
3. 自作ResNetでGrad-CAMをやってみた結果
自作ResNetでやってみた結果は↓です。
【勉強会報告】
— ごまあぶら (@tsukuruiroirop1) June 11, 2022
識別結果に対して、特徴マップのどの辺が寄与しているか見たいので、Grad-camを使ってみた。
ただ、赤と青の部分で似たような値だった。。
学習がうまくいってないのかな?
そもそもgrad-camに使うconv layerの活性値は、BNやReLUの後でよいのだろうか?
次回はその辺を調べてみよう。 pic.twitter.com/kfCFoiCa1B
色の付き方だけ見ると、パグの耳、目、口元あたりに注目していることがわかります。
ただ、、、↑のツイートに書いたように、実際にGrad-CAMで計算した値は、青い部分と赤い部分で割と同じような値でした。
具体的に言うと、赤いところが1.09、青いところが1.06とかです。
(ちなみに、Grad-CAMの計算結果が大きいほど出力に寄与しています。可視化するときは、最大値を赤、最小値を青となるように正規化してます。)
値が近いので、結局赤いところも青いところも同じくらい注目しているのでは...?
と思いましたが。
これで良いのだろうか。。。。
今回Grad-CAMを初めて使ったので、Grad-CAMで出力した数値の勘所がわかりません。。
そもそも、今回のResNetは事前学習もしてないので、このモデルが微妙なだけかもしれません。。