ディープラーニングのお勉強体験記”30:番外編「XP」の各sin波コード”(リカレントニューラルネットワーク”RNN”を中心にバックプロパゲーション”BPTT”を数式を使って理解したい!)

イメージ
「ゼロから作るDeep Learning 2 ―自然言語処理編」のRNNコード、P216、第5章「5.5.3 RNNLMの学習コード」から作ったWindows XPの各sin波コード 前回「Windows xp」でAnacondaを使えるようにしたと紹介しました。でもって、ここではそこで動く「sin波学習コード」紹介します。わざわざ紹介する内容でもないかもしれませんが、、、、、、 「Jupyter Notebook」を使うということと(普段は「Jupyter Lab」を使ってます)、コードの先頭部分に「%matplotlib inline」を追加する、グラフの表示部分をちょっと書き換えるだけ(1波形1コマンドラインにする)と、簡単ですから、、、、、 でもまあ、一応書かせてもらいます!(簡単なことでも、それなりに苦労はしていますので) 目次 1:xp用のRNNのSIN波コード 2:xp用のLSTMのSIN波コード 3:xp用のGRUのSIN波コード 1:xp用のRNNのSIN波コード # 完成版 Windows xp用 RNNコード # ゼロから作る Deep Learning2のP216、第5章「5.5.3 RNNLMの学習コード」でコード全体が見えるようにできるだけ「import」を外した # プログラムの動作検証用にSINカーブを学習させるため変更したコード # coding: utf-8 # import sys # sys.path.append('C:\\kojin\\資料\\AI関連\\ゼロから作る Deep Learning\\ゼロから作る Deep Learning2\\deep-learning-from-scratch-2-master\\') %matplotlib inline import matplotlib.pyplot as plt import numpy as np # from common.optimizer import SGD # from dataset import ptb # このimportを有効にするには上記パス設定「sys.path.append('C:\\kojin\\AI関連\\・・・」が必要! # from simple_r...

ディープラーニングのお勉強体験記”23:GRU数式導出”(リカレントニューラルネットワーク”RNN”を中心にバックプロパゲーション”BPTT”を数式を使って理解したい!)

「ゼロから作るDeep Learning 2 ―自然言語処理編」から変更したGRUコードの数式導出


いままでと同じように、コード全体が見えるようになったので、アルゴリズムを追いかけやすくなりました。


ということで、また、いままでと同じように次のステップは「ゼロから作るDeep Learning 2 ―自然言語処理編」P216、第5章「5.5.3 RNNLMの学習コード」を変更したGRUコードでバックプロパゲーションの数式を導くことにします。


GRUの構造は

となっています。

これをもとにバックプロパゲーション(誤差逆伝搬)の数式を導いていきました。

(いままでと同じで、以下ウェイト:wについて書きます、バイアス:bは端折っています)

スタートの式は


と書けるでしょうか、、、、、

g=z、rの場合、「σ()」はシグモイド関数で、

です。


ここでちょっと注意というか、私が困ったことです。GRUの数式の導出は、LSTMと同じように表記したかったのですが、、、、、、、、

GRUコードでは、変数に「h」を使って、活性化関数にも「h」を使っていました。(正確には活性化関数のhは「h hat」でhの上に帽子が乗っていますが、、、、)

こういう感じです。この絵はこのサイトからお借りいたしました。(絵は、少しだけいじっています)

これは、扱い難くて困りました。ということで、LSTMでは活性化関数を「f」などと表記しましたが、GRUでは「z」などの活性化関数は「az」などどと表記しています。

(まあ、LSTMの表記方法をGRUに合わせれば良いのですが、現時点では「心が折れている」ので、、、、、、、いずれ、気持ちが復活すれば書き直そうかなと思っています)


で、本題に戻って、求めたいのはWxとWhの誤差勾配なので

Wxに対しては、g=h,z,rのすべてに対して

と導けて、

Whに対しては、g=z,rに対して

と導けて、

g=h に対しては、活性化関数uhのWh側の項が

と、3項で、Wx側の項と比べて、1項多いので、
と計算されます。
「ar」の項がおまけで付いてますね。
これらの式を見ればわかりますが、
が共通しています。

ほぼほぼRNNの時と同じ感じで、WxとWhに共通したdL/da・da/duを導ければ誤差逆伝搬が計算できるということになります。そしてこのdL/da・da/duはLSTMよりだいぶ複雑になっています。

ではまず、dL/da・da/duを具体的に求めてみます。

(以下 「・・・と導けます」 と書いていますが、「dL/dh」が現れるように意図的に変形しています、たぶんこれは「式をコードにするための計算」の「センス」が問われる部分ではないのかと思うのです(たぶんですけど、、、)、LSTMのところでも書きましたけど、よくもまあ、誰だか知らないのですが(ここでも開発者に失礼です、すみません)こんな大変な計算したなあー、、、と、やっぱりものすごく尊敬してしまいます。(繰り返しになりますがパイオニアは、ほんと大変で、欧米の社会の人たちの底力を感じずにはいられません!!!!))

g=hの場合は、

と導けます。この計算には、

を使っています。

g=zの場合は、

と導けます。この計算には、

を使っています。

g=rの場合は、ちょっと計算が複雑になります。その理由はuhが、arを介して、urの関数となっているためで、


という関係があるためです。

この関係を使えば「dL/dur」は、「dL/duh」に書き換えられて

と計算されます。

で、最後の式の最後の項は、

となりますので、最終的に

が得られます。

以上をまとめると、(つまり g=h、z、r の場合)

となります。

この3つの式から、

が共通しているので、これを求めれば、良いことがわかります。というわけで、ここから「dL/dh」をバックプロパゲーションで求めることを考えていきます。

ということで「dL/dh」を「(l+1)層」と「(t+1)層」の勾配で展開しますと


と、なります。

ここで最後の項は、hについて


という関係があるので、和は、「j」の項のみが残り、


と求まります。
で、次の計算として上の式のうち、下のように四角で囲まれた部分については、

この下のように、(l+1)層側に対しては
と、なり、同様に、(t+1)層側に対しては

と導けます。(最後の項はポイントですね。GRUでは、層方向と時間方向の逆伝搬では式が微妙に違うんですね。)
でもって、今までの導出した式をまとめると、下記のようになります。


これが、GRUのバックプロパゲーション”BPTT”の式になります。

この式をよく見ると、(l+1)層の部分と(t+1)層の部分では数式に微妙な式の違いが見られていますね。ここは、GRUがLSTMと決定的に違うところだと思っています。
LSTMの場合は、(l+1)層の部分と(t+1)層の部分では数式の形は同じです(”「ゼロから作るDeep Learning 2 ―自然言語処理編」から変更したLSTMコードの数式導出” を参照してください)

この次は、GRUのコードと数式の関係を書こうと思っていますが、GRUのコードはLSTMのコードより複雑にみえます。

それは、GRUでは、この
「(l+1)層の部分と(t+1)層の部分では数式に微妙な違いがある」
ことが理由のようです。


以上です。



コメント

このブログの人気の投稿

ディープラーニングのお勉強体験記”17:LSTM数式導出”(リカレントニューラルネットワーク”RNN”を中心にバックプロパゲーション”BPTT”を数式を使って理解したい!)

ディープラーニングのお勉強体験記”30:番外編「XP」の各sin波コード”(リカレントニューラルネットワーク”RNN”を中心にバックプロパゲーション”BPTT”を数式を使って理解したい!)

ディープラーニングのお勉強体験記”18:LSTMコードと数式”(リカレントニューラルネットワーク”RNN”を中心にバックプロパゲーション”BPTT”を数式を使って理解したい!)