アラカン"BOKU"のITな日常

文系システムエンジニアの”BOKU”が勉強したこと、経験したこと、日々思うことを書いてます。

CNNの精度向上にBatchNormalizationが効果があるって本当か試してみる:使い方14/ニューラルネットワークコンソール

レイヤーリファレンスに「MeanSubtraction」以外にも、精度が向上する効果があるって書かている箇所がもう一箇所あります。 

引用してみますね。

入力値を平均0分散1に正規化します。

ConvolutionやAffineの後に挿入することで精度向上、および収束を早める効果があります。

これは、「BatchNormalization」の説明です。 

前に、「MeanSubtraction」を試した時ははなかなかの成果がありました。 

じゃあ、こっちも試してみないとねえ。

 

BatchNormalization の出力を視覚化してみる

 

ニューラルネットワークコンソール(Neural Network Console)を起動します。 

まず、事前に「BatchNormalization」の出力が、どうなるのかを確認してみます。 

前に処理結果の出力を確認する方法をやりました。

arakan-pgm-ai.hatenablog.com

同じやり方、(inputsquaredErrorの間に挟み込んで、MaxPoolingを0にする)で確認できます。 

上記記事のImageAugmentation」を「BatchNormalization」に置き換えればいいわけですね。

f:id:arakan_no_boku:20170909105631j:plain

結果はこんな感じ。

f:id:arakan_no_boku:20170909105940j:plain

 なかなか、激しいです。

 

CNNに組み込んでためす

 

ベースになるシンプルなCNNを組んでみます。 

ベースにするのは、例によって「使い方5」で説明しているものです。

arakan-pgm-ai.hatenablog.com

上記を元に、「使い方6」で初期値のチューニングをして保存したプロジェクトを、今回のベースで開いて、別名で保存しておきます。 

arakan-pgm-ai.hatenablog.com

もっとも、下の説明で実際に組んだハードコピーを貼り付けていますので、それを見て新規プロジェクトでペタペタ作ってもらっても全然構わないのですけれど。 

これに、「BatchNormalization」を組み込んでいくわけです。

せっかくなのでちょっとイレギュラーなことをして試してみます。 

BatchNormalizationは、ConvolutionやAffineの後に挿入するのが普通です。

でも、試しにinputの直後においてみます。 

こんなん見たことないですけど。

おもしろいので。 

さて、こんな感じでinputの直後に置くと、この出力が「convolution」の入力になるわけですよね・・・大丈夫かな。

f:id:arakan_no_boku:20170909004418j:plain

 

この構成で、データはMNISTではなくて、前につかったオリジナルのアルファベットの独自データをDATASETにしてやってみます。

arakan-pgm-ai.hatenablog.com

 

別にMNISTのままでも全然いいです。

けど、以下の結果とはちょっと変わるかもしれませんので、ご容赦ください。 

上記の構成で学習してみた結果がこちらです。

f:id:arakan_no_boku:20170909110619j:plain

 

最後の方で、なんかおかしな動きしてますが、まあまあ、学習はできてるぽいですよね。 

評価結果はこんな感じ。

f:id:arakan_no_boku:20170909110759j:plain

 

99,20%・・ということは、変更する前の結果と同じということです。 

どうも、悪さもしないが、良くもならない。 

あまり、意味がないみたいですね。

 

BatchNormalizationを、convolutionの直後に動かしてみる

 

じゃあ、今度は、正規の位置・・つまり、convolutionの直後に動かしてみます。

f:id:arakan_no_boku:20170909111321j:plain

 

他の設定はまったく変えずに、学習と評価をやって、どう変わるか見てみます。 

学習した結果はこちら。

f:id:arakan_no_boku:20170909111505j:plain

 

かなりきれいな学習曲線になりました。 

ちょっと、期待できそうです。 

でもって、評価した結果がこちら。

f:id:arakan_no_boku:20170909111644j:plain

 

おお!・・99.31%になった。 

リファレンスの

ConvolutionやAffineの後に挿入することで精度向上、および収束を早める効果があります。 

は、本当なんだなあ・・と実感できますね。

 

調子にのって、DropOutを追加して、さらなる向上を狙ってみる

 

こうなると、「DropOut」を組み合わせるとどうなるか? 

興味がでてきます。 

ここで、inputの直後にDropOutを挿入してやってみましょう。

f:id:arakan_no_boku:20170909112343j:plain

 

設定はデフォルトのままでさわらないことにします。 

さきほどの、99.31%の構成にDropOutが加わっただけですね。 

これで、学習と評価をやってみます。 

学習結果はこちら。

f:id:arakan_no_boku:20170909113027j:plain

 

うーん。なんとなく、学習が収束していない(終わってない)感じがしますね。 

DropOutをはさむと、やっぱり学習に必要なEpoch数が増えてしまうみたいです。 

案の定、評価結果もこんな感じ。

f:id:arakan_no_boku:20170909113200j:plain

 

学習が途中で終わってしまったぜ・・感、満載ですね。 

じゃあ、しょうがないから、CONFIGタブで、Max Epoch を倍の200にしてみます。

f:id:arakan_no_boku:20170909113315j:plain

 

これで、再度学習と評価をしてみます。 

学習結果は、こんな感じ。

f:id:arakan_no_boku:20170909130019j:plain

 

うーん。学習が進んでるかどうか微妙ですね。 

で、評価結果。

f:id:arakan_no_boku:20170909130102j:plain

 

98.06%・・変わらないですね。

 

本日の結論

 

過学習抑制で利用した「BatchNormalization」が、精度を向上させる効果もあるというのが本当だ・・ということが確認できました。 

最後の「DropOut」を追加したのは余計でしたけど、まあ、こういうやり方で使うのはよろしくない・・のがわかったので良いかな。 

おそらく、もっと複雑なニューラルネットワークを組んだときに、過学習のリスクを抑えるために「DropOut」は効果あるみたいなんですけど、こんなシンプルなCNNに使っても仕方ない・・ってことなんですかね。 

もちろん、今回試してみた感覚では・・ですけどね。 

でも、本を読んで概念的なものを理解するだけより、実際にためして、感覚的につかんでいるのは応用を考える時の引き出しが増えます。 

だから、時間がある時に、いろいろ試すのは面白いですね。 

関連記事

ニューラルネットワークコンソールの記事一覧はこちらです。

arakan-pgm-ai.hatenablog.com

ニューラルネットワークコンソールの裏で動いているNNabla(Neural Network Libraries)の記事一覧はこちらです。

arakan-pgm-ai.hatenablog.com