Detect MNIST numbers Using Keras and PlaidML

In [1]:
import os
import time
import numpy as np
from matplotlib import pyplot as plt

os.environ["KERAS_BACKEND"] = "plaidml.keras.backend" # Using PlaidML Backend

import keras
from keras.datasets import mnist
from keras.models import Sequential, load_model
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K
Using plaidml.keras.backend backend.

1) Prepare the data

ทำการโหลด Data MNIST จากเว็บไซต์ http://yann.lecun.com/exdb/mnist/ มาไว้ที่ Folder เดียวกันกับ Notebook และทำการแตก gzip

In [7]:
image_size = 28
num_images = 60000

with open('./data/mnist/train-images-idx3-ubyte', 'rb') as fp:
    fp.read(16)
    buf = fp.read(image_size * image_size * num_images)
    data = np.frombuffer(buf, dtype=np.uint8).astype(np.float32)
    x_train = data.reshape(num_images, image_size, image_size, 1)
    
with open('./data/mnist/train-labels-idx1-ubyte', 'rb') as fp:
    fp.read(8)
    buf = fp.read(num_images)
    y_train = np.frombuffer(buf, dtype=np.uint8).astype(np.int64)
    
num_images = 10000
    
with open('./data/mnist/t10k-images-idx3-ubyte', 'rb') as fp:
    fp.read(16)
    buf = fp.read(image_size * image_size * num_images)
    data = np.frombuffer(buf, dtype=np.uint8).astype(np.float32)
    x_test = data.reshape(num_images, image_size, image_size, 1)
    
with open('./data/mnist/t10k-labels-idx1-ubyte', 'rb') as fp:
    fp.read(8)
    buf = fp.read(num_images)
    y_test = np.frombuffer(buf, dtype=np.uint8).astype(np.int64)
In [4]:
n = 150
plt.title(f'Label: {y_train[n]}')
plt.imshow(x_train[n].squeeze())
Out[4]:
<matplotlib.image.AxesImage at 0x1448ddf90>

2) Train the model

In [8]:
batch_size = 128
num_classes = 10
epochs = 20

img_rows, img_cols = image_size, image_size

# Reshape the image 
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)  

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

# our model
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          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])
x_train shape: (60000, 28, 28, 1)
60000 train samples
10000 test samples
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 16s 268us/step - loss: 0.2619 - acc: 0.9199 - val_loss: 0.0571 - val_acc: 0.9817
Epoch 2/20
60000/60000 [==============================] - 12s 203us/step - loss: 0.0910 - acc: 0.9731 - val_loss: 0.0431 - val_acc: 0.9852
Epoch 3/20
60000/60000 [==============================] - 12s 205us/step - loss: 0.0670 - acc: 0.9800 - val_loss: 0.0364 - val_acc: 0.9870
Epoch 4/20
60000/60000 [==============================] - 12s 200us/step - loss: 0.0529 - acc: 0.9839 - val_loss: 0.0332 - val_acc: 0.9894
Epoch 5/20
60000/60000 [==============================] - 12s 205us/step - loss: 0.0481 - acc: 0.9852 - val_loss: 0.0364 - val_acc: 0.9887
Epoch 6/20
60000/60000 [==============================] - 12s 204us/step - loss: 0.0419 - acc: 0.9873 - val_loss: 0.0295 - val_acc: 0.9905
Epoch 7/20
60000/60000 [==============================] - 12s 202us/step - loss: 0.0394 - acc: 0.9878 - val_loss: 0.0289 - val_acc: 0.9902
Epoch 8/20
60000/60000 [==============================] - 12s 202us/step - loss: 0.0347 - acc: 0.9895 - val_loss: 0.0290 - val_acc: 0.9904
Epoch 9/20
60000/60000 [==============================] - 12s 201us/step - loss: 0.0322 - acc: 0.9896 - val_loss: 0.0288 - val_acc: 0.9904
Epoch 10/20
60000/60000 [==============================] - 12s 202us/step - loss: 0.0282 - acc: 0.9913 - val_loss: 0.0300 - val_acc: 0.9919
Epoch 11/20
60000/60000 [==============================] - 12s 204us/step - loss: 0.0276 - acc: 0.9917 - val_loss: 0.0300 - val_acc: 0.9911
Epoch 12/20
60000/60000 [==============================] - 12s 202us/step - loss: 0.0252 - acc: 0.9918 - val_loss: 0.0260 - val_acc: 0.9921
Epoch 13/20
60000/60000 [==============================] - 12s 201us/step - loss: 0.0235 - acc: 0.9925 - val_loss: 0.0294 - val_acc: 0.9905
Epoch 14/20
60000/60000 [==============================] - 12s 205us/step - loss: 0.0225 - acc: 0.9926 - val_loss: 0.0348 - val_acc: 0.9899
Epoch 15/20
60000/60000 [==============================] - 12s 204us/step - loss: 0.0220 - acc: 0.9927 - val_loss: 0.0264 - val_acc: 0.9922
Epoch 16/20
60000/60000 [==============================] - 12s 205us/step - loss: 0.0211 - acc: 0.9932 - val_loss: 0.0337 - val_acc: 0.9908
Epoch 17/20
60000/60000 [==============================] - 12s 198us/step - loss: 0.0213 - acc: 0.9936 - val_loss: 0.0289 - val_acc: 0.9917
Epoch 18/20
60000/60000 [==============================] - 12s 201us/step - loss: 0.0222 - acc: 0.9926 - val_loss: 0.0275 - val_acc: 0.9917
Epoch 19/20
60000/60000 [==============================] - 12s 203us/step - loss: 0.0197 - acc: 0.9940 - val_loss: 0.0291 - val_acc: 0.9912
Epoch 20/20
60000/60000 [==============================] - 12s 201us/step - loss: 0.0179 - acc: 0.9939 - val_loss: 0.0334 - val_acc: 0.9907
Test loss: 0.03335125161111355
Test accuracy: 0.9907

3) Predict an image

In [9]:
np.argmax(model.predict(x_test[6].reshape(1, 28, 28, 1)))
Out[9]:
4

4) Save the model for later usage

In [10]:
model.save('mnist_cnn.h5')
In [ ]: