MNISTを用いた学習モデルの作成

# MNISTとは
MNISTとは手書き数字を認識するために用いられる画像データセットである。
今回はそんなMNISTを使って、手書き数字を識別できる学習モデルの作成に挑戦する。
　　
#### MNISTデータ
手書きで書かれた数字を画像にした画像データ(image)と、その画像に書かれた数字を表すラベルデータ(label)から構成される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623933/bf05d81c-46b9-214f-aef1-c75ce0789ef0.png)

それらのペアは、学習用に60,000個、検証用に10,000個の数だけ提供されている。
　　
　　
　　

# 実際の画像データの中身
学習モデルをより深く理解するために、実際にどんなデータがMNISTに入っているのか確認してみる。

```python

import sys
import numpy as np
from keras.datasets import mnist
from keras.utils import np_utils
from PIL import Image
 
(X_train, y_train), (X_test, y_test) = mnist.load_data()
 
#X_trainの画像化とy_trainの値
#1番目のトレーニングの画像データについて調べてみる
train_no = 0
 
print('訓練画像')
for xs in X_train[train_no]:
    for x in xs:
        sys.stdout.write('%03d ' % x)
    sys.stdout.write('\n')
    
outImg = Image.fromarray(X_train[train_no].reshape((28,28))).convert("RGB")
outImg.save("train.png")
 
print('訓練ラベル(y_train) ＝ %d' % y_train[train_no])
 
#X_testの画像化とy_testの値
#1番目のテストの画像データについて調べてみる
test_no = 0
 
print('テスト画像')
for xs in X_test[test_no]:
    for x in xs:
        sys.stdout.write('%03d ' % x)
    sys.stdout.write('\n')
    
outImg = Image.fromarray(X_test[test_no].reshape((28,28))).convert("RGB")
outImg.save("test.png")
 
print('テストラベル(y_test) ＝ %d' % y_test[test_no])

```

このプログラムは学習用データ１件目とテストデータ１件目を表示する。

X_train = 学習用画像データ、y_train = 学習用ラベル、X_test = テスト画像データ、y_test = テストラベルとなっているので、それぞれの中身を確認すると以下のような実行結果になる。

```
訓練画像
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 003 018 018 018 126 136 175 026 166 255 247 127 000 000 000 000 
000 000 000 000 000 000 000 000 030 036 094 154 170 253 253 253 253 253 225 172 253 242 195 064 000 000 000 000 
000 000 000 000 000 000 000 049 238 253 253 253 253 253 253 253 253 251 093 082 082 056 039 000 000 000 000 000 
000 000 000 000 000 000 000 018 219 253 253 253 253 253 198 182 247 241 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 080 156 107 253 253 205 011 000 043 154 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 014 001 154 253 090 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 139 253 190 002 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 011 190 253 070 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 035 241 225 160 108 001 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 081 240 253 253 119 025 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 045 186 253 253 150 027 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 016 093 252 253 187 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 249 253 249 064 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 046 130 183 253 253 207 002 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 039 148 229 253 253 253 250 182 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 024 114 221 253 253 253 253 201 078 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 023 066 213 253 253 253 253 198 081 002 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 018 171 219 253 253 253 253 195 080 009 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 055 172 226 253 253 253 253 244 133 011 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 136 253 253 253 212 135 132 016 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
訓練ラベル(y_train) ＝ 5
テスト画像
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 084 185 159 151 060 036 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 222 254 254 254 254 241 198 198 198 198 198 198 198 198 170 052 000 000 000 000 000 000 
000 000 000 000 000 000 067 114 072 114 163 227 254 225 254 254 254 250 229 254 254 140 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 017 066 014 067 067 067 059 021 236 254 106 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 083 253 209 018 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 022 233 255 083 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 129 254 238 044 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 059 249 254 062 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 133 254 187 005 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 009 205 248 058 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 126 254 182 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 075 251 240 057 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 019 221 254 166 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 003 203 254 219 035 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 038 254 254 077 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 031 224 254 115 001 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 133 254 254 052 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 061 242 254 254 052 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 121 254 254 219 040 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 121 254 207 018 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
テストラベル(y_test) ＝ 7

```

うっすらと数字の５と７が見える。
そしてラベルも同様に表示された。

  

  
#MNISTを使った学習モデルの作成
機械学習のモデルとは、コンピュータが分かる形の入力値を受け取り、何かしらの評価・判定をして出力値を出すものである。
モデルを開発するために必要なものは膨大な学習データであり、それを今回はMNISTが担う。
　　
　　
繰り返しあらゆる角度から学習させた後に、理解度を測るためにテストをする。このことをモデルの精度を評価すると言い、そこで使われるのがテストデータである。
　　


実際に学習モデルを作成してみる。


```python
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import Adam 
from keras.utils import np_utils
 
def build_model():
 # モデルの作成
 model = Sequential()
 model.add(Dense(512, input_shape=(784,)))
 model.add(Activation('relu'))
 model.add(Dropout(0.2))
 
 model.add(Dense(512))
 model.add(Activation('relu'))
 model.add(Dropout(0.2))
 
 model.add(Dense(10))
 model.add(Activation('softmax'))
 
 # 損失関数の定義
 model.compile(
 loss='categorical_crossentropy',
 optimizer=Adam(),
 metrics=['accuracy'])
 
 return model
 
if __name__ == "__main__":
 #　MNISTのデータの読み込み
 # 訓練データ６万件、テストデータ１万件
 # 28ピクセル × 28ピクセル = 784ピクセルのデータ
 # 色は0〜255
 (X_train, y_train), (X_test, y_test) = mnist.load_data()
 X_train = X_train.reshape(60000, 784).astype('float32')
 X_test = X_test.reshape(10000, 784).astype('float32')
 X_train /= 255
 X_test /= 255
 
 # 10次元配列に変換　//数字の５ならこんな感じ[0,0,0,0,1,0,0,0,0,0]
 y_train = np_utils.to_categorical(y_train, 10)
 y_test = np_utils.to_categorical(y_test, 10)
 
 # データで訓練 今回は時間省略のため2回で学習する
 model = build_model()
 model.fit(X_train, y_train, 
 nb_epoch=2, #学習させる回数　今回は２　回数はお好みで　pytyonのnb_epochとはrangeの繰り返しのこと
 batch_size=128, #無作為に１２８画像取得している。数字はなんでも良い
 validation_data=(X_test, y_test)
 )
 
 
 #学習モデルの保存
 json_string = model.to_json()
 #モデルのファイル名　拡張子.json
 open('mnist.json', 'w').write(json_string)
 #重みファイルの保存 拡張子がhdf5
 model.save_weights('mnist.hdf5')
 
 # モデルの評価を行う
 score = model.evaluate(X_test, y_test, verbose=1)
 
 print('loss=', score[0])
 print('accuracy=', score[1])

```
学習モデルはjsonファイルとhdf5ファイルの２つできる。

実行結果は

```
Train on 60000 samples, validate on 10000 samples
Epoch 1/2
60000/60000 [==============================] - 9s 152us/step - loss: 0.2453 - accuracy: 0.9264 - val_loss: 0.0981 - val_accuracy: 0.9683
Epoch 2/2
60000/60000 [==============================] - 9s 150us/step - loss: 0.1009 - accuracy: 0.9693 - val_loss: 0.0752 - val_accuracy: 0.9760
10000/10000 [==============================] - 1s 65us/step
loss= 0.07517002068450675
accuracy= 0.9760000109672546

```

９７％の正答率をもつモデルを作成できた。

データがわかりやすいため、時間短縮を考えてepoch=2という少ない数字での学習を行なったがそれなりの精度を出すことができる。

実際は５００とか１０００とかいう数字で学習する。

#まとめ

機械学習とMNISTに関する理解が深まった。今回書いたコードを自分なりに工夫して精度をよりあげられるようにしたい。