Using Functional API to build CNN

~99.3% test accuracy


In [1]:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np
from keras.layers import Dense, Dropout, Input
from keras.layers import Conv2D, MaxPooling2D, Flatten
from keras.models import Model
from keras.datasets import mnist
from keras.utils import to_categorical


# load MNIST dataset
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# from sparse label to categorical
num_labels = len(np.unique(y_train))
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

# reshape and normalize input images
image_size = x_train.shape[1]
x_train = np.reshape(x_train,[-1, image_size, image_size, 1])
x_test = np.reshape(x_test,[-1, image_size, image_size, 1])
x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255

# network parameters
input_shape = (image_size, image_size, 1)
batch_size = 128
kernel_size = 3
filters = 64
dropout = 0.3

# use functional API to build cnn layers
inputs = Input(shape=input_shape)
y = Conv2D(filters=filters,
           kernel_size=kernel_size,
           activation='relu')(inputs)
y = MaxPooling2D()(y)
y = Conv2D(filters=filters,
           kernel_size=kernel_size,
           activation='relu')(y)
y = MaxPooling2D()(y)
y = Conv2D(filters=filters,
           kernel_size=kernel_size,
           activation='relu')(y)
# image to vector before connecting to dense layer
y = Flatten()(y)
# dropout regularization
y = Dropout(dropout)(y)
outputs = Dense(num_labels, activation='softmax')(y)

# build the model by supplying inputs/outputs
model = Model(inputs=inputs, outputs=outputs)
# network model in text
model.summary()

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

# train the model with input images and labels
model.fit(x_train,
          y_train,
          validation_data=(x_test, y_test),
          epochs=20,
          batch_size=batch_size)

# model accuracy on test dataset
score = model.evaluate(x_test, y_test, batch_size=batch_size)
print("\nTest accuracy: %.1f%%" % (100.0 * score[1]))


/usr/local/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  from ._conv import register_converters as _register_converters
Using TensorFlow backend.
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 28, 28, 1)         0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 26, 26, 64)        640       
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 13, 13, 64)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 11, 11, 64)        36928     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 3, 3, 64)          36928     
_________________________________________________________________
flatten_1 (Flatten)          (None, 576)               0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 576)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 10)                5770      
=================================================================
Total params: 80,266
Trainable params: 80,266
Non-trainable params: 0
_________________________________________________________________
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 54s 904us/step - loss: 0.2666 - acc: 0.9176 - val_loss: 0.0542 - val_acc: 0.9835
Epoch 2/20
60000/60000 [==============================] - 55s 913us/step - loss: 0.0719 - acc: 0.9775 - val_loss: 0.0380 - val_acc: 0.9886
Epoch 3/20
60000/60000 [==============================] - 55s 914us/step - loss: 0.0505 - acc: 0.9840 - val_loss: 0.0384 - val_acc: 0.9863
Epoch 4/20
60000/60000 [==============================] - 56s 937us/step - loss: 0.0408 - acc: 0.9871 - val_loss: 0.0286 - val_acc: 0.9900
Epoch 5/20
60000/60000 [==============================] - 56s 933us/step - loss: 0.0358 - acc: 0.9886 - val_loss: 0.0253 - val_acc: 0.9914
Epoch 6/20
60000/60000 [==============================] - 56s 927us/step - loss: 0.0297 - acc: 0.9906 - val_loss: 0.0238 - val_acc: 0.9921
Epoch 7/20
60000/60000 [==============================] - 56s 932us/step - loss: 0.0275 - acc: 0.9913 - val_loss: 0.0310 - val_acc: 0.9897
Epoch 8/20
60000/60000 [==============================] - 54s 902us/step - loss: 0.0238 - acc: 0.9924 - val_loss: 0.0237 - val_acc: 0.9918
Epoch 9/20
60000/60000 [==============================] - 57s 952us/step - loss: 0.0220 - acc: 0.9925 - val_loss: 0.0234 - val_acc: 0.9923
Epoch 10/20
60000/60000 [==============================] - 84s 1ms/step - loss: 0.0194 - acc: 0.9937 - val_loss: 0.0286 - val_acc: 0.9915
Epoch 11/20
60000/60000 [==============================] - 100s 2ms/step - loss: 0.0176 - acc: 0.9939 - val_loss: 0.0203 - val_acc: 0.9931
Epoch 12/20
60000/60000 [==============================] - 130s 2ms/step - loss: 0.0160 - acc: 0.9948 - val_loss: 0.0255 - val_acc: 0.9921
Epoch 13/20
60000/60000 [==============================] - 129s 2ms/step - loss: 0.0146 - acc: 0.9953 - val_loss: 0.0259 - val_acc: 0.9921
Epoch 14/20
60000/60000 [==============================] - 130s 2ms/step - loss: 0.0149 - acc: 0.9950 - val_loss: 0.0240 - val_acc: 0.9926
Epoch 15/20
60000/60000 [==============================] - 134s 2ms/step - loss: 0.0119 - acc: 0.9960 - val_loss: 0.0218 - val_acc: 0.9937
Epoch 16/20
60000/60000 [==============================] - 136s 2ms/step - loss: 0.0122 - acc: 0.9958 - val_loss: 0.0221 - val_acc: 0.9932
Epoch 17/20
60000/60000 [==============================] - 127s 2ms/step - loss: 0.0123 - acc: 0.9962 - val_loss: 0.0236 - val_acc: 0.9934
Epoch 18/20
60000/60000 [==============================] - 135s 2ms/step - loss: 0.0095 - acc: 0.9968 - val_loss: 0.0267 - val_acc: 0.9922
Epoch 19/20
60000/60000 [==============================] - 145s 2ms/step - loss: 0.0100 - acc: 0.9967 - val_loss: 0.0218 - val_acc: 0.9930
Epoch 20/20
60000/60000 [==============================] - 134s 2ms/step - loss: 0.0087 - acc: 0.9970 - val_loss: 0.0228 - val_acc: 0.9929
10000/10000 [==============================] - 5s 543us/step

Test accuracy: 99.3%

In [ ]: