In [158]:
## Keras related imports
from keras.datasets import mnist
from keras.models import Sequential, model_from_json
from keras.layers import Activation, Dropout, Flatten, Dense, Convolution2D, MaxPooling2D
from keras.utils import np_utils, data_utils, visualize_util
from keras.preprocessing.image import load_img, img_to_array
## Other data science libraries
import numpy as np
import pandas as pd
import json
from PIL import Image
import matplotlib.pylab as plt
import seaborn as sns
%matplotlib inline
In [5]:
## Some model and data processing constants
batch_size = 128
nb_classes = 10
nb_epoch = 12
# input image dimensions
img_rows, img_cols = 28, 28
# number of convolutional filters to use
nb_filters = 32
# size of pooling area for max pooling
nb_pool = 2
# convolution kernel sizeb
nb_conv = 3
In [14]:
(X_train, y_train), (X_test, y_test) = mnist.load_data()
In [5]:
y_train.shape
Out[5]:
In [7]:
y_test.shape
Out[7]:
In [37]:
fig, axes = plt.subplots(5, 5, figsize=(8,8), sharex=True, sharey=True)
for id, ax in enumerate(axes.ravel()):
image = Image.fromarray(X_train[id, :, :])
ax.imshow(image, cmap='Greys_r')
In [98]:
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 10), sharex=True)
sns.distplot(y_train, kde=False, ax=ax1, color='blue', hist_kws={"width": 0.3, "align": "mid"})
ax1.set_ylabel('Train samples')
sns.distplot(y_test, kde=False, ax=ax2, color='green', hist_kws={"width": 0.3, "align": "mid"})
ax2.set_ylabel('Test samples')
ax2.set_xlabel('Labels')
Out[98]:
This is a model that is mostly inspired from here: https://github.com/fchollet/keras/blob/master/examples/mnist_cnn.py
In [16]:
X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols)
X_test = X_test.reshape(X_test.shape[0], 1, img_rows, img_cols)
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, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
In [13]:
model = Sequential()
model.add(Convolution2D(nb_filters, nb_conv, nb_conv,
border_mode='valid',
input_shape=(1, img_rows, img_cols)))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters, nb_conv, nb_conv))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='adadelta',
metrics=['accuracy'])
In [15]:
model.summary()
In [40]:
visualize_util.plot(loaded_model,
to_file='simple_image_classification_architecture.png', show_shapes=True)
In [159]:
load_img('simple_image_classification_architecture.png')
Out[159]:
In [16]:
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch,
verbose=1, 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])
In [29]:
model.save_weights('simple_image_classification_weights.h5')
In [30]:
saved_model = model.to_json()
with open('simple_image_classification_architecture.json', 'w') as outfile:
json.dump(saved_model, outfile)
In [9]:
### Load architecture
with open('simple_image_classification_architecture.json', 'r') as architecture_file:
model_architecture = json.load(architecture_file)
loaded_model = model_from_json(model_architecture)
In [11]:
### Load weights
loaded_model.load_weights('simple_image_classification_weights.h5')
In [21]:
predictions = model.predict_classes(X_test)
In [41]:
(predictions == y_test).sum() / len(predictions)
Out[41]:
In [101]:
### Load, resize, scale and reshape the new digit image (the output is a 4D array)
def load_resize_scale_reshape(img_path):
img = load_img(img_path, grayscale=True, target_size=(img_rows, img_cols))
array_img = img_to_array(img) / 255.0
reshaped_array_img = array_img.reshape(1, *array_img.shape)
return reshaped_array_img
In [156]:
two = load_resize_scale_reshape('data/digits/2.png')
five = load_resize_scale_reshape('data/digits/5.png')
images_list = [two, five]
digits = np.stack(images_list).reshape(len(images_list), *six.shape[1:])
In [157]:
loaded_model.predict_classes(digits)
Out[157]: