今更ですがDeepLearningを勉強していまして、その最初の一歩としてMNISTで教師有り学習のモデルを自作してみました。環境構築にもプログラム作成にも苦労したので、次回また勉強する時のためにメモを残します。
環境
今の所、下の環境で一応動作しております。AnacondaとCUDAとCUDNNはホームページからダウンロードしインストールしました。もし、これより最新のドライバが入っていた場合は最新版をアンインストールしてから、下のバージョンをインストールしてください。
- Windows10Home
- Anaconda 4.10.3
- CUDA 11.2
- CUDNN 8.2.1
- Tensorflow 2.5
Anacondaはインストール後、各パッケージが最新になるようにアップデートしました。(アップデートするとAnacondaが持っているパッケージのバージョンが変わるので、この方法でいつもうまくいくかはわかりません!)
conda update --all
Tensorflowはconda
でインストールすると何故かGPUを認識しなかったのでpip
でインストールしました。
pip install tensorflow-gpu
KerasはTensorflowの一部になったので、Tensorflowが入っていれば特にインストールする必要はなくなりました。
なお、TensorflowがGPUを認識しているかを確認するためには、Pythonで下のスクリプトを実行します。
from tensorflow.python import client
client.device_lib.list_local_devices()
実行後に下のようにGPUという文字が出てくれば認識をしているようです。(出てこなければ認識していない)
name: "/device:GPU:0"
device_type: "GPU"
MNISTとは
MNISTとは手書きの数字とその値のデータをあつめたデータセットです。画像サイズは28×28で、黒背景に白文字で数字がかかれたものが70000枚あり、DeepLearningのチュートリアルでよく使われます。学習用データを作成するのは苦労しそうなので今回はMNISTを使います。
モデルを学習する
作成したプログラムを記載します。
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Flatten,BatchNormalization,Conv2D,MaxPooling2D
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
(x_train,y_train),(x_test,y_test) = mnist.load_data()
x_train = np.float32(x_train.reshape(60000,28,28,1))/255.0
y_train = to_categorical(y_train,10)
x_test = np.float32(x_test.reshape(10000,28,28,1))/255.0
y_test = to_categorical(y_test,10)
model = Sequential([
Conv2D(32,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',input_shape=(28,28,1)),
MaxPooling2D(pool_size=(2,2)),
Conv2D(32,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu'),
MaxPooling2D(pool_size=(2,2)),
Flatten(),
Dense(128,activation='relu'),
BatchNormalization(),
Dense(128,activation='relu'),
BatchNormalization(),
Dense(128,activation='relu'),
BatchNormalization(),
Dense(10,activation='softmax')
])
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
model.fit(x_train,y_train,batch_size=100,epochs=20,verbose=1,validation_data=(x_test,y_test))
model.save('mnist')
学習が終わると、mnist
というフォルダに学習されたモデルが保存されます。
プログラムの説明
他のサイトでも結構やっているので、他と違う点だけ説明します。
Conv2D(32,kernel_size=(3,3),strides=(1,1),padding='same',activation='relu',input_shape=(28,28,1)),
他では画像データを(784,)の1次元配列に展開してからDNNに入れている場合が多いのですが、本投稿では2次元配列(28,28)のまま扱っています。その際Conv2D
の中でinput_shape=(28,28)
としたら何故か動作しなかったのでinput_shape=(28,28,1)
にしてます。
学習されたモデルを使う
今回認識させる画像データは下の4.png
です。
これを学習させたモデルmnist
で認識させてみます。
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.image import load_img,img_to_array
model = load_model('mnist')
image_data = load_img('4.png',target_size=(28,28),color_mode='grayscale')
array_data = img_to_array(image_data).reshape(1,28,28,1)
result = model.predict(array_data)
print(result)
[[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]]
配列に10個の数値が入っています。これはモデルが判定した結果を表しており、左から「0と思われる確率」,「1と思われる確率」・・「9と思われる確率」を表しています。今回は左から5番目で1となっていますので、このモデルは確信を持って4と認識したようです。