"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

レイヤーの出力を眼で見て確認(Convolution/Max Pooling)/Neural Network Consoleの使い方

今回は、ディープラーニングの画像処理で一般的なCNNで使うメインのレイヤーの出力を視覚化して確認してみます。

f:id:arakan_no_boku:20190326212937j:plain

 

視覚で確認してみる

 

仕組とかについては、こちらで整理したりもしてるのですが、やっぱ、理論だけよりも視覚でも確認してみると、また違った理解ができるかな・・という感じです。

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

 

SquaredErrorを使います

 

SquaredError を使い、Max Epoch 0 で学習・評価実行すると、その直前のレイヤーまでの加工結果をモニタすることができるのを利用します。

f:id:arakan_no_boku:20180819142726j:plain

f:id:arakan_no_boku:20180819142814j:plain

 

今回は画像データで

 

Inputデータは、とりあえずMNISTを使います。 

対象にするレイヤーは、CNNではお馴染みのConvolutionとPoolingです。

日本語では畳み込み層とプーリング層といわれているものですが、このレイヤーの加工結果を見るには、ある程度、この2つの層の働きと動きを知っておかないと・・たぶん・・訳が分からないです。

だから、その説明も混ぜ込みながら、ぼちぼちやっていきます。

画像の場合はNeural Network ConsoleのOutput Resultで画像を表示してくれます。

EXCELとかは不要です。

 

まずはConvolution層のみ

 

さて、まず、Convolutionのみの加工結果をアウトプットしてみます。

f:id:arakan_no_boku:20180819213550j:plain

例によって、Max Epoch=0にしています。

InputデータはMINISTの「4」。

f:id:arakan_no_boku:20180819213656j:plain

それに対して、OUTPUTされたのは以下の16画像です。

f:id:arakan_no_boku:20180819213742j:plain

これを見て、「なんで16個も画像がOUTPUTされるの?」とか「同じINPUTなのに、なんでOUTPUTの画像がそれぞれ違うの?」などと疑問を持つ人もいると思うので、ちょっとざっくり補足しておきます。

 

1つの画像にたいして16画像も出力されるわけ

 

まず、なんで「16画像も出力されるのか」ですが、それはConvolutionのレイヤープロパティの「OutMaps」が16になっているからです。

f:id:arakan_no_boku:20180819214520j:plain

何故、16がデフォルトか?というと、たぶん、それが標準的に良い精度を期待できると考えられたからでしょう。(ざっくり・・笑)

 

生成される16画像はなぜ違う?

 

じゃあ・・。

何故、16個のOUTPUT画像がそれぞれ違うのか?・・です。

 

まず、Convolutionで出力を計算する手順の理解が必要です。

実際のデータではややこしいので、説明用に元の画像データ(7×7)で、KarnelShape(フィルターサイズ)が「3×3」、OUTPUTが「3×3」の簡単なモデルで例をのせます。

f:id:arakan_no_boku:20180819221335j:plain

元データの左上の「3×3」の数値と、カーネル(フィルター)の「3×3」の対応する位置の数値を掛け合わせて全部足して(上記の例なら 0*8+1*7+2*6+3*5+4*4+5*3+6*2+7*1+8*0)、結果の84をOUTPUTの左端にセットする・・みたいな感じで計算するわけです。

そうして横や下方向にStridesで指定された数の分ずらしながら同じことをやって、OUTPUTを埋めていくわけですね。

これが意味すること・・つまり、カーネル(フィルター)の数字によって、OUTPUTのデータは変化するということです。

ディープラーニングって、結局、学習データのバリエーションが沢山あった方が精度があがるという傾向があります。

なので、OUTPUT16パターンがデフォルトで、しかも同じものばっかり出力しても無駄なだけなので、カーネル(フィルター)の数字を買えながら、バリエーションを作っている・・ということなんでしょうね。

 

続いてPooling層を付け加えてみます

 

今度はPooling層を追加してみます。

使うのは「MaxPooling」です。

f:id:arakan_no_boku:20180820210658j:plain

このアウトプットイメージはこんな感じです。

f:id:arakan_no_boku:20180820211103j:plain

上のConvolutionの出力だとギザギザだったところが均されて、シャープな印象の画像になっているのがわかると思います。

これが、まさしくPooling層の仕事です。

 

Max Poolingの仕組をさらっと

 

デフォルトのMaxPoolingのパラメータは、こうなってます。

f:id:arakan_no_boku:20180820212854j:plain

やってることは単純です。

元データの左上から「KernelShape」で指定した範囲(上だと2×2)の中で、一番大きい数字のみをOUTPUTに出力する。

終わったら、Strides分だけずらながら同じことをやっていくわけです。

Convolutionと違って、Poolingでは重複させないように、KernelShapeとStridesは同じにするものだそうです。

言葉だとイメージしづらいので、8×8の簡単なサンプルを描きました。

f:id:arakan_no_boku:20180820213514j:plain

KernelShapeが2×2なので、上記左上の4つ(色付きのところ)をまず、見ます。

そうすると「1,2,7,8」の4つの数字なので、一番大きい「8」がアウトプットになる。

こんな感じです。

なので、KernelShape、Stridesが2,2の場合は、OUTPUTのサイズは縦横とも半分になります。

実際、Neural Network Consoleが自動計算したサイズを見ても、24×24が、12×12と縦横半分になってますよね。

f:id:arakan_no_boku:20180820210658j:plain

一番大きい数字=その領域で最も特徴を強く表す数字だけをOUTPUTしていくので、上記の図みたいに、Convolutionの出力の特徴をより明確にした感じになるわけです。

 

視覚的なイメージを持つのは悪くない

 

やっぱ、文系人間ですから。

数式とかで見ても、イメージがしづらい。

ディープラーニングだとレイヤーを何層も重ねていくので、前のアウトプットが次のインプットになって・・みたいな感じになるので、アウトプットのイメージがないと何となくやってますになってしまいがちです。

なので、Neural Network Consoleで気軽にアウトプットイメージをつかめるのは、有難いです。

同じことは、tensorflowとかでもできますけど、ちょっとイメージをつかむために、ガリガリpythonでプログラムを書くよりは、GUIで簡単にできるに越したことありませんからねえ。

ではでは。