Jovian
⭐️
Sign In
In [1]:
import jovian
In [3]:
!pip install jovian --user
Collecting jovian Downloading https://files.pythonhosted.org/packages/53/b8/07dbaf8e226aabf7909f099bd696dddf25327329dbb22e00691ba9df84cc/jovian-0.1.62.tar.gz Requirement already satisfied: requests in /home/ubuntu/anaconda3/lib/python3.7/site-packages (from jovian) (2.21.0) Collecting uuid (from jovian) Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /home/ubuntu/anaconda3/lib/python3.7/site-packages (from requests->jovian) (3.0.4) Requirement already satisfied: certifi>=2017.4.17 in /home/ubuntu/anaconda3/lib/python3.7/site-packages (from requests->jovian) (2019.3.9) Requirement already satisfied: urllib3<1.25,>=1.21.1 in /home/ubuntu/anaconda3/lib/python3.7/site-packages (from requests->jovian) (1.24.1) Requirement already satisfied: idna<2.9,>=2.5 in /home/ubuntu/anaconda3/lib/python3.7/site-packages (from requests->jovian) (2.8) Building wheels for collected packages: jovian Building wheel for jovian (setup.py) ... done Stored in directory: /home/ubuntu/.cache/pip/wheels/67/9f/b0/b841f81da3f8c9919ed232fa14bba397c5c38fa8df5d125d8a Successfully built jovian Installing collected packages: uuid, jovian Successfully installed jovian-0.1.62 uuid-1.30

Assigment Definition:

In this assignement, we will compare different Deep Convolutional Neural Networks in terms of:

  • "number of parameters"
  • "inference time"
  • "performance".

You will be required to construct the following networks:

  1. AlexNet
  2. VGG-16
  3. Your custom Deep CNN (CNN_5x5_Net): use only 5x5 convolutional kernels (hint: in VGG-16, all convolutional kernels were 3x3)
  • Check the number of parameters vs inference time (by generating random noise image and feed-forward through the networks)

  • Explain the results: why one was faster than the another, what was the key point?

  • Add "Batch Normalization" and/or "Dropout" layers to the networks (AlexNet, VGG-16, Your custom CNN_5x5_Net)

  • Check how does inference time is changing after adding those layers Note: Framework: we will be using Keras in this assignment.

In [ ]:
from datetime import datetime
import keras
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, Flatten, Conv2D, MaxPooling2D
import numpy as np


def alexnet(input_data_shape=(224, 224, 3, ), number_of_classes=10):
    model = Sequential()

    # 1st Convolutional Layer
    model.add(Conv2D(filters=96, input_shape=input_data_shape, kernel_size=(11, 11), strides=(4, 4), padding='valid', activation='relu'))
    # Max Pooling
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='valid'))

    # 2nd Convolutional Layer
    model.add(Conv2D(filters=256, kernel_size=(11, 11), strides=(1, 1), padding='valid', activation='relu'))
    # Max Pooling
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='valid'))

    # 3rd Convolutional Layer
    model.add(Conv2D(filters=384, kernel_size=(3, 3), strides=(1, 1), padding='valid', activation='relu'))

    # 4th Convolutional Layer
    model.add(Conv2D(filters=384, kernel_size=(3, 3), strides=(1, 1), padding='valid', activation='relu'))

    # 5th Convolutional Layer
    model.add(Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding='valid', activation='relu'))
    # Max Pooling
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='valid'))

    # Flatten the feature maps to pass them to Fully Connected Layers
    model.add(Flatten())

    # Fully Connected Layers
    model.add(Dense(4096, activation='relu'))
    model.add(Dense(4096, activation='relu'))
    model.add(Dense(number_of_classes, activation='softmax'))

    model.summary()
    return model
In [ ]:
def vgg_16(input_data_shape=(224, 224, 3,), number_of_classes=10):
    model = Sequential()
    # Block 1
    model.add(Conv2D(filters=64, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(Conv2D(filters=64, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

    # Block 2
    model.add(Conv2D(filters=128, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(Conv2D(filters=128, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

    # Block 3
    model.add(Conv2D(filters=256, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(Conv2D(filters=256, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(Conv2D(filters=256, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

    # Block 4
    model.add(Conv2D(filters=512, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(Conv2D(filters=512, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(Conv2D(filters=512, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

    # Block 5
    model.add(Conv2D(filters=512, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(Conv2D(filters=512, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(Conv2D(filters=512, input_shape=input_data_shape, kernel_size=(3, 3), padding='same', activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

    # Flatten the feature maps to pass them to Fully Connected Layers
    model.add(Flatten())

    # fully connected layers
    model.add(Dense(4096, activation='relu'))
    model.add(Dense(4096, activation='relu'))
    model.add(Dense(number_of_classes, activation='softmax'))

    # Create model.
    model.summary()

    return model

Set the inference hyper-parameters:

In [ ]:
batch_size = 128
num_classes = 10
num_of_training_iteration = 100

Set the input image shape/size

In [ ]:
input_data_shape = (224, 224, 3)

Build AlexNet & VGG-16 networks (default input image shape is 224x224x3)

In [ ]:
alexnet_model = alexnet(input_data_shape=input_data_shape)
vgg16_model = vgg_16(input_data_shape=input_data_shape)

Train the networks on MNIST dataset:

In [ ]:
alexnet_model.compile(loss=keras.losses.categorical_crossentropy, optimizer='adam', metrics=["accuracy"])
vgg16_model.compile(loss=keras.losses.categorical_crossentropy, optimizer='adam', metrics=["accuracy"])

alexnet_inference_time = []
vgg16_inference_time = []

# dummy tensor to check the inference time of each network
x_test = np.random.rand(batch_size, input_data_shape[0], input_data_shape[1], input_data_shape[2])

for _ in range(num_of_training_iteration):
    alexnet_inference_start = datetime.now()
    alexnet_inference = alexnet_model.predict_classes(x_test)
    alexnet_inference_finish = datetime.now()
    alexnet_inference_time.append(alexnet_inference_finish - alexnet_inference_start)

for _ in range(num_of_training_iteration):
    vgg16_inference_start = datetime.now()
    vgg_inference = alexnet_model.predict_classes(x_test)
    vgg16_inference_finish = datetime.now()
    vgg16_inference_time.append(vgg16_inference_finish - vgg16_inference_start)


print("Average Inference time for AlexNet: {}".format(np.mean(alexnet_inference_time)))
print("Average Inference time for VGG-16: {}".format(np.mean(vgg16_inference_time)))
In [ ]:
jovian.commit()
[jovian] Saving notebook..
In [ ]: