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

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

過学習を抑制するDropOutってどんな働きをするのか:使い方8/ニューラルネットワークコンソール

過学習という言葉は、ニューラルネットワークの話には必ずでてきます。

 

過学習がおきてはいけないと。

 

 

でも、なぜ駄目なのでしょうか?

 

過学習ということは、「勉強しすぎ」なわけです。

 

人間が勉強しすぎで体を壊すとかはあっても、コンピュータが多少勉強しすぎたって、問題ないじゃないか・・などと思えないことはないわけです。

 

なので、今回は過学習ってどうなるのかをやってみて、それを抑制する技術を適用したら、どの程度効果があるのか?どんな動きになるのか?・・を確認してみます。

 

2017/12/01追記

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

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

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

 

過学習を発生させるためのデータを準備する

ニューラルネットワークコンソールを立ち上げる前の準備作業が必要です。

 

過学習を発生する主な条件と言われているのは以下の2つです。

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

 

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

 

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

 

エクスプローラで、

ニューラルネットワークコンソールフォルダ}\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行目から下のデータをスパッと消して、上書き保存します。

 

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

 

過学習が発生するかやってみる

 

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

 

まず、さっき作った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

 

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

 

以下のようなシンプルな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タブを開きます。

f:id:arakan_no_boku:20170829215904j:plain

 

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

 

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

 

次に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%は大きいですね。

 

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

 

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

 

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

f:id:arakan_no_boku:20170829220802j:plain

 

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

 

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

f:id:arakan_no_boku:20170829220920j:plain

 

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

 

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

 

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

 

過学習(Over fitting)の疑い、大いにありです。

 

本来、学習させる目的は、未知のデータの認識精度をあげることです。

 

だから、全く同じデータで100%認識できても、未知のデータの認識精度が落ちてしまうのでは、本来の目的から言えば問題があります。 

 

これが、過学習(Over fitting)が駄目な理由です。 

 

DropOutで過学習を抑制してみる

 

過学習がダメなのは、わかりました。 

 

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

 

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

 

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

 

さて、どうするか?

 

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

 

そして、効果も実証されていたりします。

 

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

 

軽く、説明です。

 

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

 

DropOut と BatchNormalizasion です。

 

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

 

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

 

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

 

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

 

 

この2つは、どちらか一方しか使えないわけではなく、両方とも適用することの方が多いみたいです。

 

この2つのレイヤーはアプローチの仕方が違うので、適切な配置場所も異なります。

 

一般論的には、こんな感じじゃないかなというのを、例で示します。

 

まず、BatchNormalizasion は、計算の後です。

f:id:arakan_no_boku:20170829230120j:plain

 

DropOutは、計算の前です。

 

最初のinputの前というより、ひとつ前の層の結果と次の層のinputの間にいれる感じですかね。

f:id:arakan_no_boku:20170829230351j:plain

 

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

 

やってみます。

 

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

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・・つまり、半分に間引くよ・・ということです。

 

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

 

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

 

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

f:id:arakan_no_boku:20170830000619j:plain

 

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

 

つまり、学習に時間がかかるようになる=Epoch数を増やす必要がある・・わけです。

 

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

 

約2%程度改善したよ

 

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

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

 

f:id:arakan_no_boku:20171115215731j:plain