Build your own CNN (Feature Transformer)

In [4]:
import numpy as np
import pandas as pd
import keras
import matplotlib.pyplot as plt
%matplotlib inline
import vis
In [5]:
# !pip install altair

Get Data

In [7]:
from keras.datasets import fashion_mnist
In [8]:
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
In [9]:
labels = vis.fashion_mnist_label()

Step 1: Prepare the Input & Output

In [11]:
from keras import backend as K
In [12]:
K.image_data_format()
Out[12]:
'channels_last'
In [14]:
# Prepare the input
x_train_conv = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test_conv = x_test.reshape(x_test.shape[0], 28, 28, 1)
In [18]:
x_train_conv.shape, x_test_conv.shape
Out[18]:
((60000, 28, 28, 1), (10000, 28, 28, 1))
In [15]:
# Normalise the input
x_train_conv = x_train_conv.astype("float32")/ 255
x_test_conv = x_test_conv.astype("float32")/ 255
In [16]:
from keras.utils import to_categorical
In [17]:
# Prepare the output
y_train_class = to_categorical(y_train, 10)
y_test_class = to_categorical(y_test, 10)

Step 2: Prepare the model

In [20]:
from keras.models import Sequential
from keras.layers import Dense, Flatten, Conv2D, MaxPooling2D, Dropout
In [24]:
cnn = Sequential()
cnn.add(Conv2D(32, kernel_size=(3,3), activation="relu", input_shape=(28,28,1)))
cnn.add(MaxPooling2D(pool_size=(2,2)))
cnn.add(Conv2D(64, kernel_size=(3,3), activation="relu"))
cnn.add(MaxPooling2D(pool_size=(2,2)))
cnn.add(Flatten())
cnn.add(Dense(128, activation="relu"))
cnn.add(Dropout(0.25))
cnn.add(Dense(10, activation="softmax"))
In [25]:
cnn.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_3 (Conv2D)            (None, 26, 26, 32)        320       
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 13, 13, 32)        0         
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 11, 11, 64)        18496     
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
flatten_2 (Flatten)          (None, 1600)              0         
_________________________________________________________________
dense_3 (Dense)              (None, 128)               204928    
_________________________________________________________________
dropout_3 (Dropout)          (None, 128)               0         
_________________________________________________________________
dense_4 (Dense)              (None, 10)                1290      
=================================================================
Total params: 225,034
Trainable params: 225,034
Non-trainable params: 0
_________________________________________________________________

Step 3: Compile and fit the model

In [26]:
cnn.compile(loss="categorical_crossentropy", optimizer="sgd", metrics=['accuracy'])
In [36]:
%%time
output_cnn = cnn.fit(x_train_conv, y_train_class, batch_size=128, epochs=20, shuffle=True,
                    verbose=2, validation_data=(x_test_conv, y_test_class))
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
 - 4s - loss: 0.5690 - acc: 0.7866 - val_loss: 0.5510 - val_acc: 0.7950
Epoch 2/20
 - 4s - loss: 0.5456 - acc: 0.7943 - val_loss: 0.5348 - val_acc: 0.7989
Epoch 3/20
 - 4s - loss: 0.5240 - acc: 0.8045 - val_loss: 0.5093 - val_acc: 0.8099
Epoch 4/20
 - 4s - loss: 0.5072 - acc: 0.8106 - val_loss: 0.4976 - val_acc: 0.8142
Epoch 5/20
 - 4s - loss: 0.4928 - acc: 0.8168 - val_loss: 0.4783 - val_acc: 0.8260
Epoch 6/20
 - 4s - loss: 0.4817 - acc: 0.8219 - val_loss: 0.4799 - val_acc: 0.8234
Epoch 7/20
 - 4s - loss: 0.4702 - acc: 0.8284 - val_loss: 0.4839 - val_acc: 0.8217
Epoch 8/20
 - 4s - loss: 0.4598 - acc: 0.8311 - val_loss: 0.4511 - val_acc: 0.8376
Epoch 9/20
 - 4s - loss: 0.4489 - acc: 0.8362 - val_loss: 0.4566 - val_acc: 0.8294
Epoch 10/20
 - 4s - loss: 0.4395 - acc: 0.8394 - val_loss: 0.4509 - val_acc: 0.8362
Epoch 11/20
 - 4s - loss: 0.4333 - acc: 0.8425 - val_loss: 0.4287 - val_acc: 0.8452
Epoch 12/20
 - 4s - loss: 0.4256 - acc: 0.8450 - val_loss: 0.4217 - val_acc: 0.8477
Epoch 13/20
 - 4s - loss: 0.4196 - acc: 0.8486 - val_loss: 0.4186 - val_acc: 0.8482
Epoch 14/20
 - 4s - loss: 0.4133 - acc: 0.8508 - val_loss: 0.4111 - val_acc: 0.8512
Epoch 15/20
 - 4s - loss: 0.4062 - acc: 0.8528 - val_loss: 0.4078 - val_acc: 0.8510
Epoch 16/20
 - 4s - loss: 0.4001 - acc: 0.8550 - val_loss: 0.4065 - val_acc: 0.8513
Epoch 17/20
 - 4s - loss: 0.3943 - acc: 0.8569 - val_loss: 0.4024 - val_acc: 0.8535
Epoch 18/20
 - 4s - loss: 0.3906 - acc: 0.8579 - val_loss: 0.3944 - val_acc: 0.8569
Epoch 19/20
 - 4s - loss: 0.3841 - acc: 0.8625 - val_loss: 0.3873 - val_acc: 0.8603
Epoch 20/20
 - 4s - loss: 0.3818 - acc: 0.8619 - val_loss: 0.3760 - val_acc: 0.8633
CPU times: user 1min 17s, sys: 17.5 s, total: 1min 34s
Wall time: 1min 12s

Step 4: Check the performance of the model

In [30]:
vis.metrics(output_cnn.history)
Out[30]:
In [32]:
score=cnn.evaluate(x_test_conv, y_test_class)
10000/10000 [==============================] - 1s 68us/step
In [34]:
print("Test Accuracy:", score[1])
Test Accuracy: 0.7924

Step 5: Make & Visualise Prediction

In [37]:
predict_classes_cnn = cnn.predict_classes(x_test_conv)
In [38]:
pd.crosstab(y_test, predict_classes_cnn)
Out[38]:
col_0 0 1 2 3 4 5 6 7 8 9
row_0
0 821 2 19 35 5 3 106 0 9 0
1 3 964 1 22 4 0 4 0 2 0
2 16 1 770 13 117 0 75 0 8 0
3 13 6 16 884 35 0 42 0 4 0
4 1 0 79 36 781 0 95 0 8 0
5 0 0 0 0 0 948 0 34 2 16
6 137 2 101 25 116 0 605 0 14 0
7 0 0 0 0 0 24 0 938 0 38
8 1 1 9 5 3 1 6 5 969 0
9 0 0 0 0 0 7 0 39 1 953