ITと哲学と

IT系エンジニアによる技術と哲学のお話。

Practical aspects of Deep Learning

CorseraのDeepLearningのコースの学習メモです.

今回はニューラルネットワークを効率的に学習させるための知識を学ぶ.

Train/Dev/Test sets

ニューラルネットワークには様々なHyperParameterが存在する. 実際に各パラメータを試さずして,最適なものを見つける方法は現時点ではなく,効果的に調整することが求められる. この調整では,ネットワークの学習を行い,それを用いて動作確認してみてモデルの性能を確認し,満足するまでパラメータのチューニングを行う.

効果的にこれを実践するために,手元に得られているデータを3つの役割で分けて使い分けることがオススメ.分ける3つはトレーニングセットとデベロップメントセット,そしてテストセットである.

トレーニングセットはその名の通り,モデルの学習時に用いられるデータ群である. デベロップメントセットは,学習済みモデルの性能を確認し,パラメータの調整を行うために用いられる. さらに,テストセットはチューニングが完了した後に,最終的なモデルの性能を確認するために用いられるデータセットである.

基本的にそれぞれの役割にデータは一意に割り当てられ,被らないようにする.

全てのデータをトレーニングセットとして扱い,そのモデルの精度の評価にそこからデータを取り出して用いるような使い方では,過学習の問題を検知することができないので,アプリケーションとして提供する際に所望の性能が得られないからである.

データの割合は,総数が100-10000くらいのレンジであればTrain(60%)/Dev(20%)/Test(20%)くらいの分量に分ける.

さらに総量が増えて1000000くらいの量になって来た場合は,そこまでたくさんのDevセットやTestセットは不要なので,例えばTrain(98%)/dev(1%)/Test(1%)といったようなデータの扱い方でも問題はない.

Bias/Variance

バイアスとバリアンスについて. 学習済みモデルの性能を評価する指標として,バイアスとバリアンスがある.

図1にバイアスが高い状態とバリアンスが高い状態のそれぞれのイメージを示す.

f:id:masamasah:20180817155833j:plain

これは2変数のモデルの分類問題で,決定境界がそれぞれ示されている.

バイアスが高い状態のものは決定境界が線形であり,十分に高い精度の決定境界が得られていない. 一方で,バリアンスが高い状態のものは,決定境界が過剰に複雑になっており,トレーニングサンプルについては高い精度での分類ができているように見える. ただ,未知のデータを分類しようとした場合に,過剰にトレーニングサンプルに適応されており,適切な分類が行えないという問題がある.これはトレーニングサンプルが少なかったり,無駄にモデルが複雑な場合に発生する問題である.

高いバイアスは「トレーニングサンプルについて正しく決定境界が得られていない」状態を,高いバリアンスは「トレーニングサンプルについては満足できる決定境界が得られているものの,未知のデータについては正しくない」状態をそれぞれ指す.

テストセットに対する判定精度とデベロップメントセットに対する判定精度を比較することで,いまモデルがどんな状態にあるのかを図2のように判定することができる.

f:id:masamasah:20180817155848j:plain

Basic Recipe for Machine Learning

バイアスが大きいか,バリアンスが大きいかによって,モデルをより良い精度で動かすためにするべきことが異なる. ここでは,それぞれのケースですべき,基本的な事項を図3にまとめる.

f:id:masamasah:20180817155902j:plain

なので,例えばバイアスが高い状態では,いくらデータを増やしても問題解決には直結しないので注意が必要.

Regularization

ここでは正則化について説明する. 正則化はバリアンスが高い時に試すべき方法の一つで,バイアスを上げてしまうデメリットはあるが,データ採取などのコストをかけずにバリアンスを下げることが狙える手法である.

バリアンスが高い=過剰にくねくねした決定境界になっているという状態であり,これはモデル(W)のそれぞれの値が大きくなりすぎている時に起きる. なので,Wの値が大きくなりすぎないようにすることで,バリアンスを下げることが可能になる.

Wの値が大きくなりすぎないようにするために,ニューラルネットワークの学習時に最小化したいコスト関数に,Wができるだけ小さくなるような項を含めることで,これを実現する.この,できるだけ小さくなるような項はいろんな選択肢があり,図4に示すような場合をL2正則化と呼ぶ.

f:id:masamasah:20180817155915j:plain

このコスト関数を使った際の更新式は図5に示す通りになる. なお,λという値が初めて出て来た. これは正則化の程度を表す値であり,実装者によって調整されるべきHyperParameterの1つである.

f:id:masamasah:20180817155927j:plain

なお,αもλもmも正の値であるため,(1-αλ/m)は1よりわずかに小さい値になるので,この式の意味としては「学習ごとにWを少しだけ小さい値に減衰させていく」ことを意味する.

この直腸からL2正則化は重み減衰とも呼ばれる.

Why regularization reduces overfitting?

では,何故これによってoverfittingが起こらなくなるのかを,感覚的に説明する. なお,overfittingとは高いバリアンスを引き起こすようなトレーニングデータに対する過剰適応のことである.

λを大きくすればするほど,コストに占めるWの大きさの割合が増えるため,Wが小さくなることに対する興味が大きくなる.すると各Wの値は0に近づき,結果としてモデルがより単純な形になるため,overfittingを防ぐことができる.

Dropout Regularization

L2正則化の他にも正則化のテクニックがある. ドロップアウトはその中でも代表的な方法であり,L2正則化と同様によく使われる.

学習時に確率的に各レイヤーのノードを無効化して学習を進めるといった方法で,これを行うことで正則化効果を得ることができる.

Understanding Dropout

ドロップアウトを行うと,学習毎にノードの一部が消滅している状態になるので,学習するモデルが全てのノードをそのまま使う時に比べて小さくなる.その結果,overfittingを防ぐことが可能になる. また,確率的に全てのノードが不通になるので,1つの特徴に強く依存したモデルが作られにくい.1つの特徴に強く依存しているような場合は,特定のWの値が大きくなるが,ドロップアウトによってこれを防ぐことができる.つまりL2正則化と似たような効果が得られるわけである.

Other regularization methods

正則化の方法として他にも,既存のデータを工夫して増やすデータ拡張や学習の早期終了などがある.

Normalizing inputs

この章では,学習効率をあげるための,入力の正規化についてのべる. これを行うことで学習スピードを早めることができる.

簡単に説明すると,図6aのような入力を,図6bのような形に変えてあげることで学習を早めようというテクニックである.

f:id:masamasah:20180817155943j:plain

これを入力に対して行うことで,学習が最適化されやすくなり,学習効率が高まる.

正規化の手順を以下に示す. まず,それぞれの特徴x1,x2について平均μを求める. 次に,各特徴の分散σを求める.

上記の平均と分散を用いて各特徴を図7の式の通り正規化する.

f:id:masamasah:20180817155955j:plain

これで図6bのような平均が0で分散が1の特徴量空間への写像が完了する.

なお,トレーニング時に用いたμとσは取っておいて,予測時にも入力データに対して同様の前処理をかけるようにしなくてはいけないので注意が必要.

Vanising/Exploding gradients

深いネットワークの学習において,勾配爆発/消失の問題がある. これが発生するとモデルの学習が行われなくなる. これの発生原理の説明を行う.

簡単のために,図8のようなネットワークを考える. また,活性化関数が線形写像(g(z)=z)として考える.

f:id:masamasah:20180817160005j:plain

この時y^は図9のように表せる.

f:id:masamasah:20180817160016j:plain

ここで,Wを図10のように初期化するとy^の値が指数関数的に増大もしくは減少する.

f:id:masamasah:20180817160027j:plain

これが勾配爆発/消失の問題である.

Weight Initialization for Deep Networks

上記を完全ではないが,ある程度防ぐことのできる,Wの初期化方法がある. 初期化方法は使う活性化関数によって異なるが,偏差が特定の値になるように調整することで実現される. 図11に活性化関数毎の初期化値を示す.

f:id:masamasah:20180817160040j:plain

Gradient checking

勾配法を実装する際に,デバッグで活用できるGradientCheckingについての解説.割愛.

Gradient Checking Implementation Notes

GradientCheckingを実装する上での注意点を解説している.割愛.