Day 2 - MNIST Handwritten Digit Recognition
Hello guys,
This is day 2 of my #100DayOfMLCode challenge. Today, I implemented the MNIST handwritten digit recognition task in Python using the Keras deep learning library.
I studied the following topics:-
- How to load the MNIST dataset in Keras.
- How to develop and evaluate a baseline neural network model for the MNIST problem.
- How to implement and evaluate a simple Convolutional Neural Network for MNIST.
- How to implement a close to state-of-the-art deep learning model for MNIST.
Loading the MNIST dataset in Keras
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from keras.datasets import mnist | |
import matplotlib.pyplot as plt | |
# load (downloaded if needed) the MNIST dataset | |
(X_train, y_train), (X_test, y_test) = mnist.load_data() | |
# plot 4 images as gray scale | |
plt.subplot(221) | |
plt.imshow(X_train[0], cmap=plt.get_cmap('gray')) | |
plt.subplot(222) | |
plt.imshow(X_train[1], cmap=plt.get_cmap('gray')) | |
plt.subplot(223) | |
plt.imshow(X_train[2], cmap=plt.get_cmap('gray')) | |
plt.subplot(224) | |
plt.imshow(X_train[3], cmap=plt.get_cmap('gray')) | |
# show the plot | |
plt.show() |
Baseline Model with Multi-Layer Perceptrons
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#importing libraries | |
import numpy | |
from keras.datasets import mnist | |
from keras.models import Sequential | |
from keras.layers import Dense | |
from keras.layers import Dropout | |
from keras.utils import np_utils | |
# fix random seed for reproducibility | |
seed = 7 | |
numpy.random.seed(seed) | |
# load data | |
(X_train, y_train), (X_test, y_test) = mnist.load_data() | |
# flatten 28*28 images to a 784 vector for each image | |
num_pixels = X_train.shape[1] * X_train.shape[2] | |
X_train = X_train.reshape(X_train.shape[0], num_pixels).astype('float32') | |
X_test = X_test.reshape(X_test.shape[0], num_pixels).astype('float32') | |
# normalize inputs from 0-255 to 0-1 | |
X_train = X_train / 255 | |
X_test = X_test / 255 | |
# one hot encode outputs | |
y_train = np_utils.to_categorical(y_train) | |
y_test = np_utils.to_categorical(y_test) | |
num_classes = y_test.shape[1] | |
# one hot encode outputs | |
y_train = np_utils.to_categorical(y_train) | |
y_test = np_utils.to_categorical(y_test) | |
num_classes = y_test.shape[1] | |
# define baseline model | |
def baseline_model(): | |
# create model | |
model = Sequential() | |
model.add(Dense(num_pixels, input_dim=num_pixels, kernel_initializer='normal', activation='relu')) | |
model.add(Dense(num_classes, kernel_initializer='normal', activation='softmax')) | |
# Compile model | |
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) | |
return model | |
# build the model | |
model = baseline_model() | |
# Fit the model | |
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=200, verbose=2) | |
# Final evaluation of the model | |
scores = model.evaluate(X_test, y_test, verbose=0) | |
print("Baseline Error: %.2f%%" % (100-scores[1]*100)) |
Output-
Simple Convolutional Neural Network for MNIST
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy | |
from keras.datasets import mnist | |
from keras.models import Sequential | |
from keras.layers import Dense | |
from keras.layers import Dropout | |
from keras.layers import Flatten | |
from keras.layers.convolutional import Conv2D | |
from keras.layers.convolutional import MaxPooling2D | |
from keras.utils import np_utils | |
from keras import backend as K | |
K.set_image_dim_ordering('th') | |
# fix random seed for reproducibility | |
seed = 7 | |
numpy.random.seed(seed) | |
# load data | |
(X_train, y_train), (X_test, y_test) = mnist.load_data() | |
# reshape to be [samples][pixels][width][height] | |
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28).astype('float32') | |
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28).astype('float32') | |
# normalize inputs from 0-255 to 0-1 | |
X_train = X_train / 255 | |
X_test = X_test / 255 | |
# one hot encode outputs | |
y_train = np_utils.to_categorical(y_train) | |
y_test = np_utils.to_categorical(y_test) | |
num_classes = y_test.shape[1] | |
def baseline_model(): | |
# create model | |
model = Sequential() | |
model.add(Conv2D(32, (5, 5), input_shape=(1, 28, 28), activation='relu')) | |
model.add(MaxPooling2D(pool_size=(2, 2))) | |
model.add(Dropout(0.2)) | |
model.add(Flatten()) | |
model.add(Dense(128, activation='relu')) | |
model.add(Dense(num_classes, activation='softmax')) | |
# Compile model | |
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) | |
return model | |
# build the model | |
model = baseline_model() | |
# Fit the model | |
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=200, verbose=2) | |
# Final evaluation of the model | |
scores = model.evaluate(X_test, y_test, verbose=0) | |
print("CNN Error: %.2f%%" % (100-scores[1]*100)) |
Output-
Thanks.
Happy Coding
Happy Coding