Keras Implementation¶
We will use CIFAR-10 dataset to build a CNN image classifier. CIFAR-10 dataset has 10 different labels
- Airplane
- Automobile
- Bird
- Cat
- Deer
- Dog
- Frog
- Horse
- Ship
- Truck
It has 50,000 training data and 10,000 testing image data. Image size in CIFAR-10 is 32 x 32 x 3. It comes with Keras library
Check GPU¶
In [2]:
Copied!
import tensorflow as tf
device_name = tf.test.gpu_device_name()
if device_name != '/device:GPU:0':
raise SystemError('GPU device not found')
print('Found GPU at: {}'.format(device_name))
import tensorflow as tf
device_name = tf.test.gpu_device_name()
if device_name != '/device:GPU:0':
raise SystemError('GPU device not found')
print('Found GPU at: {}'.format(device_name))
Found GPU at: /device:GPU:0
Load libraries¶
In [3]:
Copied!
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import keras
from keras.models import Sequential
from keras.utils import to_categorical
from keras.layers import Dense, Conv2D, MaxPooling2D, Dropout, Flatten
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import keras
from keras.models import Sequential
from keras.utils import to_categorical
from keras.layers import Dense, Conv2D, MaxPooling2D, Dropout, Flatten
Data Processing¶
In [4]:
Copied!
from keras.datasets import cifar10
(train_images, train_labels), (test_images, test_labels) = cifar10.load_data()
print('Training data shape : ', train_images.shape, train_labels.shape)
print('Testing data shape : ', test_images.shape, test_labels.shape)
from keras.datasets import cifar10
(train_images, train_labels), (test_images, test_labels) = cifar10.load_data()
print('Training data shape : ', train_images.shape, train_labels.shape)
print('Testing data shape : ', test_images.shape, test_labels.shape)
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz 170498071/170498071 [==============================] - 15s 0us/step Training data shape : (50000, 32, 32, 3) (50000, 1) Testing data shape : (10000, 32, 32, 3) (10000, 1)
In [5]:
Copied!
# Find the unique numbers from the train labels
classes = np.unique(train_labels)
nClasses = len(classes)
print('Total number of outputs : ', nClasses)
print('Output classes : ', classes)
# Find the unique numbers from the train labels
classes = np.unique(train_labels)
nClasses = len(classes)
print('Total number of outputs : ', nClasses)
print('Output classes : ', classes)
Total number of outputs : 10 Output classes : [0 1 2 3 4 5 6 7 8 9]
In [6]:
Copied!
plt.figure(figsize=[4,2])
# Display the first image in training data
plt.subplot(121)
plt.imshow(train_images[0,:,:], cmap='gray')
plt.title("Ground Truth : {}".format(train_labels[0]))
# Display the first image in testing data
plt.subplot(122)
plt.imshow(test_images[0,:,:], cmap='gray')
plt.title("Ground Truth : {}".format(test_labels[0]))
plt.figure(figsize=[4,2])
# Display the first image in training data
plt.subplot(121)
plt.imshow(train_images[0,:,:], cmap='gray')
plt.title("Ground Truth : {}".format(train_labels[0]))
# Display the first image in testing data
plt.subplot(122)
plt.imshow(test_images[0,:,:], cmap='gray')
plt.title("Ground Truth : {}".format(test_labels[0]))
Out[6]:
Text(0.5, 1.0, 'Ground Truth : [3]')
Reshape data¶
In [7]:
Copied!
nRows,nCols,nDims = train_images.shape[1:]
train_data = train_images.reshape(train_images.shape[0], nRows, nCols, nDims)
test_data = test_images.reshape(test_images.shape[0], nRows, nCols, nDims)
input_shape = (nRows, nCols, nDims)
train_data = train_data.astype('float32')
test_data = test_data.astype('float32')
nRows,nCols,nDims = train_images.shape[1:]
train_data = train_images.reshape(train_images.shape[0], nRows, nCols, nDims)
test_data = test_images.reshape(test_images.shape[0], nRows, nCols, nDims)
input_shape = (nRows, nCols, nDims)
train_data = train_data.astype('float32')
test_data = test_data.astype('float32')
Normalize the data¶
In [8]:
Copied!
train_data /= 255
test_data /= 255
train_labels_one_hot = to_categorical(train_labels)
test_labels_one_hot = to_categorical(test_labels)
train_data /= 255
test_data /= 255
train_labels_one_hot = to_categorical(train_labels)
test_labels_one_hot = to_categorical(test_labels)
In [9]:
Copied!
## Display the change for category label using one-hot encoding.
print('Original label 0 : ', train_labels[0])
print('After conversion to categorical ( one-hot ) : ', train_labels_one_hot[0])
## Display the change for category label using one-hot encoding.
print('Original label 0 : ', train_labels[0])
print('After conversion to categorical ( one-hot ) : ', train_labels_one_hot[0])
Original label 0 : [6] After conversion to categorical ( one-hot ) : [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
Create Model¶
- We will add up Convo layers followed by pooling layers.
- Then we will connect Dense(FC) layer to predict the classes.
- Input data fed to first Convo layer, output of that Convo layer acts as input for next Convo layer and so on.
- Finally data is fed to FC layer which try to predict the correct labels.
In [10]:
Copied!
def createModel():
model = Sequential()
# The first two layers with 32 filters of window size 3x3
model.add(Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=input_shape))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(nClasses, activation='softmax'))
return model
def createModel():
model = Sequential()
# The first two layers with 32 filters of window size 3x3
model.add(Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=input_shape))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(nClasses, activation='softmax'))
return model
Initialize all parameters and specify loss function and optimizer¶
In [11]:
Copied!
model1 = createModel()
batch_size = 256
epochs = 50
model1.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model1 = createModel()
batch_size = 256
epochs = 50
model1.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()
is used to see all parameters and shapes in each layers in our models.
You can observe that total parameters are 276, 138 and total trainable parameters are 276, 138.
Non-trainable parameter is 0.
In [12]:
Copied!
model1.summary()
model1.summary()
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 32, 32, 32) 896 conv2d_1 (Conv2D) (None, 30, 30, 32) 9248 max_pooling2d (MaxPooling2D (None, 15, 15, 32) 0 ) dropout (Dropout) (None, 15, 15, 32) 0 conv2d_2 (Conv2D) (None, 15, 15, 64) 18496 conv2d_3 (Conv2D) (None, 13, 13, 64) 36928 max_pooling2d_1 (MaxPooling (None, 6, 6, 64) 0 2D) dropout_1 (Dropout) (None, 6, 6, 64) 0 conv2d_4 (Conv2D) (None, 6, 6, 64) 36928 conv2d_5 (Conv2D) (None, 4, 4, 64) 36928 max_pooling2d_2 (MaxPooling (None, 2, 2, 64) 0 2D) dropout_2 (Dropout) (None, 2, 2, 64) 0 flatten (Flatten) (None, 256) 0 dense (Dense) (None, 512) 131584 dropout_3 (Dropout) (None, 512) 0 dense_1 (Dense) (None, 10) 5130 ================================================================= Total params: 276,138 Trainable params: 276,138 Non-trainable params: 0 _________________________________________________________________
Fit data in¶
In [13]:
Copied!
history = model1.fit(train_data,
train_labels_one_hot,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(test_data, test_labels_one_hot))
model1.evaluate(test_data, test_labels_one_hot)
history = model1.fit(train_data,
train_labels_one_hot,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(test_data, test_labels_one_hot))
model1.evaluate(test_data, test_labels_one_hot)
Epoch 1/50 196/196 [==============================] - 23s 21ms/step - loss: 2.0635 - accuracy: 0.2349 - val_loss: 1.7800 - val_accuracy: 0.3685 Epoch 2/50 196/196 [==============================] - 3s 13ms/step - loss: 1.7274 - accuracy: 0.3723 - val_loss: 1.7093 - val_accuracy: 0.3618 Epoch 3/50 196/196 [==============================] - 3s 14ms/step - loss: 1.5212 - accuracy: 0.4532 - val_loss: 1.3849 - val_accuracy: 0.5216 Epoch 4/50 196/196 [==============================] - 3s 13ms/step - loss: 1.3829 - accuracy: 0.5051 - val_loss: 1.3491 - val_accuracy: 0.5238 Epoch 5/50 196/196 [==============================] - 3s 13ms/step - loss: 1.2761 - accuracy: 0.5458 - val_loss: 1.1934 - val_accuracy: 0.5774 Epoch 6/50 196/196 [==============================] - 3s 13ms/step - loss: 1.1873 - accuracy: 0.5760 - val_loss: 1.3081 - val_accuracy: 0.5609 Epoch 7/50 196/196 [==============================] - 3s 13ms/step - loss: 1.1227 - accuracy: 0.6057 - val_loss: 1.1414 - val_accuracy: 0.6008 Epoch 8/50 196/196 [==============================] - 3s 13ms/step - loss: 1.0520 - accuracy: 0.6304 - val_loss: 1.0671 - val_accuracy: 0.6210 Epoch 9/50 196/196 [==============================] - 3s 13ms/step - loss: 0.9989 - accuracy: 0.6498 - val_loss: 0.9351 - val_accuracy: 0.6670 Epoch 10/50 196/196 [==============================] - 3s 13ms/step - loss: 0.9496 - accuracy: 0.6690 - val_loss: 0.8911 - val_accuracy: 0.6865 Epoch 11/50 196/196 [==============================] - 3s 13ms/step - loss: 0.9022 - accuracy: 0.6851 - val_loss: 0.8515 - val_accuracy: 0.7009 Epoch 12/50 196/196 [==============================] - 3s 13ms/step - loss: 0.8585 - accuracy: 0.6996 - val_loss: 0.9883 - val_accuracy: 0.6675 Epoch 13/50 196/196 [==============================] - 3s 14ms/step - loss: 0.8270 - accuracy: 0.7120 - val_loss: 0.7599 - val_accuracy: 0.7358 Epoch 14/50 196/196 [==============================] - 3s 14ms/step - loss: 0.7909 - accuracy: 0.7251 - val_loss: 0.8385 - val_accuracy: 0.7140 Epoch 15/50 196/196 [==============================] - 3s 13ms/step - loss: 0.7656 - accuracy: 0.7326 - val_loss: 0.7481 - val_accuracy: 0.7385 Epoch 16/50 196/196 [==============================] - 3s 14ms/step - loss: 0.7421 - accuracy: 0.7410 - val_loss: 0.8492 - val_accuracy: 0.7176 Epoch 17/50 196/196 [==============================] - 3s 13ms/step - loss: 0.7221 - accuracy: 0.7511 - val_loss: 0.6704 - val_accuracy: 0.7696 Epoch 18/50 196/196 [==============================] - 3s 13ms/step - loss: 0.7005 - accuracy: 0.7556 - val_loss: 0.7235 - val_accuracy: 0.7519 Epoch 19/50 196/196 [==============================] - 3s 13ms/step - loss: 0.6782 - accuracy: 0.7647 - val_loss: 0.7859 - val_accuracy: 0.7450 Epoch 20/50 196/196 [==============================] - 3s 14ms/step - loss: 0.6688 - accuracy: 0.7704 - val_loss: 0.7000 - val_accuracy: 0.7591 Epoch 21/50 196/196 [==============================] - 3s 14ms/step - loss: 0.6495 - accuracy: 0.7747 - val_loss: 0.8003 - val_accuracy: 0.7359 Epoch 22/50 196/196 [==============================] - 3s 14ms/step - loss: 0.6343 - accuracy: 0.7792 - val_loss: 0.6582 - val_accuracy: 0.7777 Epoch 23/50 196/196 [==============================] - 3s 13ms/step - loss: 0.6170 - accuracy: 0.7868 - val_loss: 0.6441 - val_accuracy: 0.7852 Epoch 24/50 196/196 [==============================] - 3s 13ms/step - loss: 0.6101 - accuracy: 0.7902 - val_loss: 0.7041 - val_accuracy: 0.7629 Epoch 25/50 196/196 [==============================] - 3s 14ms/step - loss: 0.5984 - accuracy: 0.7928 - val_loss: 0.7197 - val_accuracy: 0.7627 Epoch 26/50 196/196 [==============================] - 3s 13ms/step - loss: 0.5909 - accuracy: 0.7960 - val_loss: 0.6819 - val_accuracy: 0.7719 Epoch 27/50 196/196 [==============================] - 3s 13ms/step - loss: 0.5738 - accuracy: 0.8020 - val_loss: 0.6671 - val_accuracy: 0.7772 Epoch 28/50 196/196 [==============================] - 3s 13ms/step - loss: 0.5652 - accuracy: 0.8044 - val_loss: 0.6551 - val_accuracy: 0.7806 Epoch 29/50 196/196 [==============================] - 4s 19ms/step - loss: 0.5619 - accuracy: 0.8059 - val_loss: 0.6860 - val_accuracy: 0.7753 Epoch 30/50 196/196 [==============================] - 4s 20ms/step - loss: 0.5555 - accuracy: 0.8077 - val_loss: 0.6611 - val_accuracy: 0.7873 Epoch 31/50 196/196 [==============================] - 4s 20ms/step - loss: 0.5438 - accuracy: 0.8097 - val_loss: 0.6509 - val_accuracy: 0.7866 Epoch 32/50 196/196 [==============================] - 4s 20ms/step - loss: 0.5352 - accuracy: 0.8161 - val_loss: 0.6431 - val_accuracy: 0.7892 Epoch 33/50 196/196 [==============================] - 4s 21ms/step - loss: 0.5333 - accuracy: 0.8176 - val_loss: 0.6354 - val_accuracy: 0.7891 Epoch 34/50 196/196 [==============================] - 4s 23ms/step - loss: 0.5279 - accuracy: 0.8176 - val_loss: 0.6336 - val_accuracy: 0.7940 Epoch 35/50 196/196 [==============================] - 5s 24ms/step - loss: 0.5218 - accuracy: 0.8202 - val_loss: 0.6622 - val_accuracy: 0.7851 Epoch 36/50 196/196 [==============================] - 5s 23ms/step - loss: 0.5197 - accuracy: 0.8204 - val_loss: 0.7469 - val_accuracy: 0.7623 Epoch 37/50 196/196 [==============================] - 5s 24ms/step - loss: 0.5127 - accuracy: 0.8248 - val_loss: 0.7208 - val_accuracy: 0.7579 Epoch 38/50 196/196 [==============================] - 5s 23ms/step - loss: 0.5022 - accuracy: 0.8273 - val_loss: 0.7328 - val_accuracy: 0.7765 Epoch 39/50 196/196 [==============================] - 5s 23ms/step - loss: 0.5008 - accuracy: 0.8272 - val_loss: 0.6307 - val_accuracy: 0.7917 Epoch 40/50 196/196 [==============================] - 5s 24ms/step - loss: 0.5010 - accuracy: 0.8279 - val_loss: 0.6767 - val_accuracy: 0.7827 Epoch 41/50 196/196 [==============================] - 4s 22ms/step - loss: 0.4983 - accuracy: 0.8272 - val_loss: 0.5953 - val_accuracy: 0.8034 Epoch 42/50 196/196 [==============================] - 4s 19ms/step - loss: 0.4932 - accuracy: 0.8306 - val_loss: 0.6459 - val_accuracy: 0.7940 Epoch 43/50 196/196 [==============================] - 4s 22ms/step - loss: 0.4859 - accuracy: 0.8322 - val_loss: 0.6623 - val_accuracy: 0.8014 Epoch 44/50 196/196 [==============================] - 4s 21ms/step - loss: 0.4866 - accuracy: 0.8341 - val_loss: 0.6432 - val_accuracy: 0.7969 Epoch 45/50 196/196 [==============================] - 5s 24ms/step - loss: 0.4788 - accuracy: 0.8355 - val_loss: 0.8475 - val_accuracy: 0.7470 Epoch 46/50 196/196 [==============================] - 4s 22ms/step - loss: 0.4803 - accuracy: 0.8332 - val_loss: 0.7082 - val_accuracy: 0.7832 Epoch 47/50 196/196 [==============================] - 5s 23ms/step - loss: 0.4734 - accuracy: 0.8353 - val_loss: 0.6438 - val_accuracy: 0.7987 Epoch 48/50 196/196 [==============================] - 4s 22ms/step - loss: 0.4705 - accuracy: 0.8363 - val_loss: 0.6317 - val_accuracy: 0.8033 Epoch 49/50 196/196 [==============================] - 5s 24ms/step - loss: 0.4670 - accuracy: 0.8402 - val_loss: 0.7534 - val_accuracy: 0.7684 Epoch 50/50 196/196 [==============================] - 4s 22ms/step - loss: 0.4637 - accuracy: 0.8415 - val_loss: 0.6584 - val_accuracy: 0.7933 313/313 [==============================] - 1s 3ms/step - loss: 0.6584 - accuracy: 0.7933
Out[13]:
[0.6583714485168457, 0.7932999730110168]
Evaluate results¶
In [14]:
Copied!
plt.figure(figsize=[8,6])
plt.plot(history.history['loss'],'r',linewidth=3.0)
plt.plot(history.history['val_loss'],'b',linewidth=3.0)
plt.legend(['Training loss', 'Validation Loss'],fontsize=18)
plt.xlabel('Epochs ',fontsize=16)
plt.ylabel('Loss',fontsize=16)
plt.title('Loss Curves',fontsize=16)
plt.figure(figsize=[8,6])
plt.plot(history.history['loss'],'r',linewidth=3.0)
plt.plot(history.history['val_loss'],'b',linewidth=3.0)
plt.legend(['Training loss', 'Validation Loss'],fontsize=18)
plt.xlabel('Epochs ',fontsize=16)
plt.ylabel('Loss',fontsize=16)
plt.title('Loss Curves',fontsize=16)
Out[14]:
Text(0.5, 1.0, 'Loss Curves')
In [18]:
Copied!
plt.figure(figsize=[8,6])
plt.plot(history.history['accuracy'],'r',linewidth=3.0)
plt.plot(history.history['val_accuracy'],'b',linewidth=3.0)
plt.legend(['Training Accuracy', 'Validation Accuracy'],fontsize=18)
plt.xlabel('Epochs ',fontsize=16)
plt.ylabel('Accuracy',fontsize=16)
plt.title('Accuracy Curves',fontsize=16)
plt.figure(figsize=[8,6])
plt.plot(history.history['accuracy'],'r',linewidth=3.0)
plt.plot(history.history['val_accuracy'],'b',linewidth=3.0)
plt.legend(['Training Accuracy', 'Validation Accuracy'],fontsize=18)
plt.xlabel('Epochs ',fontsize=16)
plt.ylabel('Accuracy',fontsize=16)
plt.title('Accuracy Curves',fontsize=16)
Out[18]:
Text(0.5, 1.0, 'Accuracy Curves')