画像入力に対する処理を実装してみる

ディープラーニング全体の流れを抑えたところで、ここでは、既に学習された(つまり、推論を行うための「重みパラメータ」がある程度洗練された状態の)ニューラルネットワークを用いて、ニューラルネットワークの実装をしてみる。

手書きの数字を判別するというテーマに関しては、MNISTと呼ばれる有名なデータセットがある。このデータセットは訓練画像60,000枚、テスト画像10,000枚によって構成されていて、全ての「手書きの数字の画像(28ピクセル×28ピクセル)」に「その画像が表す数字(正解ラベル)」がセットになっている。

画像①MNIST

実装は、①10000枚のテスト画像を入力し、②それぞれが何の数字なのかを判定し、③それらが正しいのかを確認し、④全体でどれだけの精度で判別が行えたかを確認する、という流れになる。

画像②数字判別の流れ

今回は全体の実装の流れを見るのでMNISTに関する詳細は省き、「ゼロから作るDeep Learning Pythonで学ぶディープラーニングの理論と実装」で提供されている load_mnist関数を使う。なお、「既に学習された重みパラメータ」として使う「sample_weight.pkl」もこの本から提供されているものを使う。

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

ここでは訓練用ではなくテスト用のデータを使うので、「x_test(テスト用画像)」と「t_test(テスト用画像のラベル)」のみを呼び出している。これらは10000枚分のデータの配列なので、例えば x_test[5] は5枚目の画像データ、t_test[5] は5枚目の画像データが表す数字となる。

ここで、load_mnist関数における「normalize=True」は「画像のピクセル1つ1つが表す色情報である0~255の値を正規化して0~1の値にする」という意味で、「flatten=True」は「2次元である画像情報を潰して1次元にする」という意味だ。この2つにより、入力された画像は784個(=28×28)の0~1の数字の羅列となる。「one_hot_label=False」は「正解のラベルをone hot表現しない」という意味で、one hot表現とは正解ラベル5に対して[0,0,0,0,0,1,0,0,0,0]と表現する方法のこと。Falseの場合5という表現のままになる。

画像③画像のデータ化

ここまでで入力の準備はできた。次に、ニューラルネットワークの準備として既に学習された「重みパラメータ」を読み込み(init_network関数)、骨組みとなる活性化関数の構成に当てはめる(predict関数)。今回はこれらの内容については触れないが、predict関数のニューラルネットワークは784個の入力に対して10個の出力をする形となる。

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

画像の④ニューラルネットワークの構成

10個の出力はそれぞれ、0~9のどれが正解かの可能性の高さが示される。最も大きい値を持つインデックスがこのニューラルネットワークが推測した数字となる(プログラムではnp.argmax(x)を使うことでインデックスを取り出している)。これが正解ラベルと一致するか確認し、正しければ精度パラメータに1を加える。これを10000枚に対して繰り返し、精度パラメータを10000(プログラム上ではlen(x)と書いている)で割れば、このニューラルネットワークの手書き数字の判定精度が出る。(実行すると、このニューラルネットワークは93.52%の精度となった。)

x, t = get_data()
network = init_network()

accuracy_cnt = 0
for i in range (len(x)):
y = predict(network, x[i])
p = np.argmax(y)
if p == t[i]:
accuracy_cnt += 1

print(“Accuracy:” + str(float(accuracy_cnt) / len(x)))

今回は「推論」の流れを見たが、これは既にできたニューラルネットワークのチェックに相当するものだ。「学習」のフェーズでは推論の精度を結果的に上げるために、重みパラメータをどう動かすか、活性化関数をどう配置しニューラルネットワークを構成するか、ということを考えることになる。

Leave a Comment