chakokuのブログ(rev4)

テック・コミック・DTM・・・ごくまれにチャリ

【DLfS】学習しない俺ニューラルネットでMNISTデータを認識させた→正解率10%なぜなら。。

例によって、DLfS本(ゼロから作るDeep Learning)で勉強しながら、学習しない俺ニューラルネットを組んで、MNISTデータを認識させてみた(DLfS本の3.6.2(P75))。ニューラルネットの重みづけは単なる乱数で設定した。バイアスも同様。結果、どんなデータを入れてもいつも'3'とか'4'とか固定の答えばかりのシステムができた。だから、、正解率は10%であると。。ご参考にソースは以下

#!/usr/bin/python3

import numpy as np
import nnlib
import TestBench

def init_network():
    # network
    network = {}
    network['W1'] = np.random.random(size=(784,50))/100.0
    network['B1'] = np.random.random(size=(50))/100.0
    network['W2'] = np.random.random(size=(50,100))/100.0
    network['B2'] = np.random.random(size=(100))/100.0
    network['W3'] = np.random.random(size=(100,10))/100.0
    network['B3'] = np.random.random(size=(10))/100.0
    return network

tb=TestBench.TestBench()
tb.open('MNIST')
N_OF_TRY=10

net = init_network()

labels,ptns=tb.getData('test',size=N_OF_TRY)

accuracy_count = 0

for i in range(N_OF_TRY):
    ans=labels[i]
    x = np.array(ptns[i])
    x = x / 255
    y = nnlib.forward(net, x)
    p = np.argmax(y)

    print('out:{:d}'.format(p),end='')
    print('(ans:{:d})'.format(ans))

    if ans == p:
        accuracy_count += 1

    #show final layer
    print(y)

tb.close()

# report total accuracy
print("Accuracy:{:3.0f}%".format(accuracy_count*100/N_OF_TRY))

関数:init_network()において重みづけとバイアスを乱数で設定、学習データを読み込んでくるTestBenchクラス(これは自作)でMNISTデータを取ってきて俺ニューラルネットに食わせる。結果、どんなパターンを入れても同じ答えをする。。
ニューラルネットの本体は、DLfs本の通りに作っており、ライブラリnnlib内のforward関数に実装しています。

実行結果は以下(いつも同じ答えしかしないので全然参考になりませんが)

$ ./nn.py
out:7(ans:7)
[ 0.09949794  0.10088551  0.09991322  0.0979116   0.09953837  0.09940285
  0.09918608  0.10287016  0.10049755  0.10029672]
out:7(ans:2)
[ 0.09949418  0.10089333  0.09991195  0.09789956  0.09953526  0.09940041
  0.09918479  0.1028847   0.1004978   0.10029803]
out:7(ans:1)
[ 0.09950136  0.10087872  0.09991451  0.0979227   0.09954123  0.09940506
  0.09918706  0.10285669  0.10049706  0.10029562]
out:7(ans:0)
[ 0.09949128  0.10089864  0.09991085  0.09789035  0.09953291  0.09939887
  0.09918384  0.10289598  0.10049811  0.10029917]
out:7(ans:4)
[ 0.09949768  0.10088602  0.09991316  0.09791086  0.09953817  0.09940284
  0.09918591  0.10287105  0.10049756  0.10029676]
out:7(ans:1)
[ 0.09949979  0.10088177  0.09991388  0.09791772  0.09953998  0.09940412
  0.09918655  0.10286274  0.10049725  0.10029619]
out:7(ans:4)
[ 0.09949698  0.10088757  0.09991281  0.09790857  0.09953757  0.09940242
  0.0991857   0.10287392  0.10049751  0.10029696]
out:7(ans:9)
[ 0.09949713  0.10088739  0.09991295  0.09790875  0.09953763  0.09940236
  0.09918561  0.10287356  0.10049747  0.10029715]
out:7(ans:5)
[ 0.09949346  0.10089445  0.09991162  0.09789732  0.09953465  0.0994002
  0.09918453  0.10288749  0.10049793  0.10029835]
out:7(ans:9)
[ 0.0994932   0.10089487  0.09991152  0.09789645  0.09953449  0.09940002
  0.09918434  0.10288858  0.10049798  0.10029854]
Accuracy: 10%

この学習しない俺ニューラルネットに学習機能を入れたらどこまで賢くなるか。。

■追記(161030)
【DLfS】 3.6.3 バッチ処理(P78)の説明を学び、俺ニューラルネット(俺といっても本の通りの実装なのだが)をバッチで実装して走らせてみた。データ読み込み(テスト:1万件)→フォワード計算で、1秒程度で処理が終わる。

$ time ./nnb.py
Accuracy: 10%

real    0m1.304s
user    0m1.140s
sys     0m0.156s
#!/usr/bin/python3

# NN w/batch
#
#

import numpy as np
import nnlib
import TestBench

def init_network():
    # network
    network = {}
    network['W1'] = np.random.random(size=(784,50))/100.0
    network['B1'] = np.random.random(size=(50))/100.0
    network['W2'] = np.random.random(size=(50,100))/100.0
    network['B2'] = np.random.random(size=(100))/100.0
    network['W3'] = np.random.random(size=(100,10))/100.0
    network['B3'] = np.random.random(size=(10))/100.0
    return network

batch_size=100

net = init_network()

tb=TestBench.TestBench()
tb.open('MNIST')
labels,ptns=tb.get_data('test',size=10000)

accuracy_count = 0

for i in range(0,len(ptns),batch_size):
    x = np.array(ptns[i:i+batch_size]) / 255.0
    y = nnlib.forward(net, x)
    p = np.argmax(y,axis=1)
    accuracy_count += np.sum(p == labels[i:i+batch_size])

tb.close()

# report total accuracy
print("Accuracy:{:3.0f}%".format(accuracy_count*100/len(ptns)))

#
# $  ./nnb.py
# Accuracy: 10%

というわけで、、次はニューラルネットワークのキモである(と自分では理解している)、損失関数と偏微分を使った損失最小化に入るのであった。。

■補足
エントロピー解説PDF等
http://web.tuat.ac.jp/~s-hotta/info/slide5.pdf

DLfsの公式サンプル
https://github.com/oreilly-japan/deep-learning-from-scratch