こんにちは!
現役パラレルワーカー フクコです。
前回の記事↓に続き
来年の2月の試験に向けてE資格試験勉強中のため
E資格とは?の記事はコチラ↓
ゼロつくシリーズでおなじみ
オーライリーから出版されている
ディープラーニングの本格的な入門書でよくおススメされる
「ゼロからつくる Deep Learning」本
この本↑を毎日5ページずつコツコツこなすと
約2か月間で今年中に終了するので
来年のE資格試験までにこれで基礎力をつけることにしました。(^^)
ついつい私は何もないとだらけてしまうので(笑)
毎日5ページ終わった後の記録とまとめを書いていこうと思います。
と、まとめに入る前に…
やる気を出すためのコトバをシェアします!!(主に私のやる気を出すために 笑)
「猪突猛進!!猪突猛進!!」
by 嘴平(はしびら)伊之助
おなじみ私の大好きな「鬼滅の刃」から
嘴平(はしびら)伊之助の名言です。
炭治郎と同期の鬼殺隊で、鬼滅の刃の主要メンバーの一人です。
伊之助は普段はおバカな発言(でも好きです笑)が目立ちますが、
時には名言と言えるかっこいいセリフを言ったりもします。(^^)
猪突猛進!!猪突猛進!! そして E資格合格!!笑
伊之助、どうもありがとう! (^0^)
今日もやる気が出てきました!
よし!! 今日も頑張るぞ~! お~!!
というコトで、伊之助のようにガンガン前に出て、今日も私はガンバってノルマをこなしますよ! 笑
ではでは、いい加減まとめに入ります。笑
その前に本の目次の紹介です。
ゼロつくディープラーニングは、下記↓の合計8章で構成されています。
本の目次
- 1章 Python入門
- 2章 パーセプトロン
- 3章 ニューラルネットワーク
- 4章 ニューラルネットワークの学習
- 5章 誤差伝播法
- 6章 学習に関するテクニック
- 7章 畳み込みニューラルネットワーク
- 8章 ディープラーニング
ちなみに…
ゼロつくディープラーニングの第1章はPython入門のセクション(20ページ分)なので、
とりあえず今回私は飛ばし、第2章からまとめています。
今回は第5章のつづきからでーす。
第5章 誤差逆伝播法のつづき
ココでは、
重みパラメータの勾配の計算を効率よく行える「誤差逆伝播法」について学ぶ。
5.4.1 乗算レイヤの実装
レイヤは、
forward()とbackward()という
共通のメソッドを持つように実装。
forward()は、順伝播
backward()は、逆伝播に対応。
forward()では、x,yの二つの因数を受け取り、それらを乗算して出力する。
backward()では、上流から伝わってきた微分に対して、順伝播のひっくり返した値を乗算して下流に流す。
乗算レイヤはMulLayerという名のクラスにして実装↓してみる。
class MulLayer: def __init__(self): self.x = None self.y = None def forward(self,x,y): self.x = x self.y = y out = x * y return out def backward(self, doubt): dx = dout * self.y#xとyをひっくり返す dy = dout * self.x return dx, dy
この乗算レイヤを使えば、
順伝播は↓のように実装できる。
# coding: utf-8 from layer_naive import * apple = 100 apple_num = 2 orange = 150 orange_num = 3 tax = 1.1 # layer mul_apple_layer = MulLayer() mul_orange_layer = MulLayer() add_apple_orange_layer = AddLayer() mul_tax_layer = MulLayer() # forward apple_price = mul_apple_layer.forward(apple, apple_num) # (1) orange_price = mul_orange_layer.forward(orange, orange_num) # (2) all_price = add_apple_orange_layer.forward(apple_price, orange_price) # (3) price = mul_tax_layer.forward(all_price, tax) # (4) # backward dprice = 1 dall_price, dtax = mul_tax_layer.backward(dprice) # (4) dapple_price, dorange_price = add_apple_orange_layer.backward(dall_price) # (3) dorange, dorange_num = mul_orange_layer.backward(dorange_price) # (2) dapple, dapple_num = mul_apple_layer.backward(dapple_price) # (1) print("price:", int(price))#price: 715 print("dApple:", dapple)#dApple: 2.2 print("dApple_num:", int(dapple_num))#dApple_num: 110 print("dOrange:", dorange)#dOrange: 3.3000000000000003 print("dOrange_num:", int(dorange_num))#dOrange_num: 165 print("dTax:", dtax)#dTax: 650
この↑の結果は
↓の図と一緒。
5.4.2 加算レイヤの実装
つづいて
たし算ノードである加算レイヤを実装すると↓のような感じ。
class AddLayer: def __init__(self): pass def forward(self, x, y): out = x + y return out def backward(self, dout): dx = dout * 1 dy = dout * 1 return dx, dy
加算レイヤでは特に初期化は必要ない。
加算レイヤのforward()では、
2つの引数x、yを受け取り、それらを加算して出力。
backward()では、上流から伝わってきた微分(dout)を、そのまま下流に流す。
リンゴ2個とミカン3個の買い物の例の図は↓のとおり。
そしてこの図のとおり、Pythonで実装すると次のとおり。
# リンゴ2個とミカン3個の買い物をPythonで実装 apple = 100 apple_num = 2 orange = 150 orange_num = 3 tax = 1.1 # layer mul_apple_layer = MulLayer() mul_orange_layer = MulLayer() add_apple_orange_layer = AddLayer() mul_tax_layer = MulLayer() # forward apple_price = mul_apple_layer.forward(apple, apple_num)#(1) orange_price = mul_orange_layer.forward(orange, orange_num)#(2) all_price = add_apple_orange_layer.forward(apple_price, orange_price)#(3) price = mul_tax_layer.forward(all_price, tax)#(4) # backward dprice = 1 dall_price, dtax = mul_tax_layer.backward(dprice)#(4) dapple_price, dorange_price = add_apple_orange_layer.backward(dall_price)#(3) dorange, dorange_num = mul_orange_layer.backward(dorange_price)#(2) dapple, dapple_num = mul_apple_layer.backward(dapple_price)#(1) print(price)#715 print(dapple_num, dapple, dorange, dorange_num, dtax)#答えは、110, 2.2, 3.3, 165, 650
↑のPython実装でわかるとおり、
まずは
forward()メソッドを適切な順番で呼び出す。
そして
逆の順番でbackward()メソッドを呼び出すと、求めたい微分が得られる。