ニューラルネットワーク 損失関数の数値微分vs誤差逆伝搬法 速度比較! & 損失関数を「正解率」にしてみた!

検証内容

書籍『ゼロから作るDeepLearning』で気になった内容を検証します!

 書籍サンプルコード:

GitHub - oreilly-japan/deep-learning-from-scratch: 『ゼロから作る Deep Learning』(O'Reilly Japan, 2016)

データ:MNIST手書き文字 train:1000, test:300件に絞り込み

実行ファイル:deep-learning-from-scratch\ch04\train_neuralnet.py

変数gradで呼び出す関数を変更して検証!

 

数値微分vs誤差逆伝搬法 速度比較!

数値微分

損失関数の微分算出:two_layer_net.py\def numerical_gradient(self, x, t)

【計算速度】

4080秒/30iters = 136秒/iter

【性能】

 test acc:38.7% @30iters

【実行結果】
14:09:05
iters:0 | train acc, test acc | 0.105, 0.1233
14:32:19
iters:10 | train acc, test acc | 0.116, 0.1367
14:52:55
iters:20 | train acc, test acc | 0.247, 0.2233
15:17:50
iters:30 | train acc, test acc | 0.395, 0.3867

 

誤差逆伝搬法

損失関数の微分算出:two_layer_net.py\def gradient(self, x, t)

【計算速度】

1秒/100iters = 0.01秒/iter

【性能】

test acc:39.7% @30iters

【実行結果】

13:26:09
iters:0 | train acc, test acc | 0.117, 0.1133
13:26:09
iters:10 | train acc, test acc | 0.116, 0.1367
13:26:09
iters:20 | train acc, test acc | 0.337, 0.3433
13:26:09
iters:30 | train acc, test acc | 0.378, 0.3967
13:26:09
iters:40 | train acc, test acc | 0.53, 0.4767
13:26:09
iters:50 | train acc, test acc | 0.699, 0.6767
13:26:09
iters:60 | train acc, test acc | 0.696, 0.6767
13:26:09
iters:70 | train acc, test acc | 0.833, 0.76
13:26:09
iters:80 | train acc, test acc | 0.841, 0.77
13:26:10
iters:90 | train acc, test acc | 0.856, 0.7967

 

損失関数を「1-正解率」にしたらどうなるか!

書籍4.2.5章「なぜ損失関数を設定するのか?」の内容について検証します!

損失関数の微分算出:two_layer_net.py\def numerical_gradient_acc(self, x, t)(自作)

def numerical_gradient_acc(self, x, t):
    #正解率を損失関数にしてみる
    loss_W = lambda W: self.loss_acc(x, t)
    grads = {}
    grads['W1'] = numerical_gradient(loss_W, self.params['W1'])
    grads['b1'] = numerical_gradient(loss_W, self.params['b1'])
    grads['W2'] = numerical_gradient(loss_W, self.params['W2'])
    grads['b2'] = numerical_gradient(loss_W, self.params['b2'])
    return grads

 

def loss_acc(self, x, t):
    y = self.predict(x)
    return accuracy(y, t)

 

def accuracy(y, t):
    y = np.argmax(y, axis=1)
    t = np.argmax(t, axis=1)
    accuracy = np.sum(y == t) / float(y.shape[0])
    return 1 - accuracy

 

【性能】

test acc:8.0% @30iters

 

【実行結果】
14:09:07
iters:0 | train acc, test acc | 0.097, 0.08
14:32:16
iters:10 | train acc, test acc | 0.097, 0.08
14:52:44
iters:20 | train acc, test acc | 0.097, 0.08
15:17:26
iters:30 | train acc, test acc | 0.097, 0.08

 

結論

誤差逆伝搬法は数値微分と比べて計算速度が一万倍以上!

・損失関数を「1-正解率」にすると学習が進まない