[ゼロから作るDeep Learning]勾配確認について分かりやすく解説してみた


はじめに

この記事はゼロから作るディープラーニング 6章誤差逆伝播法を自分なりに理解して分かりやすくアウトプットしたものです。
文系の自分でも理解することが出来たので、気持ちを楽にして読んでいただけたら幸いです。
また、本書を学習する際に参考にしていただけたらもっと嬉しいです。

勾配確認とは

前回の記事で実装した誤差逆伝播法による勾配式はとても複雑な作りの為ミスが出る可能性が高いです。しかし処理速度がものすごく早い為に使用せざるえません。そこで大切なことは、誤差逆伝播法による勾配式にミスがあるかどうかを確かめることです。それを勾配確認と言い、その勾配確認に作りが単純でミスの少ない数値微分の勾配式を使います。

数値微分の勾配式は処理速度は遅いものの、単純な作りの為にミスが少ないです。
そこで、勾配確認で行うことは数値微分の勾配式から求められた勾配と誤差逆伝播法による勾配式によって求められた勾配の誤差を確認します。

では、実装をしてみたいと思います。

# 下の数値微分の勾配式をニューラルネットワークのクラスメソッドに加える
def slopeing_grad_net(self,x,t):#誤差逆伝播法が正しいかを確認するための数値微分の勾配式
    loss_c = lambda W: self.loss(x, t) 

    grads_t = {}
    grads_t['W1'] = slopeing_grad(loss_c,self.params['W1'])
    grads_t['b1'] = slopeing_grad(loss_c,self.params['b1'])
    grads_t['W2'] = slopeing_grad(loss_c,self.params['W2'])
    grads_t['b2'] = slopeing_grad(loss_c,self.params['b2'])

    return grads_t

# 勾配確認
# ミニバッチを出す
x_train, x_test, t_train, t_test = dataset['train_img'], dataset['test_img'], \
                                            dataset['train_label'], dataset['test_label']

x_batch = x_train[:3]
t_batch = t_train[:3]

netwark = LayerNet(input_size = 784, hiden_size = 50, output_size = 10)
# 各勾配を出す
grad_slope = netwark.slopeing_grad_net(x_batch, t_batch)
grad_new = netwark.gradient(x_batch, t_batch)

for key in grad_slope.keys(): # それらの違いを比べる
    diff = np.average(np.abs(grad_new[key] - grad_slope[key]))
    print(key + ':' + str(diff))


W1:0.03976913034251971
b1:0.0008997051177847986
W2:0.3926011094391389
b2:0.04117287920452093

上のようなコードで勾配の誤差の平均を確認して、誤差が範囲内かどうかを確認します。