ゼロから作るDeep Learning 4.5.1 2層ニューラルネットワーク【ラムダ関数の謎】

経理と機械学習

ラムダ関数の話 loss_W=lambda W: self.loss(x,t)

こんなラムダ関数がでてきます。loss_W=lambda W: self.loss(x,t)

loss_Wの引数Wはloss(x,t)の引数となっていない?

すると引数Wに何を入れてもloss_Wには影響がない?

ネットで検索すると、同じような質問といろんな角度からの回答がいっぱい出てきます。やはり、この本は人気なんだな、と納得。しかし回答はいくつか読んでみたものの、しっくり頭に入らなかったので、単純化したクラスを作ってみてようやく理解できました。まとめておきます。

2層ニューラルネットワークの仕組み

全体はざっくりとこんな感じ。

TwoLayerNet クラス
numerical_gradient(x,t)
 【関数の定義】loss_W = lambda W : self.loss(x,t)
  【勾配】grads[W1] = numerical_gradient(loss_W, params[W1])

loss(x,t)
 y=self.predict(x)
  return cross_entropy_error(y,t)

predict(x)
  a1=np.dot(x,params[W1])+b1
  z1=sigmoid(a1)
  a2=np.dot(z1,params[W2])+b2
  y=softmax(a2)
  return y

関数
numerical_gradient(loss_W, params[W1])
 params[W1]の要素ごとに数値微分を計算
  【勾配】return grads[W1]

cross_entropy_error(y,t)
 return -np.sum(t*np.log(y+1e-7))/batch_size *スカラー値を返す

足し算ネットワーク

loss_W=lambda W: self.loss(x,t)
これを2層ニューラルネットワークで理解しようとするとなかなか頭に入りません。
そこで『足し算ネットワーク』に単純化してみました。

def numerical_gradient_test(f,x):
    print("numerical_gradient_test")
    print(" ・fに101を入れても変わらない:f(101)={}".format(f([[101]])))
    x[0][0]=101
    print(" ・x(=w)を{}に変更すると変わる".format(x[0][0]))
    return f(x)
class NetTest:
    def __init__(self):
        self.w=[[100]]
    
    def predict(self,x):
        return x+self.w[0][0]

    def loss(self,x,t):
        y=self.predict(x)
        return y+t

    def net_numerical_gradient(self,x,t):
        loss_W=lambda W: self.loss(x,t)
        print("loss(x,t) = x({}) + t({}) + w({}) = {}".\
               format(x,t,self.w[0][0],self.loss(x,t)))
        return numerical_gradient_test(loss_W,self.w) 

loss_W=lambda W: self.loss(x,t)
loss_Wの引数Wはloss(x,t)の引数となっていないので、loss_Wは引数Wに何を入れても一見影響がないように見えますが、

numerical_gradient(loss_W,self.w)
lossで計算されるpredictの計算要素wを引数にして、

numerical_gradient_test(f,x)
ここでx(=w)を変更すると、lossの引数ではないけど計算要素なので、lossの計算結果が変わります。

ここで、『足し算ネットワーク』に数字を入れて試してみます。

n=NetTest()
x=2
t=5
n.net_numerical_gradient(x,t)
≪出力≫
loss(x,t) = x(2) + t(5) + w(100) = 107
numerical_gradient_test
 ・fに101を入れても変わらない:f(101)=107
 ・x(=w)を101に変更すると変わる
108

x,t,wに2,5,100を与えると
loss=2+5+100=107
numerical_gradient_testの中でwを101に変更すると
loss=2+5+101=108
となります。なるほど😉

タイトルとURLをコピーしました