概要
MNISTデータを使い、学習済みの重みパラメータによるニューラルネットワークの推論処理を整理する。
推論とは、入力データをネットワークに通し、最終的な出力から予測結果を得る処理となる。
ここでは、入力層、中間層、出力層の計算を関数化し、手書き数字画像に対する予測の流れを確認する。
この記事の構成
- 推論処理の実行準備
推論処理の実行準備の手順と確認ポイントを整理。 - 推論処理のニューロン構成と関数定義
入力層・中間層・出力層の構成と、推論に使う関数の役割を整理。 - 推論処理の実行
推論処理の実行の意味と要点を具体例から整理。
概念の説明と実装サンプル
推論処理の実行準備
- サンプルコードとデータの準備
参考文献の『ゼロから作るDeep Learning』から提供されている推論処理のサンプルコード(
ch03/neuralnet_mnist.py)をダウンロードする。Git(deep-learning-from-scratch): ch03/neuralnet_mnist.py
MNISTのダウンロードについては、前の記事 > Python - ニューラルネットワーク: MNISTのダウンロード方法(手書き数字画像セットを取込む)> MNISTのダウンロードを参照
推論処理のニューロン構成と関数定義
- ネットワーク構成と関数
-
ニューロン構成について
入力層:784個(画像データ28 x 28 = 784(px))
隠れ層1:50(任意の値)
隠れ層2:100(任意の値)
出力層:10(数字0~9の10クラス) -
実装サンプル(関数定義)
以下、ch03/neuralnet_mnist.py内の3つの関数定義。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 yinit_network()では、pickleファイルとなるsample_weight.pklを読み込んでいる。※ pickleファイルには、重みとバイアスのパラメータがdictionary型で保存されている。信頼できないpickleは任意のコードを実行する危険があるため、配布元を確認したファイルだけを読み込む。
※ predict(network, x)のsigmoid, softmaxについては、下記を参考。
・Python - ニューラルネットワーク: ニューラルネットワークの活性化関数と実装サンプル
・Python - ニューラルネットワーク: 活性化関数の実装サンプルまとめ(ステップ、シグモイド、ReLU、恒等関数、ソフトマックス関数)
-
推論処理の実行
- 推論処理と認識精度
-
ch03/neuralnet_mnist.py内の実行処理
x, t = get_data() # … 1. network = init_network() # … 2. accuracy_cnt = 0 for i in range(len(x)): # … 3. y = predict(network, x[i]) # … 4. p= np.argmax(y) # … 5. if p == t[i]: # … 6. accuracy_cnt += 1 # … 7. print("Accuracy:" + str(float(accuracy_cnt) / len(x))) # … 8. -
実行処理の解説
get_data()でMNISTデータセットを取得。init_network()でpickleファイルを読み込む。- \(x\)のテスト画像データ10,000枚をfor文でループ。
- 1枚の画像データに対して
predict(network, x[i])を実行し、下記のNumPy配列のように数字0~9それぞれの確率を出力。
※ 0である確率:20%、1である確率:10%、2である確率:4%、… 9である確率:5%[ 0.2, 0.1, 0.04 , … , 0.05 ] # 0 ~ 9 それぞれの確率 (20%, 10%, 4%, … , 5%) - 「4.」の結果であるNumPy配列\(y\)に対して、最も確率が高い要素のインデックスを取得。
- 推論処理出した「5.」の予測結果が正解ラベル\(t\)と一致しているかチェック。
- 一致していれば、正解数を加算。
- 最後に正解率を出力。
-
実行結果
実際に上記を対話モードで実行するとAccuracy:0.9352が出力される。$ cd gitlocalrep $ cd deep-learning-from-scratch/ch03 $ source /var/www/vops/bin/activate $ python neuralnet_mnist.py Accuracy:0.9352上記実装サンプルでは、93%程度の精度だったが、実際のニューラルネットワークでは、さらにニューラルネットワークの構造や「4.」の関数
predict内の処理にあたる学習方法を工夫し、99%以上の精度を出していく。
-
まとめ
- 推論は学習済みの重みを使って予測を得る処理であり、学習のように重みを更新しない。
- 各層では、行列積、バイアス加算、活性化関数の適用を順に行う。
- 入力、重み、バイアスのshapeが一致しないと行列計算でエラーになるため、各層の次元を確認。
- 出力値の中で最大となる位置をargmaxで求め、予測クラスとして扱う。