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

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

過学習の発生と過学習を抑制する技術をGUIで体験:使い方8/ニューラルネットワークコンソール

わざと「過学習」の状態を発生させて、それを抑制する方法がどのくらい効果があるのかをGUI操作だけで体験してみようと思います。

 

この記事の対象読者は、文系で数学は苦手でプログラムも得意ではないけど、人工知能・・特に深層学習(ディープラーニング)の技術には興味があるという方を想定しています。

 

また、続きもの的に前回からの引き続きで書いている部分もあるので、まだの方は、下記の一覧で使い方1から順番に読んでもらえると、よりわかりやすいかと思います。

arakan-pgm-ai.hatenablog.com

 

特に、この記事は数回前からの続きものでやっています。

 

この回から初めて読まれる場合は、最低限、以下の「使い方5」から順番に読んでいってもらえると、よりわかりやすいのでおすすめします。

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

 

さて、本題です。

 

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

 

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

 

過学習を抑制するための方法論とか。

 

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

 

人間が勉強しすぎで体を壊すとかはあっても、「コンピュータが多少勉強しすぎたって、何が問題なんだ」などと思いませんか。

 

実際、そんな風に「過学習」という言葉は知ってるし、よくないことも知ってるが、いまひとつ具体的にイメージできてない人にも、よく会います。

 

だから、やってみよう・・ということです。 

 

 

過学習のための少ないデータ・セットの準備

さて、前回まで読んでいただいている前提で話をすすめます。

 

いつもなら、まず、ニューラルネットワークコンソールを立ち上げます。

 

でも、今回は、その前に準備がいります。

 

過学習をわざと発生させる環境と整えないといけません。

 

過学習を発生させるには、「学習データが少ない」か「非常に複雑なネットワークである」などの条件を満たす必要があります。

 

とりあえず、簡単な方「学習データを少なくして、無理やり過学習を発生させる」やり方をとりましょう。 

 

ここは、あまり手間をかけずに、既存のものを加工して、「少ない学習データ」を作ります。

 

エクスプローラで、

ニューラルネットワークコンソールフォルダ}\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

 

さて、プロジェクトの一覧に戻って、前回保存したプロジェクトを開きましょう。

f:id:arakan_no_boku:20170826132310j:plain

 

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

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

 

正確さが 96.2%と、かなり下がりました。

 

約3%は大きいですね。

 

さて、DATASETタブをもう一度開いて、今度はValidationの方も、先程のtraining用と同じCSVファイルに変更してみます。

f:id:arakan_no_boku:20170829220802j:plain

 

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

 

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

f:id:arakan_no_boku:20170829220920j:plain

 

学習データに最適化しすぎて、学習データと異なるテスト用データでの認識精度が落ちてしまっている・・ようするに、過学習(Over fitting)の疑い、大いにありですね。

 

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

 

だから、全く同じデータで100%認識できても、未知のデータの認識精度が落ちてしまうのは、問題なのです。 

 

なんとなく、過学習がなんでダメなのかは、わかりますねえ。

 

過学習を抑制する技術を試してみる

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

 

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

 

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

 

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

 

さて、どうするか?

 

実際のところ、すでに頭の良い人達が、過学習を抑制する手法をいくつか考案されていて、効果も実証されていたりします。

 

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

 

軽く、説明です。

 

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

 

DropOut と BatchNormalizasion です。

 

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

 

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

 

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

 

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

 

こんな感じですかね。

 

この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 を使うと、どちらも、学習をなだらかにすすめる方向に働きます。

 

つまり、学習により時間がかかるようになるわけです。

 

それもかなり。

 

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

 

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

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%からは相当改善しました。

 

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

 

そういう結果です。

 

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

 

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

 

これが、感覚的によくわかりますよね。

 

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

 

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

 


前の記事

 

関連カテゴリの一覧(この一覧で使用法1から順番に読むのをおすすめします)

arakan-pgm-ai.hatenablog.com

 

f:id:arakan_no_boku:20170910161122j:plain