ディープラーニングが世間に広まるようになったのは、2012年頃。画像認識のコンペティションでディープラーニングのチームが圧勝してからだ。
このあたりから、ディープラーニングを使った機械学習モデルが各種state-of-the-artを更新していくこととなる。
DropoutはHinton氏によって2012年に提案された、ニューラルネットワークの過学習を防ぐためのシンプルかつパワフルな手法だ。
本記事では、
- Dropoutとはなにか
- Dropoutの実装方法
- Dropout最適化のコツ
を紹介する。
Dropoutとは何か
ニューラルネットワークの構造が複雑化していくにつれて、ニューロンの重みは訓練データセットに最適化されていってしまう。汎化作用が働かず、1つ1つのデータを暗記していくように、訓練データセットにしか使えない貧弱なモデルとなる。
訓練データの正答率は徐々に上がっていくが、テストデータの誤差は減少が止まり、また増加しはじめるのだ。このような状態を過学習という。
ニューラルネットワークの過学習を防ぐ方法は4つある。
- 訓練データセットを増やす
- モデルの複雑性を減らす
- Early Stopping(早期終了)
- モデルの複雑さにペナルティを与える(正則化)
Dropoutはニューラルネットワークの過学習を防ぐために提案されたテクニックで、一定の確率でランダムにニューロンを無視して学習を進める正則化の一種だ。
以下の図を見て欲しい。
このように、ノード間が全て繋がったニューラルネットワークを下の図のように、学習時には一定の確率で無視する。
こうすると一時的に、ニューロンが活性化しなくなる。そして重みの更新もバックプロパゲーション時にされない。
機械学習の分野には、アンサンブル学習といって複数の認識器の出力結果を利用することで効果が上がることが分かっている。複数の構造を持つニューラルネットワークを個別に学習させ、各識別器の出力の平均値を認識結果とする。
Dropoutにはこれと同様の効果があり、複数の独立したニューラルネットワークを学習しているとみなすことができる。訓練時にランダムでニューロンを消去していくことで、毎回異なるニューラルネットワークを学習していることになる。
複数のニューラルネットワークの合議制で予測をすると、より良い結果になることが分かっているが、その分計算コストが増大する。 Dropoutはただ訓練時にランダムでニューロンを選択していくだけだ。これならお手軽にアンサンブル学習できる。
Dropoutを実装してみよう
それでは、Dropoutを試してみよう。TensorFlowのラッパーTFLearnを使って、クレジットカードの加入審査をニューラルネットワークで学習してみよう。
TFLearnのインストール
TensorFlowは事前にインストールしておこう。
- 機械学習ライブラリscikit-learn
- Deep LearningフレームワークTFLearn
をインストールする。
$ pip install sklearn tflearn
Dropoutを適用するコツ
実装する前に、Dropoutを適用していくコツを紹介しよう。提案者のHintonらは、チューニングの方法に関しても示唆している。
Dropout: A Simple Way to Prevent Neural Networks from Overfitting
Dropoutを使うときのいくつか便利なヒューリスティックスをあげている。
以下のような方針でDropoutを適用していこう。
- 控えめなサイズでニューラルネットワークを構築する
- 過学習を起こすまでネットワークのサイズを大きくしていく
- 過学習を起こしたら、入力層にDropout率0.2、隠れ層に0.5を適用する
- パラメータを微調整
- テスト時にはDropoutは使わない
クレジットカードの審査判定を自動化する
クレジットカードの審査判定を学習させてみる。
こちらから
「Data Foloder」をクリックしてcrx.data
をcredit.csv
として保存する。
headコマンドで中身を見てみよう。
$ head credit.csv
b,30.83,0,u,g,w,v,1.25,t,t,01,f,g,00202,0,+
a,58.67,4.46,u,g,q,h,3.04,t,t,06,f,g,00043,560,+
a,24.50,0.5,u,g,q,h,1.5,t,f,0,f,g,00280,824,+
b,27.83,1.54,u,g,w,v,3.75,t,t,05,t,g,00100,3,+
b,20.17,5.625,u,g,w,v,1.71,t,f,0,f,s,00120,0,+
b,32.08,4,u,g,m,v,2.5,t,f,0,t,g,00360,0,+
b,33.17,1.04,u,g,r,h,6.5,t,f,0,t,g,00164,31285,+
a,22.92,11.585,u,g,cc,v,0.04,t,f,0,f,g,00080,1349,+
b,54.42,0.5,y,p,k,h,3.96,t,f,0,f,g,00180,314,+
b,42.50,4.915,y,p,w,v,3.165,t,f,0,t,g,00052,1442,+
最後のカラムに判定結果が+/-で入っている。 残りはカテゴリ変数や連続値になっているようだ。
次に必要なライブラリをインポートしてCSVを読み込む。
target_column
は正解ラベルとなるので、-1を指定すると最後のカラムとなる。
n_classes
には+と-の2クラス分類となるので2としておこう。
データの前処理をする。数値は0~1に正規化して、カテゴリ変数はone-hotベクトルとしよう。
訓練データとテストデータに分割する。 今回は690とデータ数は多くないので、末尾の20%をテストデータとしよう。
ニューラルネットワークを構築する
それでは、ニューラルネットワークを構築していこう。 今回は中間層2層としてみよう。
まずはDropoutなしで実行
それでは実行してみる。
TensorBoardで可視化してみよう。
$ tensorboard --logdir=/tmp/tflearn_logs
として、ブラウザからlocalhost:6006
にアクセスする。
訓練データの正答率(Accuracy)は90%を超えていくが、 テストデータの正答率(Accuracy/Validation)は途中から下がっていく。
これが過学習だ。徐々に訓練データに最適化されていき汎化作用が働かなくなっていく。
隠れ層にDropout0.5、入力層に0.2で設定しよう
それではDropoutを適用していこう。
まずは、Hinton氏の提案通り入力層は0.2、隠れ層は0.5にしておく。
TFLearnのdropout
関数は1-dropout率
を指定する。
として実行しよう。
テストデータで正答率89.9%まで上がった。
TensorBoardで見てみても、先程テストデータで正答率が下がっていたのが抑制されているのが分かる。
オレンジ色がDropoutなし、Dropout付きが黄色だ。
まとめ
本記事では、ニューラルネットワークのニューロンをランダムで取り除いて学習していくことで過学習を抑制できることを見てきた。
そして、Dropoutの使い方・最適化のコツも合わせて紹介した。
最近では、Dropoutの他にもモデルの過学習を防ぐ方法は他にもいくつか提案されている。
そちらも、後に紹介していきたい。