先日、Kerasを使ったニューラルネットワークモデルでアヤメの分類をおこなう方法を紹介した。
さて、今回は同様の手順でニューラルネットワークモデルを構築し、scikit-learnで提供されている手書き文字データの分類をやってみる。
Contents
データセットの読み込み
アヤメの分類の時と同じように、まずは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%とは言えないので、所々に不正解の予測が混じっている。
このあとは学習の際に設定したモデルのパラメータを調整しながら精度を検証し、微調整していく。