Going Faraway

渡辺遼遠の雑記帳。技術ネタと読んだ本の紹介。

【Deep Learning with Python】ドロップアウト

フランソワ・ショレさんのディープラーニングとKerasの解説本『Deep Learning with Python』の読書メモ。今回で前半部分の第1部は終わり。ここでは、前回に引き続いて正則化の手法のドロップアウトを扱う。

ドロップアウトは、ニューラルネットに対して最も有効であり、最も広く使われる正則化手法で、ニューラルネットの「ゴッドファーザートロント大学のジェフ・ヒントン教授とその教え子によって開発された。ドロップアウトはどのような手法かというと、モデルの訓練時に一定の割合のノードの出力をゼロにする (値をドロップアウトする) というもの。この手法により、過学習を緩和して、汎化性能を向上させることができる。

ヒントン先生がドロップアウトの手法を考案したきっかけについて、本書では本人が語った面白いエピソードが紹介されている。

「私は銀行へ行った。窓口の行員は交代し続けており、私は彼らに何故なのかと聞いた。行員は、自分には分からないと言ったが、彼らはたくさん動き回っていた。私は、窓口係の交代で従業員同士の協力が必要となることによって、銀行詐欺を防げるからに違いないと考えた。」

窓口での顧客対応を、わざわざ複数人で行うのは一見非効率だと思える。しかし、あえて情報共有を必要とする状況を作ると、その過程で意味のない情報は捨てられることになる。そうすることで本質的な情報に対する注意が向けられ、銀行詐欺のような異常事態に気付くことができるのではないか、と言うことなのだろう。

ニューラルネットに対するドロップアウトがうまく働く理由も、これと似ていると言われている。訓練データの偏りによって生じた意味のないパターン (ヒントンが共謀(conspiracies)と呼ぶもの) は、わざとランダムなノイズを入れることでかき消すことができる。そのため、訓練データに含まれる本当に重要な意味のある情報のみが残される。


Kerasでドロップアウトを使う場合には、モデルにドロップアウト用のレイヤーを追加するという形を取る。

dropout_model.add(layers.Dropout(0.5))

ここでDropoutインスタンスに指定している引数 "0.5"はドロップアウト率を表す。ここでは、直前の層からの入力のうち50%がランダムに間引かれ、値がゼロとなることを意味する。

IMDBサンプルのモデルにドロップアウト層を追加したモデルは以下の通り。

dropout_model = models.Sequential()
dropout_model.add(layers.Dense(16, activation='relu', 
                                  input_shape=(10000,)))
dropout_model.add(layers.Dropout(0.5))
dropout_model.add(layers.Dense(16, activation='relu'))
dropout_model.add(layers.Dropout(0.5))
dropout_model.add(layers.Dense(1, activation='sigmoid'))

このモデルは、IMDBサンプル問題で使用したオリジナルのモデルにドロップアウトを足しただけのもの。
訓練時のパラメータは全て同じものを使い、検証誤差を比較したものがこちら。

f:id:liaoyuan:20180219195539p:plain

確かに、過学習が緩和されていることが分かる。