fastai動かしてみたLesson5① 誤差逆伝播法

公開日:2019-05-24
最終更新:2019-05-24

今回はLesson5 https://course.fast.ai/videos/?lesson=5

notebookはこちら https://github.com/fastai/course-v3/tree/master/nbs/dl1

誤差逆伝播法

以下はディープニューラルネットの構造がどんなものであるかの図であり、いくつかの層を持っている

層は2種類の層からなり、パラメーター(parameter)をもつ層と、活性化関数(activation)を持つ層がある
パラメーターというのは、モデルが学習するものである
パラメーターはparameters = parameters - learning rate * parameters.gradで求めることができる
つまり、元々あるparametersに学習率と勾配の積を引くことで更新している

そして、これらのパラメーターは入力(input)にかけ合わせることで行列として扱うことになる

黄色の奴は重み行列である
いくつかの入力の活性化かいくつかの層の活性化を重み行列を掛けることで活性化のbunchを得る
活性化というのは数であるが、計算して求められる
入力は計算して求められている数ではないが、活性化と似ていると考えることが出来る

活性化は単なる行列の掛け算の結果として出てくるだけでなく、活性化関数からも得られる

そして、最も大事な事は活性化関数は要素ごとの関数であるという事だ
つまり、それぞれの入力に対してこの関数は適応され、順番に活性化され、そしてそれぞれの入力要素に対応する1つの活性化を作り出している
例えば、20の長さのベクトルから始まる場合は20の長さのベクトルがアウトプットとして得られる
ReLUは活性化関数としていい値を返してくれるので、個々では活性化についてはあまり触れない

実際の値と最終層のアプトプットの値の間の損失関数を使う部分では、重み(黄色い部分)のすべてに対して勾配を求め、そして重みから勾配×学習率を引いて求める
つまり重み = 重み ー 勾配×学習率更新する
これを誤差逆伝播法(Back propagation)という

今回はこれをより詳しく行っていく

Fine tuning

ResNet34では、上記の図の10×5のWeightは、1000×5になっている

これは、ResNetはImageNetを使って1000種類の画像を分類するための物であるためである

しかし、実際にResNetをそのまま使う事はできない
第一に、カテゴリ数は何に対して行うかによって異なるからである
第二に、仮に1000カテゴリのデータを使ったとしても、それはImageNetと異なるカテゴリであるからである

そこで、ResNetをうまく利用するために、Fastaiではこの部分(5×10のWeight matrix)を、二つの新しい重み行列に置き換え、その間にReLUを挟んで利用している

1つ目の新しい重み行列にはデフォルトとして大きさが設定されているが、2つ目には自由な大きさの行列を入れることが出来る



上の図はZeiler氏とFergus氏によってそれぞれの層が画像の中の何に反応しているかを示したものである

層が深くなるにつれ、より特定の物に反応しやすくなっている

しかしながら、ImageNetに対してResNetを使うわけでは無いので、初めの方の層をモデルに導入するほど、それらの重みをそのままにしておく必要がある

Freeze, Unfreeze, Discriminative Learning Rate


Fastaiでは何もせずにLearnerをfit_one_cycleやfitさせるている場合や、Learner.freeze()をする事によって、上図の赤い部分の重み以外を変更しないようにしている
つまり、逆伝播をさせていないという事である

FastaiでResNetなどを利用して転移学習をする場合、ResNetではあらかじめImageNetで10万件?位の大規模なデータを基にして重みを決定しているので、重みを変更させずとも初めからある程度良い結果が得られる

unfreezeを行った場合は、上図の赤い部分以外の重みを可変にする、つまり逆伝播させて変更する事で、より訓練データに基づいたモデルを作れるようになる

Discriminative Learning Rateとは、学習率を複数に分けて考える事である
初期の層の学習率は小さく結果もすでに良い物であるため、そこからの変動はあまりない
しかしながら、実際にはもしより高い学習率を使えばより良い結果を得ることが出来る場合もあるので、学習率を複数設定した方が良い

Affine Function(全結合関数)

畳み込みというのはいくつかの重みが結び付けられた行列の掛け算である
そこで、ここではより正確にこれらをAffine Functionと呼ぶ

協調フィルタで使っていたモデルを見てみよう

左の5列と上の5列は重みであり、表の中身はそれらの行列の掛け算の結果である

つまり上図のような事である

この表を前回やったように最適化すると、平均二乗誤差は0.39になる
目的としている値は0.5~5の幅の数値であるので、平均して0.39だけ間違っているという事がわかり、かなりいい結果です

Embedding

Embeddingを理解するために、movielens_1hotのシートを見てみよう
左のUsers,MoviesはそれぞれのIDで、オレンジ色の部分はそれに対する重み行列である
初めは重み行列はランダムに設定されており、勾配降下法で訓練することが出来る

そのままのIDだと扱いづらいので、右側のuser idx, movie idxのように番号を振りなおしている
また、それぞれのIDを0と1の行列として扱うようにする(水色のセル)
これをone-hotエンコーディングという

activationsにある行列は入力の行列であり、これが一般的なニューラルネット層への入力である

重み行列は15行あり、One-hotエンコーディングの列は15列あるので、行列計算を行うことが出来る

予測値はuserとmovieの重みをSUMPRODUCTしたもの(SUMPRODUCT:http://www.eurus.dti.ne.jp/~yoneyama/Excel/kansu/sumproduct.htm)
Lossは実際の目的値から予測値を引いたもので
Lossの平均を取ると0.39になる
これは、Excelのソルバーで行った結果と同じである

上図はdotprodのシートで、赤と紫の枠の部分はUserとMovieのEmbeddingのベクトルであり、行列の掛け算をただ行っている


上図はレイアウトを変えたmovielens_embのシートであり、オレンジ色の部分が重み行列(embedding)である
また、オレンジ色の部分以外にも重み行列はあるが、これはExcelのOFFSET関数を使う事で得られる物である
これによってone-hotな行列を利用しないので、もっと早く計算出来るようになる
one-hot行列で掛け算を行う事は、ある行列を検索する事と同じである
つまり、毎回行列を検索するという事である。したがってone-hotな行列によって行列の掛け算を行う事を、実際にone-hot行列を作る事なしに行いたい

その具体的な方法としてembedding(埋め込み)が挙げられる
これは、整数の束を渡す事で、それらがone-hot encodingされてないものとする方法である

何か行列をone-hot encoding行列を掛けることによって得ることは、重み行列の行がユーザーIDを得る所だけに値が現れる
つまり、特定の重みの行列が特定の値に対応する重み行列となるアウトプット活性化層はこれらの2つの行列を掛けることによって得られる
つまり、それらの数(ここではembeddingとID)はお互い対応しなければならないという事である

例えば、userのembeddingが高く、movieのembeddingが高ければ、userはおそらくそのmovieを好むという事がわかる

従って、これらの数字はuser個人の嗜好の特徴と、それに対応する映画の特徴を示している

ここでは実際に行を決定するわけではない
また、行を意味のある物にするために何かするわけでもない
この勾配降下が良い結果を出す方法はuserがどんな嗜好を持っているか、そしてmovieにどんな特徴があるかを把握する事である
そのため、これらのlatent factorsあるいはlatent featuresといった要素は、ニューラルネットを訓練する事によって得られる

Bias

例えば、「Battlefield Earth」を好きになる人が居ないとする
また、「John Travolta(実在するアメリカの俳優)」が出演している映画はいい映画ではないとする
では、これらの要素をどのように扱えばいいだろうか?
なぜならJohn Travoltaの出ている映画が好きだという要素があり、そして映画がJohn Travoltaが出演しているという要素を持っていた場合、好みの映画であると考えることが出来る
しかし、ここで何らかの方法で「Battlefield Earthではない」かつ「あなたは科学者ではない」という方法を持っておく必要がある
その方法としてbias(バイアス)を加えるというものがある

上図はbiasのシートである
一見さっきと同じように見えるが、追加の行がある
この行は「これはいい映画だ」vs「これはいい映画ではない」という数値を持ち、また「高く評価する」vs「低く評価する」といった数値である
この数値をBias(バイアス)という

記事が少しでもいいなと思ったらクラップを送ってみよう!
0
+1
大学生の書きなぐりブログ 間違ってる事も書いてるので自己責任で勉強しましょう

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする