Simple Convnet - MNIST

Slightly modified from mnist_cnn.py in the Keras examples folder:

https://github.com/keras-team/keras/blob/master/examples/mnist_cnn.py


In [1]:
KERAS_MODEL_FILEPATH = '../../demos/data/mnist_cnn/mnist_cnn.h5'

In [2]:
import numpy as np
np.random.seed(1337)  # for reproducibility

from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Activation
from keras.layers import Conv2D, MaxPooling2D
from keras.utils import np_utils
from keras.callbacks import EarlyStopping, ModelCheckpoint


Using TensorFlow backend.
/home/leon/miniconda3/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: compiletime version 3.5 of module 'tensorflow.python.framework.fast_tensor_util' does not match runtime version 3.6
  return f(*args, **kwds)

In [3]:
num_classes = 10

# input image dimensions
img_rows, img_cols = 28, 28

# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

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 = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)


x_train shape: (60000, 28, 28, 1)
60000 train samples
10000 test samples

In [4]:
# Sequential Model

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

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

In [5]:
# Model saving callback
checkpointer = ModelCheckpoint(filepath=KERAS_MODEL_FILEPATH, monitor='val_acc', verbose=1, save_best_only=True)

# Early stopping
early_stopping = EarlyStopping(monitor='val_acc', verbose=1, patience=5)

# Train
batch_size = 128
epochs = 100
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=2,
          callbacks=[checkpointer, early_stopping], 
          validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])


Train on 60000 samples, validate on 10000 samples
Epoch 1/100
Epoch 00001: val_acc improved from -inf to 0.98270, saving model to mnist_cnn.h5
 - 4s - loss: 0.2833 - acc: 0.9127 - val_loss: 0.0557 - val_acc: 0.9827
Epoch 2/100
Epoch 00002: val_acc improved from 0.98270 to 0.98700, saving model to mnist_cnn.h5
 - 2s - loss: 0.0980 - acc: 0.9708 - val_loss: 0.0407 - val_acc: 0.9870
Epoch 3/100
Epoch 00003: val_acc improved from 0.98700 to 0.98870, saving model to mnist_cnn.h5
 - 2s - loss: 0.0747 - acc: 0.9777 - val_loss: 0.0344 - val_acc: 0.9887
Epoch 4/100
Epoch 00004: val_acc improved from 0.98870 to 0.98960, saving model to mnist_cnn.h5
 - 2s - loss: 0.0611 - acc: 0.9811 - val_loss: 0.0309 - val_acc: 0.9896
Epoch 5/100
Epoch 00005: val_acc did not improve
 - 2s - loss: 0.0542 - acc: 0.9836 - val_loss: 0.0329 - val_acc: 0.9888
Epoch 6/100
Epoch 00006: val_acc improved from 0.98960 to 0.99140, saving model to mnist_cnn.h5
 - 2s - loss: 0.0483 - acc: 0.9853 - val_loss: 0.0289 - val_acc: 0.9914
Epoch 7/100
Epoch 00007: val_acc did not improve
 - 2s - loss: 0.0432 - acc: 0.9863 - val_loss: 0.0278 - val_acc: 0.9912
Epoch 8/100
Epoch 00008: val_acc did not improve
 - 2s - loss: 0.0398 - acc: 0.9873 - val_loss: 0.0295 - val_acc: 0.9902
Epoch 9/100
Epoch 00009: val_acc did not improve
 - 2s - loss: 0.0351 - acc: 0.9885 - val_loss: 0.0277 - val_acc: 0.9910
Epoch 10/100
Epoch 00010: val_acc did not improve
 - 2s - loss: 0.0333 - acc: 0.9897 - val_loss: 0.0281 - val_acc: 0.9910
Epoch 11/100
Epoch 00011: val_acc improved from 0.99140 to 0.99210, saving model to mnist_cnn.h5
 - 2s - loss: 0.0322 - acc: 0.9893 - val_loss: 0.0258 - val_acc: 0.9921
Epoch 12/100
Epoch 00012: val_acc did not improve
 - 2s - loss: 0.0287 - acc: 0.9906 - val_loss: 0.0273 - val_acc: 0.9918
Epoch 13/100
Epoch 00013: val_acc did not improve
 - 2s - loss: 0.0258 - acc: 0.9915 - val_loss: 0.0291 - val_acc: 0.9918
Epoch 14/100
Epoch 00014: val_acc did not improve
 - 2s - loss: 0.0247 - acc: 0.9916 - val_loss: 0.0281 - val_acc: 0.9913
Epoch 15/100
Epoch 00015: val_acc improved from 0.99210 to 0.99270, saving model to mnist_cnn.h5
 - 2s - loss: 0.0245 - acc: 0.9922 - val_loss: 0.0279 - val_acc: 0.9927
Epoch 16/100
Epoch 00016: val_acc did not improve
 - 2s - loss: 0.0235 - acc: 0.9921 - val_loss: 0.0312 - val_acc: 0.9916
Epoch 17/100
Epoch 00017: val_acc did not improve
 - 2s - loss: 0.0228 - acc: 0.9927 - val_loss: 0.0297 - val_acc: 0.9918
Epoch 18/100
Epoch 00018: val_acc did not improve
 - 2s - loss: 0.0208 - acc: 0.9931 - val_loss: 0.0308 - val_acc: 0.9917
Epoch 19/100
Epoch 00019: val_acc did not improve
 - 2s - loss: 0.0203 - acc: 0.9930 - val_loss: 0.0297 - val_acc: 0.9918
Epoch 20/100
Epoch 00020: val_acc did not improve
 - 2s - loss: 0.0179 - acc: 0.9940 - val_loss: 0.0307 - val_acc: 0.9920
Epoch 00020: early stopping
Test score: 0.0306938055278
Test accuracy: 0.992

In [ ]: