おひとりさま現役パラレルワーカーフクコろぐ

これからの会社員は、複数の収入源をもとう! 会社に翻弄されずアナタらしく仕事ができる。 そんなパラレルワーカーを広めるフクコのブログです。

【文系プログラミング初心者deE資格】ゼロつくディープラーニング #20

f:id:fukuko-parallel-work:20211119210005j:plain

こんにちは!

現役パラレルワーカー フクコです。

f:id:fukuko-parallel-work:20210212204833p:plain



前回の記事↓に続き

www.fukuko-parallel-work.com






来年の2月の試験に向けてE資格試験勉強中のため


E資格とは?の記事はコチラ↓

www.fukuko-parallel-work.com




ゼロつくシリーズでおなじみ

オーライリーから出版されている

ディープラーニングの本格的な入門書でよくおススメされる

「ゼロからつくる Deep Learning」本


f:id:fukuko-parallel-work:20211029220008j:plain




この本↑を毎日5ページずつコツコツこなす

約2か月間で今年中に終了するので

来年のE資格試験までにこれで基礎力をつけることにしました。(^^)


ついつい私は何もないとだらけてしまうので(笑)

毎日5ページ終わった後の記録とまとめを書いていこうと思います。


と、まとめに入る前に…

やる気を出すためのコトバをシェアします!!(主に私のやる気を出すために 笑)



「猪突猛進!!猪突猛進!!」

by 嘴平(はしびら)伊之助


おなじみ私の大好きな鬼滅の刃から

嘴平(はしびら)伊之助の名言です。


炭治郎と同期の鬼殺隊で、鬼滅の刃の主要メンバーの一人です。

伊之助は普段はおバカな発言(でも好きです笑)が目立ちますが、

時には名言と言えるかっこいいセリフを言ったりもします。(^^)


 猪突猛進!!猪突猛進!! そして E資格合格!!


伊之助、どうもありがとう! (^0^)

今日もやる気が出てきました! 

よし!! 今日も頑張るぞ~! お~!! 

というコトで、伊之助のようにガンガン前に出て、今日も私はガンバってノルマをこなしますよ! 笑


ではでは、いい加減まとめに入ります。笑



その前に本の目次の紹介です。

ゼロつくディープラーニングは、下記↓の合計8章で構成されています。

本の目次

  • 5章 誤差伝播法
  • 6章 学習に関するテクニック


ちなみに…

ゼロつくディープラーニング第1章はPython入門のセクション(20ページ分)なので、

とりあえず今回私は飛ばし、第2章からまとめています。

今回は第5章のつづきからでーす。


第5章 誤差逆伝播法のつづき

ココでは、

重みパラメータの勾配の計算を効率よく行える誤差逆伝播法」について学ぶ


5.4 単純なレイヤの実装


これまで見てきた「リンゴの買い物」の例を

Pythonで実装していく。

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

この↑の結果は

↓の図と一緒

f:id:fukuko-parallel-work:20211119222259j:plain


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個の買い物の例の図は↓のとおり。


f:id:fukuko-parallel-work:20211119222353j:plain


そしてこの図のとおり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()メソッドを呼び出すと、求めたい微分が得られる

今日のまとめ


ハイ、今日はここまで!!

今日は5ページなわりにちょっと少なめな感じ。

第5章の誤差逆伝播法はまだまだつづきます!

引き続き頑張りまっす。


最後まで読んでくださり、ありがとうございます!

フクコ


ディープラーニング入門書おススメ本