先日、Kerasを使ったニューラルネットワークモデルでアヤメの分類をおこなう方法を紹介した。
さて、今回は同様の手順でニューラルネットワークモデルを構築し、scikit-learnで提供されている手書き文字データの分類をやってみる。
コンテンツ
データセットの読み込み
アヤメの分類の時と同じように、まずはscikit-learnからデータを読み込む。
from sklearn import datasets
digits = datasets.load_digits()
x = digits.data
print(x.shape)
y = digits.target
print(y.shape)
# (1797, 64)
# (1797,)
正解データ(目的変数y)をOne-Hotに変換
説明変数xは全て色情報で構成されており単位に違いがないので、今回は正規化は不要だ。
目的変数yは0〜9の質的データなので、One-Hot形式へのエンコーディングが必要だ。
from keras.utils import np_utils
y = np_utils.to_categorical(y)
y[:5]
# array([[1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
# [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
# [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
# [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
# [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.]], dtype=float32)
訓練用データとテスト用データに分ける
データの前処理ができたら、次にxとyをそれぞれ訓練用データとテスト用データに分ける。
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)
ニューラルネットワークモデルの作成と学習
アヤメの分類に関する記事で詳細は触れたので、ここでの詳しい説明は割愛する。
from keras.models import Sequential
from keras.layers.core import Dense, Activation
model = Sequential()
model.add(Dense(16, input_shape=(64,)))
model.add(Activation('relu'))
model.add(Dense(10))
model.add(Activation('softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=30, batch_size=1, verbose=1)
パラメータの調整は任意で良いが、今回はニューラルネットワークの隠れ層を16(5行目)とし、学習回数を30(11行目)とした。
なお、分類は0〜9までで行われるので、出力層は10となる(7行目)。
コードを実行すると、しばらくの間ログが流れ、学習が進んでいく。
Epoch 1/30
1347/1347 [==============================] - 1s 791us/step - loss: 2.3889 - accuracy: 0.3111
Epoch 2/30
1347/1347 [==============================] - 1s 627us/step - loss: 0.9609 - accuracy: 0.6526
Epoch 3/30
1347/1347 [==============================] - 1s 630us/step - loss: 0.4250 - accuracy: 0.8471
...
...
Epoch 28/30
1347/1347 [==============================] - 1s 635us/step - loss: 0.0198 - accuracy: 0.9963
Epoch 29/30
1347/1347 [==============================] - 1s 649us/step - loss: 0.0057 - accuracy: 0.9993
Epoch 30/30
1347/1347 [==============================] - 1s 651us/step - loss: 0.0207 - accuracy: 0.9926
loss値はかなりゼロに近づいた。
モデルの精度を評価
最後に、作成したモデルの精度を評価して終ろう。
loss, accuracy = model.evaluate(x_test, y_test, verbose=0)
print(accuracy)
# 0.9422222375869751
結果は94%を超えており、高い精度のモデルが完成した。
実際にこのモデル(分類器)にテストデータを入れてみよう。
今回はfor文を用いて全てのテストデータの予測結果を確認する。
loss_cnt = 0
size = len(x_test)
for i in range(size):
m_predict = model.predict_classes(x_test[i:i+1], batch_size=1)
if y_test[i][m_predict]:
print('{}: 正解'.format(i))
else:
print('{}: 不正解'.format(i) + ' 予測:{0}, 正解:{1}'.format(m_predict, y_test[i]))
loss_cnt+=1
print('正解率: {}'.format((size - loss_cnt) / size))
確認用のコードの内容はfor文やif文など、特に難しい内容ではないので理解するのは難しくないはずだ。
実行すると以下のとおり、1要素ごとに正解か不正解かが出力される。
0: 正解
1: 正解
2: 正解
...
43: 正解
44: 不正解 予測:[9], 正解:[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
45: 正解
...
448: 正解
449: 正解
正解率: 0.9422222222222222
モデルの精度は100%とは言えないので、所々に不正解の予測が混じっている。
このあとは学習の際に設定したモデルのパラメータを調整しながら精度を検証し、微調整していく。