[画像認識] MNISTによる手書き文字の認識

手書き文字認識はMNISTのデータセットを使って、keras, kaggleからデータを取り込むことができる。

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

mnist = tf.keras.datasets.mnist.load_data()
train, test = mnist
(x_train, y_train),(x_test, y_test) = mnist

print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)

(60000, 28, 28) // 28x28pxのデータが60000枚
(60000,)
(10000, 28, 28) // 28x28pxのデータが10000枚
(10000,)

データセットを画像で確認

print(x_train[0])

plt.imshow(x_train[0])
plt.savefig('image.jpg',dpi=100)

### モデルの作成

x_train = x_train / 255.0  # 0-1の間に抑えるよう正規化する
x_test = x_test / 255.0

# Sequential(系列)モデル構築 インスタンスにリストを追加する
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Input((28, 28))) # 入力層は28x28
model.add(tf.keras.layers.Flatten()) # 一元配列1, 784 に変換

# 入力層から情報を受け継いで計算を行う中間層
model.add(tf.keras.layers.Dense(128)) # 128個に全結合
model.add(tf.keras.layers.Activation(tf.keras.activations.relu)) # 中間層の活性化関数の設定, reluは0以下は0、0以上は入力値を出力
model.add(tf.keras.layers.Dropout(0.2)) # 過学習を防ぐため20%ドロップアウト

# 出力
model.add(tf.keras.layers.Dense(10)) # 出力層0~9の10個
model.add(tf.keras.layers.Activation(tf.keras.activations.softmax)) # softmax関数は出力値の合計が100%になる

# コンパイル
model.compile(
	optimizer=tf.keras.optimizers.Adam(), # optimizerは逆伝播モジュール 手本と出力を比較して重みw, バイアスbを修正, AdamはAdaptive Moment Estimationの略でmomentumSGDとRMSpropを合わせたアルゴリズム
	loss=tf.keras.losses.sparse_categorical_crossentropy, # 誤差関数モジュール 正解値と予想値のズレを計算
	metrics=[tf.keras.metrics.sparse_categorical_accuracy] # 評価関数
)

# fitで学習 epochsで5回
model.fit(x_train, y_train, epochs=5)

print(model.evaluate(x_test, y_test))

plt.imshow(x_test[0])
plt.savefig('data/test_img.jpg',dpi=100)

# predict
pred = model.predict(x_test[0][np.newaxis]) # numpyのnewaxis
print(np.argmax(pred)) # 一番大きい要素


img = Image.open("data/handwriting.jpg").convert('L')
img.thumbnail((28, 28))
img = np.array(img)
pred = model.predict(img[np.newaxis]) # numpyのnewaxis
print(np.argmax(pred)) # 一番大きい要素


[0.0724998340010643, 0.9782000184059143]
7
3

ほう