目次
はじめに
計算途中でインデックスを書き間違えたりすると、かなり悲惨な目にあいます。
テンソル要素の2つのインデックスをまとめ上げた行列で考える方が楽で、プログラムを書く時も、行列演算のライブラリを使った方が簡潔で演算速度も速いです。
ただ逆伝播を考える際に、行列で偏微分した損失関数 のチェーンルールでの展開は、スカラーで偏微分した時と同じようにできるわけではないので注意が必要です。
また、ネットワークが複雑になった場合は、大量に計算式を書くことになるので、行列で書いたとしても訳が分からなくなってしまいます。
そういった場合は、計算グラフというものを使うと計算がしやすくなります。
計算グラフというのは、演算を数式では無く、ただ絵に書いて表現しただけの物なのですが、いくつかの行列演算について順伝播と逆伝播のルールをまとめておくと、複雑なネットワークになった場合でも楽に計算ができるようになります。
数式で書くよりも絵で描いた方が分かりやすいという訳です。
ここではいくつかの行列演算ルールを計算グラフでまとめて、最後に多層パーセプトロンの順伝播と逆伝播を計算グラフで表してみたいと思います。
行列と行列の和
- 順伝播時に、行列 と を足して とした場合を考えます。
- 要素で書いた場合は、
- これを計算グラフで書くと以下のようになります。
- では今度は が逆伝播でどの様に 、 に展開されるか見ていきましょう。
- 同様に計算すると、
- これを計算グラフで書くと、
- つまり順伝播での行列同士の和の演算は、逆伝播では分岐になります。
行列とベクトルの和
順伝播時に、行列 と横ベクトル を足して行列 とした場合を考えます。
全結合時の閾値の演算になります。
本来は、行列にベクトルを足すと言うのは変ですが、まあnumpyでもこのまま演算できるので、あまり気にせず行きましょう。
要素で書いた場合は以下の様な演算です。
- これを計算グラフで書くと、
- 逆伝播時は、
—
- これを計算グラフで書くと、
- はそのまま分岐しますが、 は を左からかけて分岐します。
分岐
順伝播時に分岐した場合を考えてみます。
行列 が順伝播時に行列 と に分岐する場合、
- 要素で書くと、
- 逆伝播時ですが、 を基準に考えると は と の合成関数になるので、
- つまり逆伝播時は和になります。
行列と行列の積
順伝播時に行列 を左から行列 にかけて、行列 になっている場合です。
入力と重みの掛け算を想定しています。
- 以下要素表記です。
- 計算グラフでは、ドット記号 で行列の積を表しておきます。また、掛け方の順序がわかる様に、掛け算の左側はL、右側はRの記号を書いておきます。
- 逆伝播時は、
—
- 、 の転置をとって にかける形になります。かける順序に注意です。
行列と行列のアダマール積
- 行列 と の同じ場所の要素同士を掛け算したものが行列 になっている場合です。
- 要素表記では、
- 計算グラフは以下の様になります。アダマール積を の記号で表記しておきます。こちらは特に掛け算の順番は気にする必要がありません。
- 逆伝播時は、
—
- 、 をアダマール積で にかける形になります。
活性化関数
- 以下要素表記です。
- 計算グラフで書くと、
- 逆伝播時は、
ソフトマックス関数
行列 をソフトマックス関数 で演算し、行列 とする場合です。
行列演算では表記するのはちょっと難しいでが、無理やり書くと、
は行列の要素を逆数にしてアダマール積でかける演算です。一般的にこの演算を表す記号はありません。無理やり表記です。
要素で書くと、
- 計算グラフでは、特に詳細に表記するのはやめときましょう。活性化関数の時と同じように書いときます。ソフトマックス関数の演算であることが分かるように、下に
softmax
とでも書いておきましょう。
- 次に逆伝播ですが、こちらも行列表記にするのは結構難しいです。
- ソフトマックス関数の微分は、以前の記事多クラスロジスティック回帰の(8)式で求めてました。それを使うと、
は、対角成分を縦ベクトルに並べたもので、まあ無理やり表記です。
逆伝播の計算グラフを無理やり書いてもいいですが、ぐちゃぐちゃになって余計わかりずらくなるので、交差エントロピーと一緒にして書くとよいです。
一応計算グラフにすると、
交差エントロピー
- 要素で書くと、
- 計算グラフではこちらも詳細には書かずに で表記しておいて、下に
cross entropy
とでも書いておきましょう。ソフトマックス関数と一緒にして書いておくことにします。
- 次に逆伝播の計算です。
(24)式同様、 は の要素を逆数にして、アダマール積でかけるという意味です。
ただし、 の要素が1つでもゼロになるとゼロ割りエラーになりますし、ソフトマックス関数の逆伝播の行列表記も厳しいものがあるので、ソフトマックス関数と交差エントロピーを一緒にして、逆伝播を考えるとよいです。
(27)式の、 に(30)式を代入すると、
をどうしよう?と思いますが、 onehot行列である には を計算すると、その対角成分がすべて1になるという性質があるみたいです。
以下確認用スクリプト。
- 実行結果です。ランダムに作成した と ですが、 の対角成分がちゃんと1になっています。
-————————————— B: [[ 0.69070455 0.18605051 0.74967903] [ 0.38630318 0.1353262 0.85122728] [ 0.34214172 0.79788061 0.18338467]] -————————————— Y: [[ 1. 0. 0.] [ 0. 0. 1.] [ 0. 1. 0.]] -————————————— dLdB: [[ 1.44779704 0. 0. ] [ 0. 0. 1.17477438] [ 0. 1.25332034 0. ]] -————————————— np.dot(dLdB, B.T): [[ 1. 0.55928861 0.49535176] [ 0.88070372 1. 0.21543561] [ 0.23318088 0.16960708 1. ]] -————————————— np.diag(np.dot(dLdB, B.T)): [ 1. 1. 1.]
事前に要素で計算していたので、そうなるのはわかっていましたが、なんか不思議な発見ですね。
よって(31)式の続きは、
- すごく簡単にかけました。
多層パーセプトロンの計算グラフ
最後に多層パーセプトロンの順伝播の計算グラフから、逆伝播の計算グラフを機械的に作成し、逆伝播の計算式を求めてみましょう。
順伝播時の中間層( 層から 層への演算)です。
先ず計算式を先に書いてから、その後順伝播時の計算グラフを組み立てていきます。
- 順伝播時の出力層 (全部で 層あるとしています)です。ソフトマックス関数と交差エントロピーが後ろにつきます。
作成した順伝播の計算グラフをもとに、今度は逆伝播の計算グラフを書いていきます。
順伝播の計算グラフを各演算要素ごとに分解して考える事で、逆伝播の計算グラフを機械的に書く事が出来ます。
逆伝播時の中間層の計算グラフです。形式的に と表記します。
活性化関数演算、行列とベクトルの和の演算、行列同士の積の演算の3つの演算要素の逆伝播を組み合わせて行きます。
- 計算グラフが出来上がると、逆伝播の計算式は容易に算出できます。
- 逆伝播時の出力層です。ソフトマックス関数と交差エントロピーの逆伝播をくっつけてます。