"BOKU"のITな日常

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

過学習をわざと発生させて問題点の確認と改善手段を試す/Neural Network Consoleの使い方

今回は過学習(オーバーフィッティング)について書いてみます。

f:id:arakan_no_boku:20190326212937j:plain

2017/12/01追記

>以降の説明の画面は、Version1.00を使用しています。

>Version1.10でアイコンのデザインなどが一部変更になっています。

>しかし、見てわかる程度の変更なので画像の貼替えまではしてません。 

 

過学習が何故ダメだと言われるのか 

 

過学習は文字とおりにとれば、「勉強しすぎ」です。

なんで勉強しすぎがダメなのかというと応用が利かなくなるからです。

ディープラーニングの学習の目的は、学習データと完全に一致するものを識別できるようにすることではありません。

同じカテゴリに属する学習データから、カテゴリを識別するための「特徴」を抜き出して、それを学習することで、学習データには存在していない「未知のもの」についても、同じカテゴリかどうかを判断できるようにしたいわけです。

ところが、「過学習」がおきてしまうと、学習データと同じものがでてきたら100%判別できるのだけれど、「未知のもの」についての判断精度が落ちてしまいます。

なので・・本末転倒ってことになるわけですね。

  

過学習を発生させる

 

理屈だけだとわかりにくいので、やってみます。

まず、過学習を発生させられるか・・です。

一般的に過学習を発生する主な条件と言われているのは以下のものです。

  • 学習データが少ない
  • 非常に複雑なネットワークである
  • 学習のさせすぎ

などなど。

今回は、いちばん簡単な「学習データを少なくして、無理やり過学習を発生させる」やり方をとります。 

 

少ない学習データを用意する 

 

既存のものを加工して、「少ない学習データ」を作ります。 

エクスプローラで、

ニューラルネットワークコンソールフォルダ}\samples\sample_dataset\MNIST

を開きます。 

ここから「small_mnist_4or9_training.csv」を、適当なフォルダにコピーします。 

そして、コピーしたファイルの名前を「bad_mnist_4or9_training.csv」にします。(別に他の名前でもいいですよ。後でわかれば)

f:id:arakan_no_boku:20170829215554j:plain

 

ここで、コピーした「bad_mnist_4or9_training.csv」の方のファイルを開きます。

f:id:arakan_no_boku:20170829000151j:plain

 

この501行目から下のデータをスパッと消して、上書き保存します。 

これで、約三分の一に減った、少ない学習データができました。

 

ニューラルネットワークコンソールでの作業

 

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

 

DATASETタブ

 

まず、さっき作ったCSVファイルを「DATASET」に登録します。 

左側で「DATASET」を選び、Open dataset ボタンを押します。

f:id:arakan_no_boku:20170829001445j:plain

 

開いたファイル選択ダイアログで、さっき作成したデータ件数を減らしたCSVを選択します。

f:id:arakan_no_boku:20170829001651j:plain

 

追加されましたね。

f:id:arakan_no_boku:20170829001758j:plain

 

EDITタブ

 

さて、プロジェクトの一覧に戻ります。 

以下のようなシンプルなCNN(Convolutional Neural Network)を組みます。

f:id:arakan_no_boku:20170826132310j:plain

 

前回(使い方7)で保存したプロジェクトを開けば、こうなっているはずです。 

新たに組む場合は、「使い方5」から「使い方7」で説明しているので、そちらを参照してください。

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

 

 

これを名前をつけて保存で、違う名前のプロジェクトとして保存します。

f:id:arakan_no_boku:20170829000716j:plain

 

新規プロジェクトのDATASETタブ

 

次に、DATASETタブを開きます。

f:id:arakan_no_boku:20170829215904j:plain

 

上の段の「training」を選択したうえで、右上の「Open Dataset」ボタンを押し、表示された一覧から、さきほど追加した「件数の少ないCSVファイル」を選択します。 

こんな感じで、NUM_DAT(データ件数)500件のtrainingデータが選択されていればOKです。 

 

CONFIGタブ

 

次にCONFIGタブを開いて、Epochを 100、Batch Sizeを100に変更します。 

これは、まあ、念のためです。

f:id:arakan_no_boku:20170829220222j:plain

 

上書き保存します。 

 

学習の実行

 

さて学習をしてみます。  

データの多い時とくらべて、Epoch数50以下の収束の仕方が遅いですね。 

f:id:arakan_no_boku:20170829220517j:plain

 

評価すると確かに精度は下がった

 

精度はどうかというと。

f:id:arakan_no_boku:20170829004205j:plain

 

正確さが 元データで学習・評価した99.2%から96.2%と、3%下がりました。 

約3%は大きいですね。 

 

学習データと同じものなら100%

 

では、学習したのを同じデータを評価に使ったらどうなるかを確認します。 

DATASETタブをもう一度開きます。 

今度はValidationの方も、先程のtraining用と同じCSVファイルに変更してみます。

f:id:arakan_no_boku:20170829220802j:plain

 

これで上書きして、今度は評価だけを再実行します。 

正確さが「1」・・つまり、100%ですよね。

f:id:arakan_no_boku:20170829220920j:plain

 

学習したデータと同じデータに対しては100%の精度で一致する。 

しかし、学習データと異なるデータに対する精度は約3%低下した。 

これは、学習データに最適化しすぎて、学習データと異なるテスト用データでの認識精度が落ちてしまっているわけです。 

過学習をわざと発生させるのはできたっぽいです。  

 

過学習を抑制する技術をさわりだけ試す

 

今度は、過学習が発生しているときに、それをどうやって解消していくか?です。  

これを防ぐ一番簡単な方法は、学習データを増やすことだというのはわかってます。 

でも、適切な学習データをたくさん作ることは大変です。 

それに、複雑なネットワークを組んだことが原因で「過学習」が起きているケースは、それでは対処できません。 

さて、どうするか? 

これも、すでに頭の良い人達が、過学習を抑制する手法を考えてます。 

 

過学習を抑制する効果のあるレイヤー

 

当然、ニューラルネットワークコンソールにも、「過学習」を抑制するために使える技術(レイヤー)がすでに用意されています。 

過学習を抑制する効果のある技術で有名なものが2種類あります。

 

DropOut と BatchNormalizasion です。

 

この2つは異なるアプローチで、過学習を抑制します。 

ざっくりと、アプローチの違いを整理すると。 

 

DropOut

 

DropOutは、ランダムに計算対象とするデータを間引いて処理をすることで、同じ学習データでもバリエーションを生み出して、過学習を抑制します。

データを間引くわけですから、普通に考えれば、DropOutは、計算の前ですよね。 

 

f:id:arakan_no_boku:20170829230351j:plain

 

BatchNormalizasion

 

BatchNormalizasionは、計算結果のバラ付きを補正して、きれいな分布に修正することで、過学習の抑制効果をもちます。 

計算結果のバラつきを補正するわけですから、置き場所は計算の後でしょうね。

こんな感じですかね。

f:id:arakan_no_boku:20170829230120j:plain

 

この2つは、どちらか一方しか使えないわけではありません。

複雑なネットワークを見てると、両方とも適用しているだけでなく、やたらとDropOutをはさみまくってるモデルも結構見ます。

 

DropOutと BatchNormalizasionを試しに使ってみる

 

どのくらい効果があるんでしょうか? 

やってみます。 

ニューラルネットワークコンソールを起動して、「過学習の疑いのある」プロジェクトを開きます。

f:id:arakan_no_boku:20170826132310j:plain

上記の例にならって、ConvolutionとAffineの下に、「BatchNormalization」を挿入していきます。 

間をつないでいる線を事前に消すのを忘れないようにしましょう。 

同様に、一つ目のMaxPoolingの下に「DropOut」をはさみこみます。 

配置できたら、Shift+クリックで線をつなぎます。 

できあがりは、こんな感じです。

f:id:arakan_no_boku:20170829232210j:plain

f:id:arakan_no_boku:20170829232229j:plain

 

DropOut と BatchNormalizasion の設定はデフォルトのままにします。 

ちなみに、DropOutの設定で重要なのは、「P」の項目です。

f:id:arakan_no_boku:20170829234554j:plain

 

これは0.5・・つまり、半分に間引くよ・・ということです。 

ここの数字を変更すると、結果が動いたりしますので、興味があったら、適当に変更して試してみるのも面白いとは思います。 

 

MaxEpochを増やすのは必須

 

ただ、これだけだとダメで、もう少し設定変更が必要です。 

CONFIGタブを開いて、Epochを、100から、とりあえず、700くらいにしておく必要があります。

f:id:arakan_no_boku:20170830000619j:plain

 

なぜ、これが必要かというと、DropOut と BatchNormalizasion を使うと、どちらも、学習をなだらかにすすめる方向に働くからです。

特にDropOutを使うと学習の収束に時間がかかるようになります。

すると少ないEpoch数だと途中で学習が終わってしまうので、数を増やすわけです。 

まあ、試すなら、学習ボタンを押してから、お風呂にでもゆっくりつかってでてくることをおすすめします(笑)。

 

学習・評価結果の確認

 

学習結果はこんな感じです。

f:id:arakan_no_boku:20170830003113j:plain

 

DropOutやBatchNormalizerを適用していない時の学習曲線の例を下におきますので比較してみてください。

f:id:arakan_no_boku:20170829004044j:plain

 

上の図の学習曲線がすごくなだらかになっているのがわかると思います。 

さて、肝心の評価(正確さ)です。

f:id:arakan_no_boku:20170830003511j:plain

 

98,2%・・、対策前の96.2%から約2%改善しました。 

でも、学習用データが1500件あった時の99.2%には、ちょっと足りない。 

そういう結果です。 

 

まとめ

 

対策をうつことで、学習曲線がなだらかになって、過学習の傾向を抑制する動きになっているのは間違いなさそうです。 

学習曲線がなだらかになるということは、学習用データ件数と学習単位・時間のトレードオフ関係になってしまうことも、感覚的によくわかりますね。 

本を読んでるだけでは、この辺のイメージがよくわかりません。  

それを気楽にやってみることができるニューラルネットワークコンソールは、やはり、素敵です。 

 

2017/12/01追記

Version1.10でこの部分のアイコンデザインが主に変わってます。

f:id:arakan_no_boku:20171130202351j:plain

まあ、見てわかる範囲と思ってます。 

------

カテゴリの一覧

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com