ITと哲学と

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

ML Strategy (1)

この週と次の週では機械学習プロジェクトを進めていくための戦略について説明する.

Why ML Strategy

MLプロジェクトを進めていくための戦略がなせ必要なのか?

モデルの精度が例えば90%であるとした時,それをさらに改善するためにどんなことをしたらより改善できるのか?という判断を適切に行えることはプロジェクトの効率や進捗に大きく影響する.

そのため,この週と次の週で話される戦略を理解し,活用することが大切になる.

Orthogonalization

日本語でOrthogonalizeationは直交という意味. 機械学習プロジェクトにおけるモデルの調律時に意識すると良い考え方として「Orthogonalization」がある.

これは,1度に1つのものを変えてみるということ.

まず調律においては,はじめに「教師データによりよくフィットするように」という点に絞って調律を行う.次に「バリデーションセットによりよくフィットするように」という点に絞って調律を行う.

同時に双方を満たすように調整するのではなく,それぞれ独立して調律を行うことが効率的な進め方につながる.この考え方をorthogolanizationという.

Single number evaluation metric

調律を行う際には,例えば分類制度や処理時間など,複数の指標を最適化しようとして調律すると行った戦略が考えられるが,より効率的な調律を進めるためには,1つの調律するための指標を決めてそれを追い求めるほうが効率が良い.

どのように1つの指標を決めるかについては後ほどの授業で述べるが,例えばF1Scoreなどがある.

Satisficing and Optimizing metric

モデルのパラメータのセットから,最適なものを見つけたい. その際に,複数のメトリクスがあると意思決定が難しいことがある.

例えば,(F1Score,処理時間)がA(90%, 80ms),B(92%, 95ms),C(95%, 1500ms)だとする. この時, F1Scoreだけに着目すると最適なのはCだが,処理時間の観点に着目すると最適なのはBとなる.

さらにメトリクスが増えて,N個になった時,適切な判断を下すのは難しい.

これをうまく扱うための方法として「1つを最適化対象として,他のN-1は制約条件とする」という考え方がある.

例えば,F1Scoreを最適化対象として,処理時間は制約条件とするような考え方である. 「処理時間は100ms以下であること」という制約を課し,その条件下でF1Scoreを最適化するものが良いパラメータセットであると考える.

すると先ほどの例は処理時間が制約条件に収まり,F1Scoreが最適なBがベストな選択であると判断できる.

Train/dev/test distributions

特にDevセットとテストセットについては,同様の発生源からデータを得るようにすることが大切になる. トレーニングセットを使い,パラメータを決めて学習したモデルを,Devセットで評価して,最適なパラメータに調整していく.その際に,Devセットとテストセットがかけ離れていると,その調整が全く意味をなさなくなってしまう. これを避けるためにも,Devセットとテストセットは同一の発生源からデータを取得できるように心がけるほうがいい.

Size of the dev and test sets

データ総量がそんなに大きくなかったこれまでの世界では,教師データとして総量の60%を,Devセットとして20%,テストセットとして20%を使うようなバランスが多かった.

近年,扱えるデータ量の増加に伴って,母数が増えたので,総量の20%をDevとテストセットに使う必要は必ずしもなくなった. 最近では98%を教師データとして使い,残り1%づつをDevセットやテストセットとして扱うケースもある.

さらに,テストセットは最終的なシステムのパフォーマンスを推定するためのものであり,最終的なシステムのパフォーマンスの推定が不要であれば,テストセットを用意しないという選択もありうる.

When to change dev/test/ sets and metrics

メトリクスがモデルの「良さ」を直接的に反映していないことがわかったら,メトリクスを変更する必要がある.

例えば,誤差1%で動くがミスした際に大きな事故がつながるAモデルと,誤差5%で動きミスしたとしても事故には繋がらないBモデルがあるとする.

メトリクスを誤差率にすると,モデルAの方が良いように見えるが,実際には事故が起きると様々な損害につながるため,メトリクスとしては誤差率だけでなく,事故の大きさのようなものも含むべきである.

このようなことが後から判明したら,そのタイミングでメトリクス自体を変更する必要がある.

Why human-level performance?

機械学習によるタスクの精度は近年向上してきており,人の能力と戦えるレベルに進化してきた. 分野によっては人の能力を超えるような成果も出始めている.

機械学習の分野では,人の能力に比べてモデルの精度がどの程度か?という問いが,重要な指標として扱われている. 機械学習のモデルの到達可能な最大精度を見積もるために,人の能力が活用できるからである.

到達可能な理想的な最大精度に達した際に残る誤差をBayesOptimalErrorと呼ぶ. 人のパターン認識力や識別力はとても高く,BayesOptimalErrorと人間の限界値は近しい.

そのため,モデルが到達可能な精度として,人の識別能力がBayesOptimalErrorを間接的に示す指標として扱われるのである.

さらに,別の観点からは,人の能力限界までは,人が教師データを作成できるので,学習に用いる教師データを増やすことが容易いということや,人の能力限界までは,モデルがどのような条件の時に失敗しやすいかを人が理解できるので,最適化しやすいため,人の能力限界までモデルの精度をあげることは,それ以上に引き上げることに比べるとやりやすい.

そのため,図1のような投資する時間とモデルの精度の関係が描ける.

f:id:masamasah:20180827201650j:plain

Avoidable bias

過去の章で,モデルの性能を評価する指標としてバイアスとバリアンスについて考えた. 過去の章で説明したバイアスとバリアンスはHumanLevelError(≒BayesOptimalError)が0であるとして計算したもので,実際は異なる.

バイアスは教師データについての誤差率から,HumanLevelError率を引いた値として定義される.バリアンスは,バリデーションセットデータについての誤差率から教師データについての誤差率を引いた値として定義される.

例えば,HumanLevelErrorが1%で,教師データに対する誤差率が8%,バリデーションセットデータに対する誤差率が10%だとすると,バイアスが7%でバリアンスが2%なので,Highバイアスな状態であると言える. これが,HumanLeverErrorが7.5%のような場合は,バイアスが0.5%でバリアンスが2%なので,Highバリアンスな状態であると言える.

このように,HumanLevelErrorは誤差率の分析を行う上でも重要な指標となっている.

Undrstanding human-level performance

HumanLevelErrorとは具体的にどうやって計算したら良いのか? 例えば以下のような状態を考える.

Task:画像による骨折診断 * 一般的な人の誤差率:1% * 一般的な専門家の誤差率0.5% * エキスパートな専門家の誤差率0.4% * エキスパートな専門家のチームによる誤差率0.3%

この場合は,BayesOptimalErrorはエキスパートな専門家チームによる誤差率0.3%よりも低いと見積もるのが正しい.

Supassing human-level performance

近年では,分野によっては人の能力を超えるような成果が出始めている.

広告配信やレコメンドシステムなど,構造化されたデータを扱うようなタスクの場合に,モデルが人を超えることが増えてきている. 人は構造化データの処理があまり得意ではなく,機械はそれが得意だからである.

構造化されていないような,画像認識や音声認識などの分野においては,一般的には人の能力を超えることは難しいが,近年は扱えるデータ量が増えてきたこともあり,少しずつ人の能力を超えるモデルが出てきている.なので,モデルが人を超えることは不可能ではないので,チャレンジする価値がある.

Improving your model performance

ここまでの内容をまとめて,モデルのパフォーマンスを向上させて行くためのプロジェクトの進め方ガイドラインを示す.

教師データにフィットさせる

まずは,モデルを十分に教師データにフィットさせることを考える. これは,バイアスを下げることを意味する.

モデルのネットワークを大きく,深くしたりする必要があるかもしれないし,学習期間をもっと伸ばす必要があるかもしれない.学習を効率良く進めるために最適化アルゴリズムを変える必要があるかもしれないし,CNNやRNNなど別のネットワークアーキテクチャを試すべきかもしれない.

バリデーションセットにフィットさせる

十分に教師データにフィットしたら,次はバリデーションセットにフィットさせる. つまり,バリアンスを下げる.

もっともっとたくさんの教師データを集めて学習させることでこれが達成できるかもしれない. 正則化(L2正則化やDropOut)することで解決できるかもしれないし,データを水増しするためにデータ拡張を行う必要があるかもしれない. CNNやRNNなど別のアーキテクチャを選択することで解決できるかもしれない.

この2つのステップを,一度に片方にだけ集中して行い,反復させることで効率良くモデルが育って行く.

Hyperparameter tuning, Batch Normalization and Programming Frameworks

CouseraのDeepLearningのコース2つめ最終週. 学習メモです.

Hyperparameter tuning

Tuning process

これまで見てきたように,チューニングするべきhyperparameterはいっぱいある. これをうまくチューニングするためのガイドラインを説明する.

チューニング対象

チューニングするべき対象は以下の通り.

  • 学習率α
  • Momentumのβ
  • Adamのパラメータβ1とβ2
  • Layer数
  • 隠れユニット数
  • 学習率減衰の係数
  • ミニバッチサイズ

このうち,一番大切なチューニング対象は学習率αであり,積極的にチューニングを行う. 次に大事なのはMomentumのβと隠れユニット数,ミニバッチサイズである.これらもチューニングする. そのあとに大事なのがLayer数と学習率減衰の係数であり,これはあまりチューニングしない. 最後に,Adamのためのパラメータはほぼチューニングせずにデフォルトの値を用いることが多い.

チューニング方法

純化するために2つのパラメータを考える.

従来のやり方では,例えばN回の施行ができるとすると,2つのパラメータから√N個ずつ候補を決め,それらをGrid的に全探索して良いものを最適な組み合わせとして使っていた. この方法では,各パラメータについて√N個のパターンを試すことしかできないため,実はあまり効率が良くなかった.

そこで,DeepLearningの世界では,Grid的な探索は行わず,ランダムにN個の候補をパラメータ空間から取り出して探索を行う.こうすることで,各パラメータに対してN個の値を施工することができ,効率が良くなる.

さらに,必要に応じて粗密サンプリングを行う. 粗密サンプリングとは,2つのステップからなるチューニング方法で,

  1. まずパラメータ空間の中で荒く候補点を決めて探索する
  2. 良い結果が得られたサンプル付近からさらに重点的に候補点を抽出し,改めて探索する

という方法である.

闇雲に全探索するより効率が良い.

Using an appropriate scale to pick hyperparameters

必ずしもリニアスケール上でランダムサンプリングすれば良いというわけではないというお話.

例えば隠れユニット数について,だいたい50-100の間くらいに正解があるだろうという状況であればリニアスケール上でランダムにサンプリングして探索すれば問題ない.

一方で,学習率αについて,0.0001から1くらいの間に正解があると思われるときに,リニアスケールでランダム抽出すると効率がよくない.

何も考えずにランダム抽出すると抽出される候補の割合が,0.0001~0.1が10%,0.1~1が90%になる. αのようなレンジの場合,そうではなく,0.0001~0.001と0.001~0.01と0.01~0.1と0.1~1の間のサンプルの割合を等しくしたい.そんな時はリニアスケールではなくログスケール上でのランダムサンプリングを行う必要があるので注意が必要.

Hyperparameters tuning in practice

実践的に効率的にチューニングをする方法について.

使える計算リソースによってチューニング方法を選択する必要がある. 選択肢は2つあり,「Baby sitting one Model」と「Parallel Model」である.

Baby sitting one Model

計算リソースが限られているケースで選択する. コスト関数を観察しながら,学習中にパラメータを手動で調整するようなモデル. 最初はランダムに初期化したパラメータを使い,学習を開始する. コスト関数の値を観察しながら,手動で学習率をあげたり,下げたりする.

このアプローチは別名パンダアプローチとも呼ぶ. パンダは子供が少なく,1人の子供を大切に育てるため. 手塩にかけてモデルを育てていくイメージ.

Parallel Model

潤沢に計算リソースを持っているケースで選択する. 複数のモデルを同時に別パラメータで学習させ,その中から一番良いものを選び出す方法.

前述のパンダアプローチに比べてキャビアアプローチというイメージ. チョウザメは一度に大量の子供を産むので,一人一人を大事に育てることはしない.

Parallel Modelも同様に,たくさん施工して良いものだけを選択する. Baby sitting one Modelのように1つに手をかけたりはしない.

Batch Normalization

バッチ正規化という方法について説明する. バッチ正規化はネットワークをロバストにすることができるため,hyperparameterのチューニングが楽になる.また,学習を高速化する効果も望める.かなり重要なアルゴリズムの1つ.

Normalizing activations in a network

以前,ロジスティック回帰において,Inputとなるベクトルを正規化することでモデルの学習が高速化されることを見てきた.

ニューラルネットワークはロジスティック回帰のノードを積み重ねたようなものであり,各ノードへの入力となる部分を正規化することで学習を早めることができるのではないだろうか,というのがバッチ正規化のアイディアとなる.

なお,実際には各ノードへの入力a=g(z)の正規化ではなく,zの正規化を行うほうが実践的によく用いられる手法であるため,zの正規化を行うものをバッチ正規化として説明する.

バッチ正規化は,ニューラルネットワークを学習する過程のなかで,各隠れ層について図1のような処理を行う.

f:id:masamasah:20180819083017j:plain

ここでΓとβはそれぞれモデル学習時に学習するものであり,学習方法については後述する. ここで大切なのは,Zは一度平均0,分散1に正規化された後で,学習されたΓとβを用いて平均と分散が補正されているという点である.

この補正されたZを用いてニューラルネットワークの学習を進めることになる.

Fitting Batch Norm into a neural network

ニューラルネットワークの中にバッチ正規化を取り入れた全体像を説明する. バッチ正規化を取り入れる前のニューラルネットワークと取り入れた後の違いを図2に示す.

f:id:masamasah:20180819083035j:plain

ざっくりこんなイメージ.

学習したいパラメータは図3のようになる.

f:id:masamasah:20180819083051j:plain

ただし,バッチ正規化によって,Zは一度平均0で分散1の値に変換される. この変換において,平均が0に補正される際に,バイアス項bが0になる. なので,バッチ正規化時には,bはパラメータから意図的に外されなくてはいけない,

これを考慮して,正しい学習対象のパラメータは図4のようになる.

f:id:masamasah:20180819083105j:plain

ミニバッチへの適用

ミニバッチ勾配法へバッチ正規化を適用する際には,平均と分散の計算をミニバッチに含まれるデータのみで毎回計算すること.一旦全ての教師データから平均と分散を計算して補正に用いるようなことはせず,あくまでミニバッチの中でのみ完結させる.

ミニバッチ勾配法へバッチ正規化を適用したアルゴリズム(1epoch)を図5に示す.

f:id:masamasah:20180819083122j:plain

なおこれはスタンダードな勾配法だが,MomentumやRMSpropやAdamについても同様である.

Why does Batch Norm work?

バッチ正規化を行うことで,深い層が入力の変化についてロバストな耐性を得ることができるため,バッチ正規化は有効.

一方副作用もあり,ミニバッチサイズが小さい状態でバッチ正規化を行うと正則化と同様の効果が発生する.ミニバッチサイズを大きくしてバッチ正規化を行うことで正則化効果を下げることは可能.

Batch Norm at test time

学習したモデルを用いて予測を行う際には,1つの入力を処理して出力を得る. 扱う入力は1つなので,平均と分散を求めることができないのでどうするか.

この問題を解決するために,学習時に計算した平均と分散を使う.

学習時には,各バッチごとに各レイヤーの平均と分散が得られる. この各レイヤーごとの平均と分散から指数移動平均を求めてとっておき,それを予測時の平均と分散として用いることでこの問題を解決することができる.

Multi-class classification

これまでは,binaryClassificationの例を見てきた. ここからは多クラス分類について見ていく.

Softmax Regression

これまでは,「この画像は猫か?」というような問題を扱ってきた. ここからは「この画像は猫か犬かひよこかそれ以外か?」という問題を扱う.

上記の例は4つのクラスへの分類と表現できる. 正解ラベルが,猫であれば1,犬であれば2,ひよこであれば3,それ以外であれば0だとする.

これを分類するネットワークは図6のように表せる.

f:id:masamasah:20180819083138j:plain

最終的な層がクラスの分になっている点がこれまでとの違いである. 最終的な層には,各クラスである確率を表現させたい. 例えば,0番目は入力がクラス0(つまりその他)である確率を表現させ,1番目には入力がクラス1(つまり猫)である確率を表現させる.

これを表現させるために最後の層の活性化関数としてよく用いられるのがsoftmax関数である. softmax関数は図7の式で表せる.全てのクラスについて確率を足し合わせると1になる特徴を持つ.

f:id:masamasah:20180819083156j:plain

Training a softmax classifier

多クラスの場合のネットワークの学習について. 損失関数とコスト関数は図8のように表せる.

f:id:masamasah:20180819083210j:plain

このコスト関数において,誤差逆伝播の際に使われる一番はじめの誤差は図9のように求まる.

f:id:masamasah:20180819083225j:plain

あとはいつも通り学習を進めれば良い.

Introduction to programming frameworks

DeepLearningのためのフレームワークの説明. 割愛.

Optimization algorithms

CouseraのDeepLearningコースの学習メモ続きです.

Mini-batch gradient descent

MachineLearningのプロジェクトは反復的にモデルを育てていくような進め方になるので,早く学習を進めることができる仕組みはとても大切になる.

これまで見てきた最急勾配法は明示的なfor文を取り払い,素早く学習が進むようにベクトル化して最適化が効きやすいようにしていた.

とはいえ,サンプル数が大きいと,やはり時間がかかってしまう.

全てのデータを学習の1step毎に使うのはサンプル数の増大に合わせてかかる時間が大きくなりすぎる.

これを解決するために,一度に全てのデータを使う方法ではなく,小さい単位に分けて,ちょっとずつ使っていくような方法がある.小さい単位のことをミニバッチ(mini-batch)とよび,これを活用して勾配法を行うものをミニバッチ勾配法と呼ぶ.なお,これまで通り一度に全てのデータを活用する方はバッチ(batch)と呼ぶ.

50000件データが存在している場合に1000データずつ分けたイメージを図1に示す.

f:id:masamasah:20180818170602j:plain

なお,ミニバッチのインデックスを表す変数としてはtを使う.

ミニバッチを用いた勾配法のアルゴリズムを図2に示す.

f:id:masamasah:20180818170618j:plain

図2の中で,for文がt=1toTまで繰り返されると,全てのデータについての1回の学習が完了する.全てのデータについての1回の学習を行うことを1epochと呼ぶ.

Understanding mini-batch gradient descent

コスト関数の特徴について

全てのデータを毎回使う方法であれば,コスト関数は単調減少するが,ミニバッチ法は毎回ミニバッチに対してのみ処理を行うため,コスト関数は単調減少しない. トレンド的には下がるが,毎回必ず下がるわけではなく,図3のような違いが出てくるという特徴がある.

f:id:masamasah:20180818170634j:plain

ミニバッチサイズの決め方について

ミニバッチのサイズがデータ総量と等しいように設定すると,それはバッチで行う最急勾配法と同義になる. ミニバッチのサイズを1とすると,全てのデータが独立してミニバッチになり,学習1step毎に1つのデータのみを扱うことになる.これを確率的勾配法と呼ぶ.

最急勾配法は全てのデータを1stepに使うので当然時間がかかるという問題がある. 一方で,確率的勾配法であれば1stepに1データしか使わないので,一見すると早そうだが,この状態ではベクトル化の恩恵を得ることができず,逆に時間がかかるといった問題を引き起こす.

なので,ミニバッチサイズは大きすぎず,小さすぎず,いい感じに調整する必要がある. いい感じにミニバッチサイズを決めるためのガイドラインとしては,以下の通り.

  • 小さいデータ量(m<2000程度)であればバッチで行う
  • それ以上であれば,64,128,256,512くらいのサイズから選択する

64,128,256,512はそれぞれ2の累乗であり,計算機で扱う上で最適化が行われ計算速度が上がる可能性があるため,この値を選んでいる. なお,処理するコンピュータの性能と相談しながら,1度に使いたいデータがメモリ上で処理できることも重要な要素となる.メモリ上で保持できない場合はI/Oが走るため,処理が遅くなるためである.

Exponentially weighted averages

勾配法による学習自体を効率化するための方法を以下数章で説明する.

まず,この章では,そのための基礎となるExonentially weighted averages(指数加重移動平均)という考え方の説明を行う.

指数加重移動平均は図5の式で与えられる.

f:id:masamasah:20180818170650j:plain

この式の意味について考えるために,例としてとある地域の気温グラフ(図4)を考える.

f:id:masamasah:20180818170703j:plain

このグラフに対して指数加重移動平均をとると,図4'のように平均気温の推移が得られる.

f:id:masamasah:20180818170715j:plain

Understaning exponentially weighted averages

t=100の場合を考えると,図6に示すように,過去のデータを減衰させながら少しずつ取り入れるような仕組みになっている.

f:id:masamasah:20180818170727j:plain

このように.指数加重移動平均は過去のデータの寄与を取り入れて値の推移を滑らかに表すことができる指標と言える.

なお,指数加重移動平均の最初の方は著しくデータが小さい値になるという問題がある. v0=0として初期化しているので,ある程度tが進むまでは「これまでの値」が存在しないためである. これをいい感じに補正するためにBiasCorrectionという処理を行う. これは単純に,指数加重移動平均の値に図7に示す式を掛け算して補正してあげることを示す.

f:id:masamasah:20180818170739j:plain

Gradient descent with momentum

指数加重移動平均を使って,普通の勾配法より早く学習が進む方法,Momentumを紹介する. 通常の勾配法では,パラメータの更新にコスト関数の微分した結果をそのまま用いていたが,これを指数加重移動平均に置き換える.つまり図8のようなアルゴリズムになる.

f:id:masamasah:20180818170751j:plain

こうすると学習が図9のようになる.勾配の平均が更新に大きく関わってくるので,常に存在する水平方向への学習は加速され,常に符号が反転する垂直方向への学習は行われなくなるのである.

f:id:masamasah:20180818170804j:plain

これによって,学習効率が上がる.

RMSprop

Momentumと似たようなもので,RootMeanSquareProp(RMSprop)という方法もある. アルゴリズムを図10に示す.

f:id:masamasah:20180818170823j:plain

この方法によっても,学習の効率をあげることができる.

Adam optimization algorithm

MomentumとRMSpropを組み合わせた方法をAdam(Adaptive moment estimation)と呼ぶ. アルゴリズムを図11に示す.

f:id:masamasah:20180818170840j:plain

Adamのhyperparameterを図12にまとめる. このうち,αは実装者によるチューニングが大切になるが,他の値はだいたいデフォルトの値を使っておけば間違いはない.

f:id:masamasah:20180818170855j:plain

Learning rate decay

学習の最初の方では学習率を大きく設定することで,学習スピードを高め,学習がある程度進んだら学習率を小さくしてちょっとずつ進みたいと言ったようなこともできる.

学習率に,学習回数をパラメータとした値を掛け算してあげるような式であればこれが実現できる. いくつか種類があるようだ.

The problem of local optima

最適化を進めるなかで,コスト関数が鞍状だった際に学習スピードが遅くなるという問題がこれまであったが,Adamのように,移動平均を用いて同一方向への学習が加速していくような仕組みを採用するとその問題は気にしなくて良くなるので便利というお話.

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を実装する上での注意点を解説している.割愛.

Deep Neural Networks

CouseraのDeepLearningのコース. コース1の最終週分です.

Deep L-layer neural network

2層や3層の浅いモデルでは,性能的に限界があるので,より高い性能を求めて深いニューラルネットワークが活用されるようになった.

浅いニューラルネットワークでは使っていなかったが,新たな記法としてL(総ノード数)を今後は使っていく.

Forward Propagation in a Deep Network

深いネットワークにおける順伝播を定式化する. まず,単純に1サンプルに対する順伝播を考えると,図1のように定式化できる.

f:id:masamasah:20180814184820j:plain

これをmサンプルに拡張し,ベクトル化すると,図2のように表せる.

f:id:masamasah:20180814184830j:plain

これがDeepNetworkにおける順伝播の式となる.

Getting your matrix dimensions right

各実装を行なっていく上で,各行列のサイズを意識してコーディングしていくとバグが減らせる.そこで,この章では各行列のサイズを明らかにする.

図3のようなネットワークを考える.

f:id:masamasah:20180814184844j:plain

この時,1サンプルのみを考えると各行列のサイズは図4のようになる.

f:id:masamasah:20180814184858j:plain

さらに,これをmサンプルに拡張すると図5のようになる.

f:id:masamasah:20180814184912j:plain

なお,b^[l]については,サンプルごとに異なるものを用いるのではなく全てのサンプルに対して同様のものを使い回すこと.

Why deep representations?

深いネットワークにすると,より複雑なことができるようになる.

これをイメージ的に説明する.

例えば顔画像認識のネットワークについて,はじめの方の層は例えば画像のエッジや境界線を検出するような単純なものを検出するために働く. これが,中段の層になると.下位の層の単純なものを組み合わせて例えば目や鼻を検出するようなことができるようになる.

さらに深い層になると,目や鼻を組み合わせて様々な顔のパターンを検出できるようになることで,顔の画像認識が高い精度で実現できる.

このように,下位の層で抽出したシンプルな特徴を組み合わせて,深い層では複雑なパターンの認識ができるようになる.

これによって,より例えば画像認識であればより精度が高まるなど,複雑なことができるようになる.

画像の例だけでなく,例えば音声認識では,下位の層は音の上がり下がりなどの簡易的な特徴を捉えるが,深い層になるについれて音素を識別し,さらに深い層ではそれを組み合わせて単語を識別したりできるようになる.

これが,深い層でより複雑なことができるようになることについての直感的な説明である.

BUilding blocks of deep neural networks

これまでの内容を一枚の図でまとめると図6のようになる.

f:id:masamasah:20180814184929j:plain

ここには深いネットワークにトレーニングデータが入力され,推定値が計算され,その誤差を持ってネットワークが学習するといった1stepが示されている.

これを何度も繰り返して,モデルを学習する.

Forward and Backward Propagation

図6で行う具体的な計算を図7にまとめる.

f:id:masamasah:20180814184951j:plain

Parameters vs Hyperparameters

ニューラルネットのパラメータはこれまで見て来た通り,Wやbがある, これらとは別に,アルゴリズムに与えないといけないHyperParameterがいくつかある. 以下にその一覧を示す.

  • Learning rate α
  • イテレーション数(学習回数)
  • 隠れ層のレイヤー数(L)
  • 各レイヤーのユニット数(n^[1],...,n^[L])
  • 活性化関数としてどれを選ぶか

これらのhyperparameterはアプリケーション毎に調整する必要がある. コスト関数の収束度合いからLearning rateを調整したり,レイヤ数を調整したり,CrossValidationの結果からも様々なHyperparameterを調整する必要がある.

What dose this have to do with the brain?

ニューラルネットの説明として,よく使われる脳に似ているという表現は,ニューラルネットの研究の進歩に伴って,陳腐化してきている.

シナプスニューロンの関係性はわかりやすい類似性がある一方で,その学習過程などについては,脳の学習機構も同様に逆伝播が活用されているのかそうではないのかなど,まだ解明されていない.

CNNの文脈では脳の構造から着想を得た部分が大きいが,一方で通常のニューラルネットについては脳との関連性はあまりなくなって来ているのが現状.

キャッチーでわかりやすいが,厳密性はあまりなくなっているのが現状.

Shallow neural networks

CouseraのDeep Learningコースの第1コースの3週目

Neural Networks Overview

ニューラルネットワークの大枠の説明. 以降の章で話されることが端的に出てくる.

Neural Network Representation

前回学んだロジスティック回帰のノードを複数結合させたようなものをニューラルネットワークと呼ぶ(図1).

f:id:masamasah:20180814151142j:plain

入力のノード群をInput Layer,出力のノードをOutput Layerと呼び,真ん中の層をHidden Layerと呼ぶ.

トレーニングセットにはInputLayerとOutputLayerのデータのみが含まれ,HiddenLayerの情報は含まれない.そのためHiddenLayer(隠れ層)という表現で呼ばれる.

図1のニューラルネットワークは2層のニューラルネットワークと呼ばれ,慣習的にInputLayerはカウントしない.

各レイヤーの出力する値は図2のようにそれぞれa^[i]で表される.

f:id:masamasah:20180814151507j:plain

Computing a Neural Network's Output

各ノードは自身へのインプットと重みの計算活性化関数の処理を行う. 活性化関数は後述するが,ロジスティック回帰のSigmoid関数をイメージすればよい.

図3に第一層で行われる処理のイメージを示す.

f:id:masamasah:20180814151232j:plain

前の章でもあったように,ニューラルネットワークを実装する上では,ベクトル化が重要になる.

図3の処理を2層目にも適用し,ベクトル化すると図4のように表せる.

f:id:masamasah:20180814151253j:plain

Vectorizeing across multiple examples

図4をさらに,トレーニングサンプルについて拡張してベクトル化すると図5のように表せる.

f:id:masamasah:20180814151325j:plain

Explanation for Vectorized Implementation

これまでの振り返りなので割愛.

Activation functions

活性化関数についてのお話. これまではシグモイド関数だった部分について,ほかの選択肢として図6に示す3つがあげられた.

f:id:masamasah:20180814151341j:plain

シグモイド関数は限られた用途のニューラルネットワークでしか用いられない. 代わりにtanhもしくはReLU関数が用いられる.

特にReLU関数はおすすめで,とある問題を解決することができる. とある問題とは,ニューラルネットワークにて最急勾配法を行う際に,活性化関数の微分した形が必要になる際に,引数Zの値が大きくなりすぎることで発生する問題であり,これが発生すると学習の効率が著しく下がる.

引数Zの値が大きくなると,tanhやsigmoid関数の場合,勾配がほぼ0となり,その結果として学習が全く進まないからである.

ReLU関数はZがどれだけ大きくなったとしても勾配は常に一定であり,上記の問題が発生しないという特性がある.そのため,ReLU関数は活性化関数としてよく用いられる.

なお,これまで見てきた4つの関数はいずれも非線形な関数であり,線形な関数は基本的に活性化関数として向かない.その理由は次の章で説明する.

Why do you need non-linear activation functions

図5において,A^[i]を求める際に用いる関数が例えばf(z)=zだったとする(線形関数). すると,図7のように,最終的に1層のニューラルネットワークとして表す値の組み合わせを見つけることができる.

f:id:masamasah:20180814151356j:plain

これは如何に多段にしても変わることはなく,何層にしたところで,線形関数を用いている以上は最終的には1ノードで表すことができる. そのため,表現力の高いモデルにはならず,多段にする意味がない.

これを避けるために非線形な関数を活性化関数として採用しなくてはいけない.

Derivatives of activation functions

次の章で詳細は述べるが,最急勾配法を行うためには活性化関数の微分形が必要になる. 各活性化関数の微分形を図8に示す.

f:id:masamasah:20180814151411j:plain

Gradient descent for Neural Networks

計算グラフから,ニューラルネットワークでの最急勾配法を定式化する. まず,解きたい問題のアルゴリズムを図9に示す.

f:id:masamasah:20180814151428j:plain

これを計算グラフを使って表すと図10のように定式化できる.

なお,np.sum(A, axis=1, keepdims=True)は,Aを縦方向にsumして,得られる解の形を(n,1)とするためのもの.keepdimsがないと,pythonの仕様から,(n,)という形状で返って来てしまうので扱いにくくなる.型を揃えるためのおまじないみたいなもの.

f:id:masamasah:20180814151449j:plain

ここまで,図5では2層ニューラルネットの順伝播による推定を,図10では2層ニューラルネットの逆伝播による学習を定式化した.

これで,2層のニューラルネットの学習並びに推定において必要なことはほぼ出揃った.

次章では細かいことだが,重要な各パラメータの初期化について述べる.

Random Initialization

2層ニューラルネットワークではパラメータがw1,b1,w2,b2と4つあった. このうち,b1,b2については初期化時に考慮しなければならない特別な問題はないので,一般的には全て0で初期化される.

一方で,W1,W2については初期化時にそれぞれの要素をランダムで小さい値で初期化する必要がある.

初期化時にランダムな値ではなく,全て0で初期化すると,各レイヤーにおいて,ノード同士の出力の値が等しくなる.順伝播を繰り返し,誤差を計算して逆伝播する際に,出力が各レイヤー内部のノード同士で等しかったので,等しい値で学習が行なわれる. どれだけ学習を繰り返したところで,各レイヤー間の各ノードの値同士が等しい状況は変わらず,学習がうまくいかない. この問題を対称性の破れという.

これを避けるために,それぞれノードの初期値はランダムで初期化してあげる必要がある.

さらに,初期化の値を大きくした場合,活性化関数としてシグモイド関数tanh関数を用いた場合,微分形の値がほぼ0になるため,学習が進まない.

そのため,各初期値は十分小さい値でランダムに初期化する必要がある.

Neural Networks Basics

CouseraのDeep Learningのコースのお勉強メモpart2

Binary Classification

ニューラルネットワークの説明の前に,先ずは簡単な導入としてLogistic回帰を説明する.

ロジスティック回帰とは,Yes/Noを予測するアルゴリズム. 例えば写真に猫が写っているという問いに対するYes/Noを予測する.

ロジスティック回帰のinputとしては,画像をそのまま使うのではなく,画像のRGBの各ピクセルを1列に並べ替えたベクトルを用いる(図1).

f:id:masamasah:20180813155852j:plain

このベクトルの要素数をnxと呼ぶ.

他にも,数学的な記法として図2のようなものがある.今後はこれを使って行く.

f:id:masamasah:20180813155905j:plain

Logistic Regression

このアルゴリズムでは,inputを受け取って,inputが問いに対してYesとなる確率(0~1の範囲)を計算する. その際のパラメータとしてwとbの2つがある.なお,wはベクトルで,bは実数.

計算方法は図3の通りで,ベクトル同士の内積にbを加えてシグモイド関数をかけたら完成.

f:id:masamasah:20180813155918j:plain

シグモイド関数は図に示す通り,0~1の値をとる関数.

y^が正しい値になるように,パラメータのwとbを学習し,そのパラメータを用いて,Yesとなる確率を計算する.

Logistic Regression Cost Function

ロジスティック回帰では,できるだけy予測値とy(実測値)を近づけたい.

予測値と実測値の近さを評価する関数を損失関数とよび,図4のように表現する. ややこしい数式っぽく見えるが,これはこのあと出てくる最急勾配方をうまく動かすために必要な工夫なので,詳細は割愛.

f:id:masamasah:20180813155931j:plain

全ての教師データ(トレーニングセット)に対して平均的により良いパラメータを求めたいので,全てのトレーニングセットについてどれだけ正しく予測できたかという指標として,Cost関数を図4のように定義した.

これを小さくするためのwとbを探すことが,学習である.

Gradient Descent

最急勾配法についての説明.

Logistic Regression Cost Functionにて,なんだかややこしい損失関数を定義していたが,そのお陰でCost関数が下に凸な形状になる(図5).

f:id:masamasah:20180813155945j:plain

このCost関数を一番小さくするwが求めたい.図中のw_{min}がそれ. これを行うための簡単な方法として最急勾配法がある.

アルゴリズムは以下の通り.

  1. 適当な値にwを初期化する
  2. J(w)の値が小さくなる方向にwを少しだけ更新する
  3. 収束するまで繰り返す

ここで更新する式は図6の通り.

f:id:masamasah:20180813155959j:plain

なぜこれを繰り返すことでw_{min}に近づくかを以下で説明する.

まず,図7のようにw0としてwが初期化される.

f:id:masamasah:20180813160010j:plain

更新式にある微分を計算すると,w0の地点でのJ(w)の傾きがわかる.

w0+であれば微分結果は正の値になるし,w0-であれば負の値になる. これに学習率を掛け合わせて1stepの歩幅が決まり,更新式の通りに更新される.

w0+の場合は微分結果が正であり,aもまた正なので,wは小さくなる方向に更新される. これを繰り返すとw_{min}に近づく.

逆にw0-の場合は微分結果が負になり,aは正なので,wは大きくなる方向に更新される. これを繰り返すことでw_{min}に近く.

最急勾配法はこんな感じでCost関数を最小化するwを見つけることができる.

Derivatives

微分の簡単な説明なので割愛

More Derivatives Excamples

微分の簡単な説明なので割愛

Computaion Graph

順伝播と逆伝播の説明に欠かせない,計算グラフについて説明する. 先ずは簡単な例としてJ(a,b,c)= 3 * (a + b * c)を計算グラフで表すと図8のようになる.

f:id:masamasah:20180813160024j:plain

a,b,cそれぞれに値を入れて,順順に値を伝播させ,Jを求める作業を順伝播と呼ぶ.

Derivation with a Computation Graph

計算グラフを用いて簡単に微分を求めることができる.その方法を逆伝播と呼ぶ.

順伝播とは逆に,最終結果から1つずつ微分を求めて行くと図9のように,a,b,cそれぞれによる微分を簡単に求めることができる.

f:id:masamasah:20180813160037j:plain

この知見を最急勾配法で必要な微分計算に用いる.

Logstic Regression Gradient Desent

計算すると,図10のようになる.

f:id:masamasah:20180813160050j:plain

Gradient Desent on m Example

上記はあくまで1サンプルに対して成り立つ方法だった. これをm個のトレーニングセットについて適用すると図11のようになる.

f:id:masamasah:20180813160105j:plain

Python and Vectorization

実際にコーディングする際には,最適化と並列実行をサポートするために,明示的なFor文を極力書かずに実装する必要がある.このテクニックをベクトル化とよぶ.

これによって実行速度がかなり変わってくる.簡単な例であっても300倍ほどの違いにもつながるので,とても大事なテクニック.

ベクトル化することで図11のFor文があってわかりにくかった記載が図12までシンプルに記載でき,実行速度の面でもかなり有利になる.

f:id:masamasah:20180813160122j:plain