ニューラルネットワークが学習した概念を理解するための手法の1つとして、内部ニューロンの出力を最大化させる画像を生成する方法があります。様々なフレームワークでの実装が見受けられますが、ベースとなる理論は共通しています。それでもなお、最適化の手法(+learning rate)や正則化の種類などの取り入れ方で、生成される画像は全く様相が異なってきます。
近年google brain teamが公開した論文(総説とカテゴライズしてよいのでしょうか)の中で、種々の手法を効果的に組み合わせることでかくも美しい画像を生成することに成功しています。しかしながら、その時点では自分が知る限りソースコードを開示していませんでした。
feature visualization techniques
自分でなんとかするしかないのか、、、と思っていたら、最近出された下記の論文と併せてついにgithubにて可視化ライブラリlucidが公開されました。
The Building Blocks of Interpretability
lucid
最適化手法を柔軟に設定することができる一方、ネットワークなどはGoogleNetとしてハードコードされています。inceptionモジュールの数だけ遊ぶ余地はたくさんあります。よく理解していないのですが、google上で遊べるcolabという形でも提供していますので、pcリソースがなくても大丈夫そうです。lucid tutorial ローカルで使いたい人はlucidとtensorflowをpipで入れて使ってみてください。詳細はgithubのチュートリアル参照。(GPUないとしんどいです)。
しかしながら、自分はkerasユーザー。kerasで作成したモデルをtensorflowベースのlucidでなんとか使えないかといじっていました。時間がかかったのですが、最近ようやく動かすことができました。自前のモデルを適用させることが最終目標なのですが、今回は予備実験兼ねて学習済みinceptionv3を使ってみることにしました。
概要
kerasでimagenet学習済InceptionV3モデルを読み込み→protobuf形式としてグラフと重みを保存→lucidのコードと連携するように自前ネットワークを読み込むクラスを作成→各層の可視化
今回はいくつかの層での生成結果の一部を紹介したいと思います(コードの詳細は後日)。protobufを用意できればどのようなネットワークでもlucidに持っていけるのでフレームワーク非依存になってとても良いと思います。
conv2d_1
CNNの最初は単純な特徴抽出に始まると言われていますが、確かにそうですね。色情報の抽出が中心として行われていると推測されます。
conv2d_2 conv2d_3 conv2d_4
省略
conv2d_5
mixed0
mixed1~mixed4
省略
mixed5
物体のパーツらしきものが見え始めます。左の画像は犬か狐(それともアヒル?)の鼻先で、右は目でしょうか。
mixed6-mixed9
省略
mixed10
You may still identify specific subjects, but will usually need a combination of diversity and dataset examples to do so. Neurons do not seem to correspond to particularly meaningful semantic ideas anymore.
feature visualization techniques
といわれているように、深い層ではニューロンが複雑化しすぎて人間にとってよくわからない状態になると言われています。
さて、上記論文では行われていませんが、最終層の全結合層(imagenetなのでニューロンは1000個)のSoftmax活性化関数前の状態を利用することで特定のラベルっぽくなるような画像も生成することができます。みてみましょう。
最終層(Relu前)
なんて微妙なラベルのチョイスなんだという感じですが、1000ラベルの生成がまだ終わっていないのと、そもそも生成してもラベルを想起させることのできる画像がなかなか出てこないのです。これはCNNの弱点を反映していて、Pooling層の作用でパーツ間の位置情報が失われているため、と言われています。(ないと位置情報に弱くなるのでどうしようもないのですが、、)福笑い状態の画像でも目と鼻と口があれば人と判断されるということと同義です。(巷で話題のカプセルネットワークにこのような手法を適用できればクリアできるんでしょうかね?)。
ちなみにページ一番上のモンタージュも最終層出力です。左上から右下の順番で(tench, goldfish, great white shark, tiger shark, hammerhead, electric ray, stingray, cock, hen, ostrich, brambling, goldfinch, house finch, junco, indigo bunting, robin)です。わかりますか?自分はgoldfishがかろうじて、、、ぐらいです。
今回うまくいったのはシンプルな物体(カタツムリや線虫を書くのに必要なパーツは動物に加えて少ない)だったからでしょうか?フラミンゴはよくわかりません。他のラベルとの冗長性が少ないか、それとも引きの写真が多くて結果的にパーツが少なかったのでしょうか。だれかここ詳しい人いますかね。。。
全部のニューロンを可視化するには時間がかかります。空いたリソースでちょこちょこやっていきますので、できたらまた紹介します。xceptionやresnetでも試したいです。
元々は自分の研究題材で学習させた場合、どのような特徴が見えてくるのかというところに今回の試みがありますので、そちらの方は本手法を取り入れて形にしたいと考えています。
それでは!