MNISTのデータセットをKeras(Tensorflow)で機械学習させる方法

Pythonを使ったデータ学習です。
TensorflowならびにMNISTを使います。
TensorflowはGoogle が開発しているオープンソースライブラリです。
MNISTは画像データにラベル付けされた完成されたデータセットです。
Anacondaは使いません。初学者がディストリビューションに慣れるのは早計だと思います。

初学者向けで、数字認識学習プログラムに適した記事かと思います。
分からない関数や用語などの説明は公式サイトを利用して理解を深めていってください。
あくまで実際に手を動かす導入レベルです。
通常の機械学習であれば、画像を自力で集め、ある程度分類する必要があります…

広告

Prepare for your environment(Terminal)

sudo pip3 install tensorflow
sudo pip3 install -U scikit-learn 
#確認(Confirmation)
pip3 show tensorflow
python3 -m pip show scikit-learn
#もしエラーがでたら(Version adjustment) 
pip uninstall numpy pip install numpy==1.16.4
#TRY IT!
jupyter notebook

Tensorflowをインストールします。
ここで注意すべき点は、バージョンが異なってエラーが発生してしまうことです。
原因はnumpyにあるようで、numpyをダウングレードしています。
もちろん今後のアップデートでズレが生じる可能性があります。適宜調整して下さい。

scikit-learnは機械学習の要だと思ってもらって構いません。
Tensorflowは深層学習が目的です。

Pythonだけで完結するなら個人的にJupyter Notebookを勧めます。
Pythonがインタープリタ言語である点を考慮して、逐次実行して修正を繰り返せるからです。
以下各段落でRun cellsを実行してください。

Prepare for data

import keras
import numpy as np
import matplotlib.pyplot as plt
from keras.datasets import mnist
from keras.layers import Dense, Dropout
from keras.utils import np_utils
from keras.optimizers import RMSprop

ここが一番の壁です。
他のモジュールをインポートします。
あなたの環境にて書いたコードに対応するファイル(コード)が必須です。
kerasはtensorflowに付属してるはずです。
この時点でエラーが出たら必ず対応してください。
おおよそダウンロードされていないことによるエラーだと思います。

Road mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000, 784)/255
x_test = x_test.reshape(10000, 784)/255

MNISTの読み込みです。
kerasで利用できるデフォルトデータセットのうちの1つであり、別途用意する必要はありません。
28×28=784の一次元配列に整形し、各データを0.0~1.0に変換してます。

Variable

batch_v = 128
num_v = 10
epochs_v = 20

変数です。下記で使いますが、まとめておいた方が便利なので最初に書きます。
batch_vは一度に処理するデータの数です。
epochs_vは学習回数です。
num_vは0~9までのタグ付けです。

Binary type

y_train = keras.utils.to_categorical(y_train, num_v)
y_test = keras.utils.to_categorical(y_test, num_v)

ラベルデータをINT型からバイナリ型へ

Deep learning model

kerasが公式に公開しているサンプルコードを用います。
参照:https://github.com/keras-team/keras/blob/master/examples/mnist_mlp.py

Sequential-model (or Functional-API)

from keras.models import Sequential
model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(num_v, activation='softmax'))

model.summary()

model.compile(loss='categorical_crossentropy',optimizer=RMSprop(),metrics=['accuracy'])
Model: "sequential_10"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_28 (Dense)             (None, 512)               401920    
_________________________________________________________________
dropout_19 (Dropout)         (None, 512)               0         
_________________________________________________________________
dense_29 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_20 (Dropout)         (None, 512)               0         
_________________________________________________________________
dense_30 (Dense)             (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
_________________________________________________________________
history = model.fit(x_train, y_train,batch_size=batch_v,epochs=epochs_v,verbose=1,validation_split=0.15,validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:422: The name tf.global_variables is deprecated. Please use tf.compat.v1.global_variables instead.

Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 18s 303us/step - loss: 0.2495 - accuracy: 0.9220 - val_loss: 0.1236 - val_accuracy: 0.9609
Epoch 2/20
60000/60000 [==============================] - 11s 176us/step - loss: 0.1030 - accuracy: 0.9684 - val_loss: 0.0758 - val_accuracy: 0.9766
Epoch 3/20
60000/60000 [==============================] - 11s 179us/step - loss: 0.0756 - accuracy: 0.9772 - val_loss: 0.0866 - val_accuracy: 0.9750
Epoch 4/20
60000/60000 [==============================] - 8s 126us/step - loss: 0.0608 - accuracy: 0.9819 - val_loss: 0.0785 - val_accuracy: 0.9787
Epoch 5/20
60000/60000 [==============================] - 9s 143us/step - loss: 0.0507 - accuracy: 0.9848 - val_loss: 0.0740 - val_accuracy: 0.9815
Epoch 6/20
60000/60000 [==============================] - 7s 122us/step - loss: 0.0429 - accuracy: 0.9874 - val_loss: 0.0840 - val_accuracy: 0.9817
Epoch 7/20
60000/60000 [==============================] - 13s 218us/step - loss: 0.0372 - accuracy: 0.9890 - val_loss: 0.0819 - val_accuracy: 0.9799
Epoch 8/20
60000/60000 [==============================] - 18s 294us/step - loss: 0.0346 - accuracy: 0.9896 - val_loss: 0.0823 - val_accuracy: 0.9831
Epoch 9/20
60000/60000 [==============================] - 12s 196us/step - loss: 0.0314 - accuracy: 0.9908 - val_loss: 0.0939 - val_accuracy: 0.9809
Epoch 10/20
60000/60000 [==============================] - 7s 124us/step - loss: 0.0284 - accuracy: 0.9919 - val_loss: 0.0893 - val_accuracy: 0.9839
Epoch 11/20
60000/60000 [==============================] - 8s 129us/step - loss: 0.0276 - accuracy: 0.9921 - val_loss: 0.1030 - val_accuracy: 0.9818
Epoch 12/20
60000/60000 [==============================] - 8s 129us/step - loss: 0.0257 - accuracy: 0.9929 - val_loss: 0.1012 - val_accuracy: 0.9822
Epoch 13/20
60000/60000 [==============================] - 8s 126us/step - loss: 0.0223 - accuracy: 0.9937 - val_loss: 0.1151 - val_accuracy: 0.9827
Epoch 14/20
60000/60000 [==============================] - 8s 127us/step - loss: 0.0251 - accuracy: 0.9936 - val_loss: 0.1011 - val_accuracy: 0.9832
Epoch 15/20
60000/60000 [==============================] - 8s 126us/step - loss: 0.0212 - accuracy: 0.9941 - val_loss: 0.1138 - val_accuracy: 0.9834
Epoch 16/20
60000/60000 [==============================] - 8s 130us/step - loss: 0.0193 - accuracy: 0.9944 - val_loss: 0.1295 - val_accuracy: 0.9823
Epoch 17/20
60000/60000 [==============================] - 8s 129us/step - loss: 0.0206 - accuracy: 0.9947 - val_loss: 0.1220 - val_accuracy: 0.9840
Epoch 18/20
60000/60000 [==============================] - 8s 127us/step - loss: 0.0192 - accuracy: 0.9953 - val_loss: 0.1219 - val_accuracy: 0.9824
Epoch 19/20
60000/60000 [==============================] - 8s 128us/step - loss: 0.0164 - accuracy: 0.9955 - val_loss: 0.1444 - val_accuracy: 0.9827
Epoch 20/20
60000/60000 [==============================] - 8s 128us/step - loss: 0.0167 - accuracy: 0.9955 - val_loss: 0.1423 - val_accuracy: 0.9833
Test loss: 0.14228209604984043
Test accuracy: 0.983299970626831

実行結果も添付しました。
正解率(accuracy)は0.98~0.99の間を示すことが多いです。
変数やvalidation_split(学習データとテストデータの割合)をいじると更に変わってくると思います。

Graph

acc = history.history['accuracy']
val_acc = history.history['val_loss']

epochs = range(1, len(acc)+1)
plt.plot(epochs, acc, 'b', label='Training accuracy')
plt.plot(epochs, val_acc, 'r', label='Loss')
plt.legend()
plt.show()

ⅹ軸が試行回数、y軸が割合、
赤線が損失率、青線が学習結果を表した表になります(確認用なので適宜カスタマイズして下さい)。
赤線と青線が乖離してるので大雑把なものになっていますが、可視化しました。

Save data

model.save("MNIST.h5")

学習済モデルを保存。

以上で、優秀な数字認識学習モデルができました。

参考サイト:
https://github.com/tensorflow/tensorflow/issues/31249
https://github.com/keras-team/keras/blob/master/examples/mnist_mlp.py

タイトルとURLをコピーしました