end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

Relu活性化関数の計算グラフと、微分

「ゼロから作るDeep Learning ① (Pythonで学ぶディープラーニングの理論と実装)」 p.141~142の写経です。

github.com

Relu層のpython実装

# coding: utf-8
import numpy as np

def main():
    relu = Relu()
    x = np.array( [[1.0, -0.5],
                   [-2.0, 3.0]] )
    # 準伝播
    fwd = relu.forward(x)
    print(fwd)
    
    # 逆伝播
    back = relu.backward(x)
    print(back)
    

class Relu:
    def __init__(self):
        self.mask = None
        
    def forward(self, x):
        # 0以下の要素をTrue、それ以外をFalse化
        self.mask = (x <= 0)
        # print( self.mask )

        # Trueの要素位置にものを0化、それ以外はそのまま
        out = x.copy()
        out[self.mask] = 0
        # print( out )
        
        return out
    
    def backward(self, dout):
        # print( self.mask )
        
        dout[self.mask] = 0
        # print( dout )
        dx = dout
        return dx
    
if __name__ == '__main__':
    main()

上記のオライリーのサポートサイトには、 上記のsample codeが掲載されていますが、 特に backward() は、以下が正しい気がします。

# coding: utf-8

import numpy as np

# coding: utf-8
import numpy as np

def main():
    relu = Relu()
    x = np.array( [[1.0, -0.5],
                   [-2.0, 3.0]] )
    # 準伝播
    fwd = relu.forward(x)
    print(fwd)
    
    # 逆伝播
    back = relu.backward(x)
    print(back)
    

class Relu:
    def __init__(self):
        self.mask = None
        
    def forward(self, x):
        out = np.maximum(0, x)
        return out
    
    def backward(self, dout):
        dx = np.where(dout>0, 1, 0)
        return dx
    
if __name__ == '__main__':
    main()

計算グラフ

<sodipodi:namedview id="namedview7" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" showgrid="false" inkscape:zoom="0.9888468" inkscape:cx="60.171101" inkscape:cy="265.96638" inkscape:window-width="1651" inkscape:window-height="1329" inkscape:window-x="2955" inkscape:window-y="150" inkscape:window-maximized="0" inkscape:current-layer="layer1" />yxxy==Ly0{(x>0)(x≦0)yx==0{1ReluLy(x>0)(x≦0)(x>0)yxReluLy0(x≦0)