例によって、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