In [14]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.utils import np_utils
from keras.layers import Convolution2D, MaxPooling2D

np.random.seed(25)

In [2]:
(X_train, y_train), (X_test, y_test) = mnist.load_data()
print("X_train original shape", X_train.shape)
print("y_train original shape", y_train.shape)
print("X_test original shape", X_test.shape)
print("y_test original shape", y_test.shape)


X_train original shape (60000, 28, 28)
y_train original shape (60000,)
X_test original shape (10000, 28, 28)
y_test original shape (10000,)

In [3]:
plt.imshow(X_train[0], cmap='gray')
plt.title('Class '+ str(y_train[0]))


Out[3]:
<matplotlib.text.Text at 0x7fdaefb16550>

In [4]:
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1)
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1)

X_train = X_train.astype('float32')
X_test = X_test.astype('float32')

X_train/=255
X_test/=255

X_train.shape


Out[4]:
(60000, 28, 28, 1)

In [5]:
number_of_classes = 10

Y_train = np_utils.to_categorical(y_train, number_of_classes)
Y_test = np_utils.to_categorical(y_test, number_of_classes)

y_train[0], Y_train[0]


Out[5]:
(5, array([ 0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.]))

In [9]:
# Three steps to Convolution
# 1. Convolution
# 2. Activation
# 3. Polling
# Repeat Steps 1,2,3 for adding more hidden layers

# 4. After that make a fully connected network
# This fully connected network gives ability to the CNN
# to classify the samples

model = Sequential()

model.add(Convolution2D(32, 3, 3, input_shape=(28,28,1)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Convolution2D(32,3,3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.2))
model.add(Flatten())

model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.2))

model.add(Dense(10))
model.add(Activation('softmax'))

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

In [11]:
model.fit(X_train, Y_train, batch_size=128, nb_epoch=5, validation_data=(X_test, Y_test))


Train on 60000 samples, validate on 10000 samples
Epoch 1/5
60000/60000 [==============================] - 63s - loss: 0.2177 - acc: 0.9348 - val_loss: 0.0642 - val_acc: 0.9796
Epoch 2/5
60000/60000 [==============================] - 62s - loss: 0.0668 - acc: 0.9792 - val_loss: 0.0388 - val_acc: 0.9873
Epoch 3/5
60000/60000 [==============================] - 67s - loss: 0.0480 - acc: 0.9853 - val_loss: 0.0366 - val_acc: 0.9873
Epoch 4/5
60000/60000 [==============================] - 63s - loss: 0.0386 - acc: 0.9878 - val_loss: 0.0303 - val_acc: 0.9906
Epoch 5/5
60000/60000 [==============================] - 64s - loss: 0.0309 - acc: 0.9904 - val_loss: 0.0238 - val_acc: 0.9925
Out[11]:
<keras.callbacks.History at 0x7fdadc64b978>

In [12]:
score = model.evaluate(X_test, Y_test)
print()
print('Test accuracy: ', score[1])


 9888/10000 [============================>.] - ETA: 0s
Test accuracy:  0.9925

In [13]:
predictions = model.predict_classes(X_test)

predictions = list(predictions)
actuals = list(y_test)

sub = pd.DataFrame({'Actual': actuals, 'Predictions': predictions})
sub.to_csv('./output_cnn.csv', index=False)


 9920/10000 [============================>.] - ETA: 0s