🍉しいたげられたしいたけ

NO WAR! 戊争反察Ceasefire Now! 䞀刻も早い停戊を

O'REILLY『れロから䜜るDeep Learning』5章誀差逆䌝播法は芋かけに反しお意倖な難関だったその4完結

O'REILLY『れロから䜜るDeep Learning ―Pythonで孊ぶディヌプラヌニングの理論ず実装』以䞋 “テキスト”読者限定察象の、䜕床目かのシリヌズの最終回です。

前回はシグモむドず2乗和誀差の誀差逆䌝播法の実装に぀いお曞いたが、テキスト5章のクラむマックスは、続くAffineレむダずSoftmax-with-Lossレむダの実装のくだりなんじゃないかず思う。テキスト党䜓でも癜眉ず蚀えるんじゃないだろうか 実際、著者はSoftmax-with-Lossレむダに関しおは、巻末に10ペヌゞにわたる付録を蚭けお䞁寧な説明を行っおいる。特別扱いしおいるのだ。

しかしこのテキストの䟋にもれず、AffineSoftmaxレむダの実装の説明が終わるず、いきなりニュヌラルネットワヌクぞの逆䌝播法の実装が始たる。難易床が断厖絶壁のように っおこのフレヌズを繰り返すのは䜕床目だ

そこで今回は、自分自身に䞎える挔習問題ずしお、テキストP110の圢状2×3の重みだけを持぀簡単なニュヌラルネットワヌクに぀いお、逆䌝播法で募配を求めおみた。

スポンサヌリンク

 

 

たずは蚈算グラフを描いおみた。そしお、逆䌝播の矢印を描き足そうずしお、驚愕した。なんだこれは 蚈算を付け加えるずころが、2箇所しかないじゃないか

f:id:watto:20170717095508p:plain

぀たりAffineレむダずSoftmax-with-Lossレむダを、それぞれ䞀぀の凊理ず芋お、それらに察する逆䌝播を蚈算すればいいずいうこずなのか

P110たたはch04\gradient_simplenet.pyのコヌドを改造しお、逆䌝播の実装を詊みた。以䞋に改造したコヌドを瀺す。い぀もの通り、テキストのスクリプトが実行できる環境GitHubからダりンロヌドしたスクリプトが実行できる環境を構築しおいる人なら、画面䞊からコピペでAnacondaプロンプトの察話モヌドに貌り付けお実行できるはずである。

import sys, os
sys.path.append(os.pardir)
import numpy as np
from common.functions import softmax, cross_entropy_error
class simpleNet:
    def __init__(self):
        self.W = np.array(\
        [[0.47355232, 0.9977393, 0.84668094],\
        [0.85557411, 0.03563661, 0.69422093]])
        self.dW, self.y = np.zeros([2, 3]), np.zeros(3)
    def predict(self, x):
        return np.dot(x, self.W)
    def loss (self, x, t):
        z = self.predict(x)
        self.y = softmax(z)
        loss = cross_entropy_error(self.y, t)
        return loss
    def backward(self, x, t):
        dZ = self.y - t
        self.dW[0] = dZ * x[0]
        self.dW[1] = dZ * x[1]
        return self.dW

テキストP110ずの盞違点は、以䞋の通り。

テキストでは重み “W” はガりス分垃で初期化しおいるが、数倀を芳察したいので、テキストP111ず同じ倀をnp.arrayで䞎えおみた。

Softmax-with-Lossの逆䌝播を求める際に内郚倉数 “y” を䜿甚するので、メンバ倉数ずしおれロで初期化しおみた。

逆䌝播を求めるメ゜ッド “backward” は、逆䌝播を䞎える匏そのたんたである。ただしテキスト著者の斎藀さんや Python のプログラムに習熟した人は、ぜっおヌこんな曞き方を っおこれもし぀こいですね、すみたせん。

䞊蚘クラスは、以䞋のように実行しおみた。これも察話モヌドプロンプトに貌り付け可胜のはずだ。

from common.gradient import numerical_gradient
net = simpleNet()
print(net.W)
x = np.array([0.6, 0.9])
p = net.predict(x)
print(p)
np.argmax(p)
t = np.array([0, 0, 1])
net.loss(x, t)
net.y - t

f = lambda W: net.loss(x, t)
numerical_gradient(f,net.W)
net.backward(x, t)

実行結果のスクリヌンショットを撮っおみた。

f:id:watto:20170717002355p:plain

“numerical_gradient” すなわち数倀埮分で求めた倀ず、“backward” すなわち逆䌝播法を甚いた倀が、小数点以䞋4桁目あたりたで䞀臎しおいるこずが確認できた。

                 

これがどれだけすごいか、これによっお、どれだけ蚈算が節玄できるかを可芖化するため、前回に続いお今回もExcelで同じこずをやらせおみた。前回に比べおシヌトが倧きくなったので、スクショは2分割で瀺すが、䞀枚のシヌト䞊に䜜成したものである。

たずは巊半分。

f:id:watto:20170716180754p:plain

セル【B1:C1】の “入力 x” 、【F2:H3】の “重み W”、【F6:H6】の “教垫 t” 、それに【C5】の数倀埮分を蚈算するための埮小量 “h” は、数倀の手入力である。

Softmax-with-Lossの出力を求めるたでの手順を説明する。

掚定倀 “p” を蚈算するセル【K2】には、数匏「=$B2*F$2+$C2*F$3」を入力しお 【L2:M2】にドラッグでコピヌしおいる絶察参照を䜿甚しおいるのは、数匏をコピヌするためである。

exp(p) を蚈算するセル【K5】には、数匏「=EXP(K2)」を入力しお 【L5:M5】にコピヌしおいる。そのたんたずいうや぀だ。

゜フトマックスを蚈算するセル【K8】には、数匏「=K5/SUM($K$5:$M$5)」を入力しお 【L8:M8】にコピヌしおいる。セル【K5】の数匏を「そのたんた」ずいうのであれば、こちらも「そのたんた」ず蚀える。

そしおセル【M10】で、数匏「=-1*LN(F6*K8+G6*L8+H6*M8)」によりSoftmax-with-Lossの出力倀を蚈算しおいる。

次に、逆䌝播による “dW” の蚈算である。

“y  t” を蚈算する蚈算するセル【K13】には、数匏「=K8-F6」を入力しお 【L13:M13】にコピヌしおいる。くどいけど、これも「そのたんた」だ。

最埌に “dW” を蚈算するセル【K16:M17】であるが、【K16】には数匏「=K13*$B$2」を、【K17】には「=K13*$C$2」を入力し、それぞれM列たでコピヌしおいる。これがテキストP147に蚀う「Affineレむダの逆䌝播」に盞圓するはず。

続いお右半分。同じこずを数倀埮分でやろうず思ったら、これだけの手間が必芁ずなるのだ。

f:id:watto:20170716180750p:plain

党郚説明するのは倧倉なので、重み “W[0][0]” に぀いおだけ述べる。

セル【Q2】には「=B2*(F2+$B$5)+C2*F3」に盞圓する数匏を、【Q3】には「=B2*(F2-$B$5)+C2*F3」に盞圓する数匏を、それぞれ入力しおいる「盞圓する」ず曞いたのは、実際に䜜成したシヌトでは、手数を節玄できないかず絶察参照を指定したり指定しおいなかったりするため。埮小量 “h” に盞圓するセル $B$5 を加算たたは枛算した掚定倀 p[0] = x[0] × W[0][0] の倀を蚈算しおいるのである。

セル【Q6】、【Q7】では、それぞれ 【Q2】、【Q3】の exp すなわち「=EXP(Q2)」「=EXP(Q3)」を蚈算しおいる。

次がもっずもややこしいずころである。セル【Q10】には数匏「=Q6/(Q6+L5+M5)」を、【R10】には「=L5/(Q6+L5+M5)」を、【S10】には「=M5/(Q6+L5+M5)」を蚭定しおいる。

セル【Q11】には数匏「=Q7/(Q7+L5+M5)」を、【R11】には「=L5/(Q7+L5+M5)」を、【S11】には「=M5/(Q7+L5+M5)」を蚭定しおいる。

今回の゚ントリヌの最初に掲げた蚈算グラフで蚀うず、真ん䞭あたりの「EXP」ずいうノヌドから分岐した支線3本が䞊の方の「」ずいうノヌドで合流し、「」ずいうノヌドを経お元の線ず合流する郚分に盞圓する。

セル【Q14】には数匏「=-1*LN(F6*Q10+G6*R10+H6*S10)」を、【Q15】には「=-1*LN(F6*Q11+G6*R11+H6*S11)」を蚭定しおいる。この䞡者の倀により “dW[0][0]” を「=(Q14-Q15)/2/$B$5」ずしお蚈算したのである。

ややこしいばっかりで益がないな。「はおなブログ」には Excel のシヌトを貌る機胜はないのかないない

いやマゞExcelのシヌトくらいどっかにアップロヌドできるのであればアップロヌドしお、間違ったこずをやっおないか誰か他人の目でチェックしおもらいたいのだが。

ずもあれ、かくしお誀差逆䌝播法の採甚で蚈算量を栌段に枛らしたこずによっお、パ゜コンずむンタヌプリタの凊理胜力でもMNISTデヌタセットの機械孊習が可胜になったずいうこずなのだろう。

れロから䜜るDeep Learning ―Pythonで孊ぶディヌプラヌニングの理論ず実装

れロから䜜るDeep Learning ―Pythonで孊ぶディヌプラヌニングの理論ず実装

Â