🍉しいたげられたしいたけ

NO WAR! 戦争反対!Ceasefire Now! 一刻も早い停戦を!

O'REILLY『ゼロから作るDeep Learning』「3.6.3 バッチ処理」を動かすための前処理 on Windows10

忘れちゃうんで自分用メモ。これが正しいかどうかは、わからない。「何やっとんじゃいボケ!」とお気づきの方がいたら、ぜひご指摘願います。今回も対象は『ゼロから作るDeep Learning』の読者だけなので、新着に表示されにくくするため日付をさかのぼって公開しています。 

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

 

 「3.6.3 バッチ処理」のP78と80のコードは、いきなり対話モードのプロンプトから入力すると、エラーになる。それは事前に予想できた。未定義の関数を使うことになるからだ。

P78 のコードを入力して、エラーを表示させた様子を下記に示す。Anaconda Prompt からのテキストのみのコピペである。

(C:\Users\…\Anaconda3) C:\Users\…\Documents\Python Scripts\ch03>python
Python 3.5.2 |Anaconda 4.2.0 (64-bit)| (default, Jul 5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> x, _ = get_data()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'get_data' is not defined
>>> network = init_network()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'init_network' is not defined
>>> W1, W2, W3 = network['W1'], network['W2'], network['W3']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'network' is not defined
>>>

太字で示したのが、テキストに従ってユーザが入力した部分である。

じゃあどうすればいいかというと、P76に出てくるサンプルスクリプト ch03/neuralnet_mnist.py は、プロンプトにコピペができるのだ(うちは Windows10で Anaconda Prompt を使用しています)。だから事前準備として、それを貼りつけて実行しておく。

ただし、スクリプトは改行が [LF] のみなので、[CR][LF]に置き換える必要がある。それが面倒臭いので GitHub の 『ゼロから作る Deep Learning』のリポジトリ をブラウザからコピペしている(いいのかそれ?

f:id:watto:20170226104653p:plain

実行している様子を Anaconda Prompt からテキストでコピペする。青字が neuralnet_mnist.py のコードを貼りつけた部分、太字がP78の通りに入力した箇所である。

(C:\Users\…\Anaconda3) C:\Users\…\Documents\Python Scripts\ch03>python
Python 3.5.2 |Anaconda 4.2.0 (64-bit)| (default, Jul 5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys, os
>>> sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定
>>> import numpy as np
>>> import pickle
>>> from dataset.mnist import load_mnist
>>> from common.functions import sigmoid, softmax
>>>
>>> def get_data():
...     (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
...     return x_test, t_test
...
>>>
>>> def init_network():
...     with open("sample_weight.pkl", 'rb') as f:
...     network = pickle.load(f)
...     return network
...
>>> def predict(network, x):
...     W1, W2, W3 = network['W1'], network['W2'], network['W3']
...     b1, b2, b3 = network['b1'], network['b2'], network['b3']
...     a1 = np.dot(x, W1) + b1
...     z1 = sigmoid(a1)
...     a2 = np.dot(z1, W2) + b2
...     z2 = sigmoid(a2)
...     a3 = np.dot(z2, W3) + b3
...     y = softmax(a3)
...     return y
...
>>> x,_ = get_data()
>>> network = init_network()
>>> W1, W2, W3 = network['W1'], network['W2'], network['W3']
>>>
>>> x.shape
(10000, 784)
>>> W1.shape
(784, 50)
>>> W2.shape
(50, 100)
>>> W3.shape
(100, 10)
>>>

本と同じ結果が得られたので、当然とはいえホッとした。

ただし、関数 predict(network, x): には改行が二箇所あるので、ブラウザからコピペする時には、その部分をスキップする必要がある。また "Accuracy:" を計算している部分は貼りつけなかったが、やりたければやってもいい。

P80のバッチ処理のコードを実行させる前にも、これらの準備が必要である。

>>> x, t = get_data()
>>> network = init_network()
>>>
>>> batch_size = 100
>>> accuracy_cnt = 0
>>>
>>> for i in range(0, len(x), batch_size):
...     x_batch = x[i:i+batch_size]
...     y_batch = predict(network, x_batch)
...     p = np.argmax(y_batch, axis=1)
...     accuracy_cnt += np.sum(p == t[i:i+batch_size])
...
>>> print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
Accuracy:0.9352
>>>

書き忘れたが、以上の作業を行うためには、P73にあるように、事前にカレントディレクトリを ch01 ~ ch08 のいずれかに移動しておく必要がある。

ここまでの作業をまとめた結果は、サンプルスクリプト ch03/neuralnet_mnist_batch.py の内容と同じになった。また実際、対話モードを抜けてコマンドプロンプトから neuralnet_mnist_batch.py を実行させた結果とも一致したので、大きな過ちはしていないと思いたい。

(C:\Users\…\Anaconda3) C:\Users\…\Documents\Python Scripts\ch03>python neuralnet_mnist_batch.py
Accuracy:0.9352

(C:\Users\…\Anaconda3) C:\Users\…\Documents\Python Scripts\ch03> 

スポンサーリンク