<jupyter_start><jupyter_text>Gesture RecognitionIn this group project, you are going to build a 3D Conv model that will be able to predict the 5 gestures correctly. Please import the following libraries to get started.By __<NAME>__ & __<NAME>__  Import the Libraries<jupyter_code>import warnings
warnings.filterwarnings("ignore")

import numpy as np
import os
import datetime
import os

# Image preprocessing Libraries
from skimage import io
from skimage.transform import resize,rescale
from skimage import exposure
from skimage.filters import gaussian


# Keras DL Modules
from keras.models import Sequential, Model
from keras.layers import Dense, GRU, LSTM, Flatten, TimeDistributed, Flatten, BatchNormalization, Activation,Dropout, GlobalAveragePooling2D
from keras.layers.convolutional import Conv3D, MaxPooling3D, MaxPooling2D
from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping
from keras import optimizers,regularizers
from keras.regularizers import l1,l2,l1_l2

# Transfer Learning archs
from keras.applications import ResNet50
from keras.applications import MobileNetV2
from keras.applications import MobileNet

import cv2<jupyter_output>Using TensorFlow backend.<jupyter_text>We set the random seed so that the results don't vary drastically.<jupyter_code># set rand_seed as global variable to use it across the assignment
rand_seed = 30

np.random.seed(rand_seed)
import random as rn
rn.seed(rand_seed)
from keras import backend as K
import tensorflow as tf
#tf.set_random_seed(rand_seed)

import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>Define Local functions<jupyter_code>def metric_comp(hist):

    fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(15,4))
    ax[0].plot(hist.history['categorical_accuracy'])   
    ax[0].plot(hist.history['val_categorical_accuracy'])
    ax[0].legend(['Training Accuracy','Validation Accuracy'])
    ax[0].title.set_text('Model_Accuracy')
    ax[0].set_ylabel('Accuracy')
    ax[0].set_xlabel('Epoch')
    ax[0].grid(True)
    
    ax[1].plot(hist.history['loss'])   
    ax[1].plot(hist.history['val_loss'])
    ax[1].legend(['Training Loss','Validation Loss'])
    ax[1].title.set_text('Model_Loss')
    ax[1].set_ylabel('Loss')
    ax[1].set_xlabel('Epoch')
    ax[1].grid(True)

    plt.show()
def brightness(img, low, high):
    value = np.random.uniform(low, high)
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    hsv = np.array(hsv, dtype = np.float64)
    hsv[:,:,1] = hsv[:,:,1]*value
    hsv[:,:,1][hsv[:,:,1]>255]  = 255
    hsv[:,:,2] = hsv[:,:,2]*value 
    hsv[:,:,2][hsv[:,:,2]>255]  = 255
    hsv = np.array(hsv, dtype = np.uint8)
    img = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    return img<jupyter_output><empty_output><jupyter_text>GeneratorThis is one of the most important part of the code. The overall structure of the generator has been given. In the generator, you are going to preprocess the images as you have images of 2 different dimensions as well as create a batch of video frames. You have to experiment with `img_idx`, `y`,`z` and normalization such that you get high accuracy.<jupyter_code>def generator(source_path, folder_list,dims,img_aug=False):
    
    batch_size, num_frms,num_pxs,num_chanls = dims
    print( '\nSource path = ', source_path, '\nbatch size = ', batch_size, '\nNo of Frames = ',num_frms , '\nHeight&Width of Image = ', num_pxs, '\nNo of Channels = ', num_chanls)
    
    # select the number of images randomly without loosing the sequence
    img_idx = np.arange(0,30,(30/num_frms)).astype(int)

    while True:
        t = np.random.permutation(folder_list)
        num_batches = len(folder_list) // batch_size
        
        scale_factor = 1
        r_num_pxs = num_pxs
        
        
        for batch in range(num_batches): # we iterate over the number of batches
            
            batch_data = np.zeros((batch_size,len(img_idx),num_pxs,num_pxs,num_chanls)) 
            batch_labels = np.zeros((batch_size,5)) # batch_labels is the one hot representation of the output
            if (img_aug):
                batch_data_aug = np.zeros((batch_size,len(img_idx),num_pxs,num_pxs,num_chanls))
                batch_labels_aug = np.zeros((batch_size,5))          
            
            for folder in range(batch_size): # iterate over the batch_size
                
                imgs = os.listdir(source_path+'/'+ t[folder + (batch*batch_size)].split(';')[0]) # read all the images in the folder
                
                for idx,item in enumerate(img_idx): #  Iterate iver the frames/images of a folder to read them in
                    
                    image = io.imread(source_path+'/'+ t[folder + (batch*batch_size)].strip().split(';')[0]+'/'+imgs[item]).astype(np.float32)
                    #crop the images and resize them. Note that the images are of 2 different shape 
                    #and the conv3D will throw error if the inputs in a batch have different shapes
                    img_resize = resize(image,(r_num_pxs,r_num_pxs,3))
                    img_f = rescale(img_resize, (scale_factor,scale_factor,1))
                    
                    batch_data[folder,idx,:,:,0] = (img_f[:,:,0]) / 255
                    batch_data[folder,idx,:,:,1] = (img_f[:,:,1])  / 255
                    batch_data[folder,idx,:,:,2] = (img_f[:,:,2])  / 255
                    
                    #batch_data[folder,idx,:,:,0] = (img_f[:,:,0] - np.percentile(img_f[:,:,0],5)) / (np.percentile(img_f[:,:,0],95) - np.percentile(img_f[:,:,0],5))
                    #batch_data[folder,idx,:,:,1] = (img_f[:,:,1] - np.percentile(img_f[:,:,1],5)) / (np.percentile(img_f[:,:,1],95) - np.percentile(img_f[:,:,1],5))
                    #batch_data[folder,idx,:,:,2] = (img_f[:,:,2] - np.percentile(img_f[:,:,2],5)) / (np.percentile(img_f[:,:,2],95) - np.percentile(img_f[:,:,2],5))
                    
                
                    if (img_aug):
                        #img_a = brightness(image,0.1,2)
                        image_bright = exposure.adjust_gamma(image, gamma=0.25,gain=1)
                        image_dark = exposure.adjust_gamma(image_bright, gamma=2.5,gain=1)
                        img_a = gaussian(image_dark, sigma=5, multichannel=True)
                        
                        img_a_resize = resize(img_a,(r_num_pxs,r_num_pxs,3))
                        img_a_f = rescale(img_a_resize, (scale_factor,scale_factor,1))
                        
                        batch_data_aug[folder,idx,:,:,0] = (img_f[:,:,0]) / 255
                        batch_data_aug[folder,idx,:,:,0] = (img_f[:,:,1]) / 255
                        batch_data_aug[folder,idx,:,:,0] = (img_f[:,:,2]) / 255

                batch_labels[folder, int(t[folder + (batch*batch_size)].strip().split(';')[2])] = 1
            
            if (img_aug):
                batch_data=np.concatenate([batch_data,batch_data_aug])
                batch_labels=np.concatenate([batch_labels,batch_labels])                
            
            yield batch_data, batch_labels #you yield the batch_data and the batch_labels, remember what does yield do

        
        # write the code for the remaining data points which are left after full batches
        remaining_batch = len(folder_list) % batch_size
        
        batch = num_batches
        batch_data = np.zeros((remaining_batch,len(img_idx),num_pxs,num_pxs,num_chanls))
        batch_labels = np.zeros((remaining_batch,5))
        
        if (img_aug): 
            batch_data_aug = np.zeros((remaining_batch,len(img_idx),num_pxs,num_pxs,num_chanls))
            batch_labels_aug = np.zeros((remaining_batch,5))
        
        for folder in range(remaining_batch):
            imgs = os.listdir(source_path+'/'+ t[folder + (batch*batch_size)].split(';')[0])
            
            for idx,item in enumerate(img_idx):
                image = io.imread(source_path+'/'+ t[folder + (batch*batch_size)].strip().split(';')[0]+'/'+imgs[item]).astype(np.float32)
                
                img_resize = resize(image,(r_num_pxs,r_num_pxs,3))
                img_f = rescale(img_resize, (scale_factor,scale_factor,1))
                
                batch_data[folder,idx,:,:,0] = (img_f[:,:,0])/255
                batch_data[folder,idx,:,:,1] = (img_f[:,:,1])/255
                batch_data[folder,idx,:,:,2] = (img_f[:,:,2])/255
                
                if (img_aug):
                    #img_a = brightness(image,0.1,2)
                    image_bright = exposure.adjust_gamma(image, gamma=0.25,gain=1)
                    image_dark = exposure.adjust_gamma(image_bright, gamma=2.5,gain=1)
                    img_a = gaussian(image_dark, sigma=5, multichannel=True)
                        
                    img_a_resize = resize(img_a,(r_num_pxs,r_num_pxs,3))
                    img_a_f = rescale(img_a_resize, (scale_factor,scale_factor,1))
                        
                    batch_data_aug[folder,idx,:,:,0] = (img_a_f[:,:,0]) / 255
                    batch_data_aug[folder,idx,:,:,0] = (img_a_f[:,:,1]) / 255
                    batch_data_aug[folder,idx,:,:,0] = (img_a_f[:,:,2]) / 255
            
            batch_labels[folder, int(t[folder + (batch*batch_size)].strip().split(';')[2])] = 1
        
        if (img_aug):
            batch_data=np.concatenate([batch_data,batch_data_aug])
            batch_labels=np.concatenate([batch_labels,batch_labels])     
        
        yield batch_data, batch_labels
            
        
        
"""           
        
        r_batch_size = len(folder_list) % batch_size 
        if (r_batch_size != 0):
            
            batch = num_batches
            batch_data = np.zeros((r_batch_size,len(img_idx),num_pxs,num_pxs,num_chanls)) 
            batch_labels = np.zeros((r_batch_size,5)) # batch_labels is the one hot representation of the output
            if (img_aug): 
                batch_data_aug = np.zeros((r_batch_size,len(img_idx),num_pxs,num_pxs,num_chanls))
                batch_labels_aug = np.zeros((r_batch_size,5))   
        
            
            for folder in range(r_batch_size): # iterate over the batch_size 
                imgs = os.listdir(source_path+'/'+ t[folder + (batch * batch_size)].split(';')[0]) # read all the images in the folder
            
                for idx,item in enumerate(img_idx): #  Iterate iver the frames/images of a folder to read them in 
                    image = io.imread(source_path+'/'+ t[folder + (batch * batch_size)].strip().split(';')[0]+'/'+imgs[item]).astype(np.float32)
                    #crop the images and resize them. Note that the images are of 2 different shape 
                    #and the conv3D will throw error if the inputs in a batch have different shapes
                    img_resize = resize(image,(r_num_pxs,r_num_pxs,3))
                    img_f = rescale(img_resize, (scale_factor,scale_factor,1))
                
                    batch_data[folder,idx,:,:,0] = (img_f[:,:,0])  / 255
                    batch_data[folder,idx,:,:,1] = (img_f[:,:,1]) / 255
                    batch_data[folder,idx,:,:,2] = (img_f[:,:,2])  / 255
                
                    #batch_data[folder,idx,:,:,0] = (img_f[:,:,0] - np.percentile(img_f[:,:,0],5)) / (np.percentile(img_f[:,:,0],95) - np.percentile(img_f[:,:,0],5))
                    #batch_data[folder,idx,:,:,1] = (img_f[:,:,1] - np.percentile(img_f[:,:,1],5)) / (np.percentile(img_f[:,:,1],95) - np.percentile(img_f[:,:,1],5))
                    #batch_data[folder,idx,:,:,2] = (img_f[:,:,2] - np.percentile(img_f[:,:,2],5)) / (np.percentile(img_f[:,:,2],95) - np.percentile(img_f[:,:,2],5))
                
                    if (img_aug):
                        #img_a = brightness(image,0.1,2)
                        image_bright = exposure.adjust_gamma(image, gamma=0.25,gain=1)
                        image_dark = exposure.adjust_gamma(image_bright, gamma=2.5,gain=1)
                        img_a = gaussian(image_dark, sigma=5, multichannel=True)
                        
                        img_a_resize = resize(img_a,(r_num_pxs,r_num_pxs,3))
                        img_a_f = rescale(img_a_resize, (scale_factor,scale_factor,1))
                        
                        batch_data_aug[folder,idx,:,:,0] = (img_f[:,:,0]) / 255
                        batch_data_aug[folder,idx,:,:,0] = (img_f[:,:,1]) / 255
                        batch_data_aug[folder,idx,:,:,0] = (img_f[:,:,2]) / 255
                
                batch_labels[folder, int(t[folder + (batch * batch_size)].strip().split(';')[2])] = 1
            
            if (img_aug):
                batch_data=np.concatenate([batch_data,batch_data_aug])
                batch_labels=np.concatenate([batch_labels,batch_labels])    
            
            yield batch_data, batch_labels #you yield the batch_data and the batch_labels, remember what does yield do
        
"""<jupyter_output><empty_output><jupyter_text>Note here that a video is represented above in the generator as (number of images, height, width, number of channels). Take this into consideration while creating the model architecture. In this block, you read the folder names for training and validation. You also set the `batch_size` here. Note that you set the batch size in such a way that you are able to use the GPU in full capacity. You keep increasing the batch size until the machine throws an error.  Source the data<jupyter_code># Randomly select the train data and validation data

train_doc = np.random.permutation(open('/mnt/disks/user/project/PROJECT/Project_data/train.csv').readlines())
val_doc = np.random.permutation(open('/mnt/disks/user/project/PROJECT/Project_data//val.csv').readlines())
curr_dt_time = datetime.datetime.now()
train_path = '/mnt/disks/user/project/PROJECT/Project_data/train'
val_path = '/mnt/disks/user/project/PROJECT/Project_data/val'

num_train_sequences = len(train_doc)
print('# training sequences =', num_train_sequences)

num_val_sequences = len(val_doc)
print('# validation sequences =', num_val_sequences)<jupyter_output># training sequences = 663
# validation sequences = 100<jupyter_text>Different DL Models for Gesture Recognition  CNN(Conv2d)+RNN - Transfer Learning with GRU* We have used existing __MobileNet__ for transfer learning    - No of trainable layers - __ALL__* It is followed by TimeDistributed, GRU and Dense Layers<jupyter_code># Input dimensions
num_frms = 10
num_pxs = 224
num_chanls = 3

batch_size = 64

# Output dimensions
num_classes = 5

dims = [batch_size,num_frms,num_pxs,num_chanls]

num_epochs = 25
print ('No of epochs =', num_epochs)
input_shape_tl = (num_pxs,num_pxs,num_chanls)

# Initialize the MobileNet model
mobilenet = MobileNet(weights='imagenet', include_top=False, input_shape=input_shape_tl)

trainable = 8

for layer in mobilenet.layers[:-trainable]:
    layer.trainable = False
for layer in mobilenet.layers[-trainable:]:
    layer.trainable = True    

# Initialize the model
model_1 = Sequential()

input_shape = (num_frms,num_pxs,num_pxs,num_chanls)

# Connect the ouput of mobilenet to TimeDistributed layer
model_1.add(TimeDistributed(mobilenet, input_shape=input_shape))
model_1.add(TimeDistributed(Dropout(.2)))
model_1.add(TimeDistributed(BatchNormalization()))
model_1.add(TimeDistributed(GlobalAveragePooling2D()))

# add GRU layer 
model_1.add(GRU(512, activation='relu', return_sequences=False))

# add Dense layer 1
model_1.add(Dense(128, activation='relu'))
model_1.add(BatchNormalization())


# add Dense layer 2
model_1.add(Dense(64, activation='relu'))
model_1.add(Dropout(.4))

# Ouput layer
model_1.add(Dense(5, activation='softmax'))

# Compile the model
lrate = 0.001
decay = lrate/num_epochs
#optimiser = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False) #write your optimizer
optimiser = optimizers.Adam(lr=1e-3, epsilon = 1e-8, beta_1 = .9, beta_2 = .999)
model_1.compile(optimizer=optimiser, loss='categorical_crossentropy', metrics=['categorical_accuracy'])
print (model_1.summary())
train_generator = generator(train_path, train_doc, dims,img_aug=False)
val_generator = generator(val_path, val_doc, dims,img_aug=False)
model_name = 'model_1' + '_' + str(curr_dt_time).replace(' ','').replace(':','_') + '/'
    
if not os.path.exists(model_name):
    os.mkdir(model_name)
        
filepath = model_name + 'model-{epoch:05d}-{loss:.5f}-{categorical_accuracy:.5f}-{val_loss:.5f}-{val_categorical_accuracy:.5f}.h5'

cp = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=False, save_weights_only=False, mode='auto', period=1)

lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1 , patience=3, min_delta=0.000004, mode='auto', verbose=1,min_lr=1e-9)

es = EarlyStopping(monitor='val_loss', patience=8, verbose=1)

callbacks_list = [cp, lr]
if (num_train_sequences%batch_size) == 0:
    steps_per_epoch = int(num_train_sequences/batch_size)
else:
    steps_per_epoch = (num_train_sequences//batch_size) + 1

if (num_val_sequences%batch_size) == 0:
    validation_steps = int(num_val_sequences/batch_size)
else:
    validation_steps = (num_val_sequences//batch_size) + 1
model_1_history = model_1.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=num_epochs, verbose=1, 
                    validation_data=val_generator, callbacks=callbacks_list,
                    validation_steps=validation_steps, class_weight=None, workers=1, initial_epoch=0)
metric_comp(model_1_history)<jupyter_output><empty_output><jupyter_text>CNN(Conv2d)+RNN - Transfer Learning with GRU* We have used existing __MobileNet__ for transfer learning    - No of trainable layers - __8__* It is followed by TimeDistributed, GRU and Dense Layers<jupyter_code># Input dimensions
num_frms = 10
num_pxs = 224
num_chanls = 3

batch_size = 16

# Output dimensions
num_classes = 5

dims = [batch_size,num_frms,num_pxs,num_chanls]

num_epochs = 25
print ('No of epochs =', num_epochs)
input_shape_tl = (num_pxs,num_pxs,num_chanls)

# Initialize the MobileNet model
mobilenet = MobileNet(weights='imagenet', include_top=False, input_shape=input_shape_tl)

trainable = 8

for layer in mobilenet.layers[:-trainable]:
    layer.trainable = False
for layer in mobilenet.layers[-trainable:]:
    layer.trainable = True    

# Initialize the model
model_2 = Sequential()

input_shape = (num_frms,num_pxs,num_pxs,num_chanls)

# Connect the ouput of mobilenet to TimeDistributed layer
model_2.add(TimeDistributed(mobilenet, input_shape=input_shape))
model_2.add(TimeDistributed(Dropout(.2)))
model_2.add(TimeDistributed(BatchNormalization()))
model_2.add(TimeDistributed(GlobalAveragePooling2D()))

# add GRU layer 
model_2.add(GRU(512, activation='relu', return_sequences=False))

# add Dense layer 1
model_2.add(Dense(128, activation='relu'))
model_2.add(BatchNormalization())


# add Dense layer 2
model_2.add(Dense(64, activation='relu'))
model_2.add(Dropout(.4))

# Ouput layer
model_2.add(Dense(5, activation='softmax'))

# Compile the model
lrate = 0.001
decay = lrate/num_epochs
#optimiser = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False) #write your optimizer
optimiser = optimizers.Adam(lr=1e-3, epsilon = 1e-8, beta_1 = .9, beta_2 = .999)
model_2.compile(optimizer=optimiser, loss='categorical_crossentropy', metrics=['categorical_accuracy'])
print (model_2.summary())
train_generator = generator(train_path, train_doc, dims,img_aug=True)
val_generator = generator(val_path, val_doc, dims,img_aug=False)
model_name = 'model_2' + '_' + str(curr_dt_time).replace(' ','').replace(':','_') + '/'
    
if not os.path.exists(model_name):
    os.mkdir(model_name)
        
filepath = model_name + 'model-{epoch:05d}-{loss:.5f}-{categorical_accuracy:.5f}-{val_loss:.5f}-{val_categorical_accuracy:.5f}.h5'

cp = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=False, save_weights_only=False, mode='auto', period=1)

lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1 , patience=3, min_delta=0.000004, mode='auto', verbose=1,min_lr=1e-9)

es = EarlyStopping( monitor='val_loss', patience=5, verbose=1)

callbacks_list = [cp, lr]
if (num_train_sequences%batch_size) == 0:
    steps_per_epoch = int(num_train_sequences/batch_size)
else:
    steps_per_epoch = (num_train_sequences//batch_size) + 1

if (num_val_sequences%batch_size) == 0:
    validation_steps = int(num_val_sequences/batch_size)
else:
    validation_steps = (num_val_sequences//batch_size) + 1
model_2_history = model_2.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=num_epochs, verbose=1, 
                    validation_data=val_generator, callbacks=callbacks_list,
                    validation_steps=validation_steps, class_weight=None, workers=1, initial_epoch=0)
metric_comp(model_2_history)<jupyter_output><empty_output><jupyter_text>CNN(Conv2d)+RNN - Transfer Learning with LSTM* We have used existing __MobileNet__ for transfer learning    - No of trainable layers - __ALL__* It is followed by TimeDistributed, GRU and Dense Layers<jupyter_code># Input dimensions
num_frms = 10
num_pxs = 224
num_chanls = 3

batch_size = 64

# Output dimensions
num_classes = 5

dims = [batch_size,num_frms,num_pxs,num_chanls]

num_epochs = 25
print ('No of epochs =', num_epochs)
input_shape_tl = (num_pxs,num_pxs,num_chanls)

# Initialize the MobileNet model
mobilenet = MobileNet(weights='imagenet', include_top=False, input_shape=input_shape_tl)

trainable = 8

for layer in mobilenet.layers[:-trainable]:
    layer.trainable = False
for layer in mobilenet.layers[-trainable:]:
    layer.trainable = True    

# Initialize the model
model_3 = Sequential()

input_shape = (num_frms,num_pxs,num_pxs,num_chanls)

# Connect the ouput of mobilenet to TimeDistributed layer
model_3.add(TimeDistributed(mobilenet, input_shape=input_shape))
model_3.add(TimeDistributed(Dropout(.2)))
model_3.add(TimeDistributed(BatchNormalization()))
model_3.add(TimeDistributed(GlobalAveragePooling2D()))

# add GRU layer 
model_3.add(LSTM(512, activation='relu', return_sequences=False))

# add Dense layer 1
model_3.add(Dense(128, activation='relu'))
model_3.add(BatchNormalization())


# add Dense layer 2
model_3.add(Dense(64, activation='relu'))
model_3.add(Dropout(.4))

# Ouput layer
model_3.add(Dense(5, activation='softmax'))

# Compile the model
lrate = 0.001
decay = lrate/num_epochs
#optimiser = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False) #write your optimizer
optimiser = optimizers.Adam(lr=1e-3, epsilon = 1e-8, beta_1 = .9, beta_2 = .999)
model_3.compile(optimizer=optimiser, loss='categorical_crossentropy', metrics=['categorical_accuracy'])
print (model_3.summary())
train_generator = generator(train_path, train_doc, dims,img_aug=False)
val_generator = generator(val_path, val_doc, dims,img_aug=False)
model_name = 'model_3' + '_' + str(curr_dt_time).replace(' ','').replace(':','_') + '/'
    
if not os.path.exists(model_name):
    os.mkdir(model_name)
        
filepath = model_name + 'model-{epoch:05d}-{loss:.5f}-{categorical_accuracy:.5f}-{val_loss:.5f}-{val_categorical_accuracy:.5f}.h5'

cp = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=False, save_weights_only=False, mode='auto', period=1)

lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1 , patience=3, min_delta=0.000004, mode='auto', verbose=1,min_lr=1e-9)

es = EarlyStopping( monitor='val_loss', patience=8, verbose=1)

callbacks_list = [cp, lr]
if (num_train_sequences%batch_size) == 0:
    steps_per_epoch = int(num_train_sequences/batch_size)
else:
    steps_per_epoch = (num_train_sequences//batch_size) + 1

if (num_val_sequences%batch_size) == 0:
    validation_steps = int(num_val_sequences/batch_size)
else:
    validation_steps = (num_val_sequences//batch_size) + 1
model_3_history = model_3.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=num_epochs, verbose=1, 
                    validation_data=val_generator, callbacks=callbacks_list,
                    validation_steps=validation_steps, class_weight=None, workers=1, initial_epoch=0)
metric_comp(model_3_history)<jupyter_output><empty_output><jupyter_text>CNN(Conv3d) Base Model<jupyter_code># Input dimensions
num_frms = 15
num_pxs = 100
num_chanls = 3

batch_size = 64

# Output dimensions
num_classes = 5

dims = [batch_size,num_frms,num_pxs,num_chanls]

num_epochs = 25
print ('No of epochs =', num_epochs)
# model
model_4 = Sequential()

input_shape = (num_frms,num_pxs,num_pxs,num_chanls) # input shape = (num_frms, img_rows, img_cols, num_chnls)

# first conv3d layer
model_4.add(Conv3D(16, kernel_size=(2,2,2),padding='same',
                 activation='relu',input_shape=input_shape))
model_4.add(BatchNormalization())
model_4.add(MaxPooling3D(pool_size=(2,2,2)))

# second conv3d layer
model_4.add(Conv3D(32, kernel_size=(2,2,2),padding='same',
                 activation='relu'))
model_4.add(BatchNormalization())
model_4.add(MaxPooling3D(pool_size=(2,2,2)))

# third conv3d layer
model_4.add(Conv3D(64, kernel_size=(2,2,2),padding='same',
                 activation='relu'))
model_4.add(BatchNormalization())
model_4.add(MaxPooling3D(pool_size=(2,2,2)))


# Flatten the layers
model_4.add(Flatten())

# Dense layer 
model_4.add(Dense(128,activation='relu'))
model_4.add(BatchNormalization())
model_4.add(Dropout(0.4))

# Dense layer (good64)
model_4.add(Dense(128,activation='relu'))
model_4.add(BatchNormalization())
model_4.add(Dropout(0.45))

# softmax layer
model_4.add(Dense(num_classes, activation='softmax'))

# Compile the model
optimiser = optimizers.Adam(lr=0.0001)
model_4.compile(optimizer=optimiser, loss='categorical_crossentropy', metrics=['categorical_accuracy'])

print(model_4.summary())

train_generator = generator(train_path, train_doc, dims,img_aug=False)
val_generator = generator(val_path, val_doc, dims,img_aug=False)
model_name = 'model_4' + '_' + str(curr_dt_time).replace(' ','').replace(':','_') + '/'
    
if not os.path.exists(model_name):
    os.mkdir(model_name)
        
filepath = model_name + 'model-{epoch:05d}-{loss:.5f}-{categorical_accuracy:.5f}-{val_loss:.5f}-{val_categorical_accuracy:.5f}.h5'

cp = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=False, save_weights_only=False, mode='auto', period=1)

lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1 , patience=3, min_delta=0.000004, mode='auto', verbose=1,min_lr=1e-9)

es = EarlyStopping( monitor='val_loss', patience=6, verbose=1)

callbacks_list = [cp, lr]
if (num_train_sequences%batch_size) == 0:
    steps_per_epoch = int(num_train_sequences/batch_size)
else:
    steps_per_epoch = (num_train_sequences//batch_size) + 1

if (num_val_sequences%batch_size) == 0:
    validation_steps = int(num_val_sequences/batch_size)
else:
    validation_steps = (num_val_sequences//batch_size) + 1
model_4_history = model_4.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=num_epochs, verbose=1, 
                    validation_data=val_generator, callbacks=callbacks_list,
                    validation_steps=validation_steps, class_weight=None, workers=1, initial_epoch=0)
metric_comp(model_4_history)<jupyter_output><empty_output><jupyter_text>CNN(Conv3d) with Image Augumentation<jupyter_code># Input dimensions
num_frms = 15
num_pxs = 80
num_chanls = 3

batch_size = 32  # Since we have augumentation, we have reduced the batch size to fit the data into memory

# Output dimensions
num_classes = 5

dims = [batch_size,num_frms,num_pxs,num_chanls]

num_epochs = 25
print ('No of epochs =', num_epochs)
# model
model_5 = Sequential()

input_shape = (num_frms,num_pxs,num_pxs,num_chanls) # input shape = (num_frms, img_rows, img_cols, num_chnls)

# first conv3d layer
model_5.add(Conv3D(16, kernel_size=(2,2,2),padding='same',
                 activation='relu',input_shape=input_shape))
model_5.add(BatchNormalization())
model_5.add(MaxPooling3D(pool_size=(2,2,2)))

# second conv3d layer
model_5.add(Conv3D(32, kernel_size=(2,2,2),padding='same',
                 activation='relu'))
model_5.add(BatchNormalization())
model_5.add(MaxPooling3D(pool_size=(2,2,2)))

# third conv3d layer
model_5.add(Conv3D(128, kernel_size=(2,2,2),padding='same',
                 activation='relu'))
model_5.add(BatchNormalization())
model_5.add(MaxPooling3D(pool_size=(2,2,2)))


# Flatten the layers
model_5.add(Flatten())

# Dense layer 
model_5.add(Dense(128,activation='relu'))
model_5.add(BatchNormalization())
model_5.add(Dropout(0.4))

# Dense layer (good64)
model_5.add(Dense(256,activation='relu'))
model_5.add(BatchNormalization())
model_5.add(Dropout(0.45))

# softmax layer
model_5.add(Dense(num_classes, activation='softmax'))

# Compile the model
optimiser = optimizers.Adam(lr=0.0001)
model_5.compile(optimizer=optimiser, loss='categorical_crossentropy', metrics=['categorical_accuracy'])

print(model_5.summary())

train_generator = generator(train_path, train_doc, dims,img_aug=True)
val_generator = generator(val_path, val_doc, dims,img_aug=False)
model_name = 'model_5' + '_' + str(curr_dt_time).replace(' ','').replace(':','_') + '/'
    
if not os.path.exists(model_name):
    os.mkdir(model_name)
        
filepath = model_name + 'model-{epoch:05d}-{loss:.5f}-{categorical_accuracy:.5f}-{val_loss:.5f}-{val_categorical_accuracy:.5f}.h5'

cp = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=False, save_weights_only=False, mode='auto', period=1)

lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1 , patience=2, min_delta=0.000004, mode='auto', verbose=1,min_lr=1e-9)

es = EarlyStopping( monitor='val_loss', patience=4, verbose=1)

callbacks_list = [cp, lr]
if (num_train_sequences%batch_size) == 0:
    steps_per_epoch = int(num_train_sequences/batch_size)
else:
    steps_per_epoch = (num_train_sequences//batch_size) + 1

if (num_val_sequences%batch_size) == 0:
    validation_steps = int(num_val_sequences/batch_size)
else:
    validation_steps = (num_val_sequences//batch_size) + 1
model_5_history = model_5.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=num_epochs, verbose=1, 
                    validation_data=val_generator, callbacks=callbacks_list,
                    validation_steps=validation_steps, class_weight=None, workers=1, initial_epoch=0)
metric_comp(model_5_history)<jupyter_output><empty_output><jupyter_text>CNN(Conv3d) reduce the no of frames and pixes with higher batch size<jupyter_code># Input dimensions
num_frms = 10
num_pxs = 80
num_chanls = 3

batch_size = 64

# Output dimensions
num_classes = 5

dims = [batch_size,num_frms,num_pxs,num_chanls]

num_epochs = 25
print ('No of epochs =', num_epochs)
# model
model_6 = Sequential()

input_shape = (num_frms,num_pxs,num_pxs,num_chanls) # input shape = (num_frms, img_rows, img_cols, num_chnls)

# first conv3d layer
model_6.add(Conv3D(16, kernel_size=(2,2,2),padding='same',
                 activation='relu',input_shape=input_shape))
model_6.add(BatchNormalization())
model_6.add(MaxPooling3D(pool_size=(2,2,2)))

# second conv3d layer
model_6.add(Conv3D(32, kernel_size=(2,2,2),padding='same',
                 activation='relu'))
model_6.add(BatchNormalization())
model_6.add(MaxPooling3D(pool_size=(2,2,2)))

# third conv3d layer
model_6.add(Conv3D(64, kernel_size=(2,2,2),padding='same',
                 activation='relu'))
model_6.add(BatchNormalization())
model_6.add(MaxPooling3D(pool_size=(2,2,2)))


# Flatten the layers
model_6.add(Flatten())

# Dense layer 
model_6.add(Dense(128,activation='relu'))
model_6.add(BatchNormalization())
model_6.add(Dropout(0.4))

# Dense layer (good64)
model_6.add(Dense(128,activation='relu'))
model_6.add(BatchNormalization())
model_6.add(Dropout(0.45))

# softmax layer
model_6.add(Dense(num_classes, activation='softmax'))

# Compile the model
optimiser = optimizers.Adam(lr=0.0001)
model_6.compile(optimizer=optimiser, loss='categorical_crossentropy', metrics=['categorical_accuracy'])

print(model_6.summary())

train_generator = generator(train_path, train_doc, dims,img_aug=False)
val_generator = generator(val_path, val_doc, dims,img_aug=False)
model_name = 'model_6' + '_' + str(curr_dt_time).replace(' ','').replace(':','_') + '/'
    
if not os.path.exists(model_name):
    os.mkdir(model_name)
        
filepath = model_name + 'model-{epoch:05d}-{loss:.5f}-{categorical_accuracy:.5f}-{val_loss:.5f}-{val_categorical_accuracy:.5f}.h5'

cp = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=False, save_weights_only=False, mode='auto', period=1)

lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1 , patience=3, min_delta=0.000004, mode='auto', verbose=1,min_lr=1e-9)

es = EarlyStopping( monitor='val_loss', patience=6, verbose=1)

callbacks_list = [cp, lr]
if (num_train_sequences%batch_size) == 0:
    steps_per_epoch = int(num_train_sequences/batch_size)
else:
    steps_per_epoch = (num_train_sequences//batch_size) + 1

if (num_val_sequences%batch_size) == 0:
    validation_steps = int(num_val_sequences/batch_size)
else:
    validation_steps = (num_val_sequences//batch_size) + 1
model_6_history = model_6.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=num_epochs, verbose=1, 
                    validation_data=val_generator, callbacks=callbacks_list,
                    validation_steps=validation_steps, class_weight=None, workers=1, initial_epoch=0)
metric_comp(model_6_history)<jupyter_output><empty_output><jupyter_text>CNN(Conv3d) Increase the no of layers<jupyter_code># Input dimensions
num_frms = 16
num_pxs = 100
num_chanls = 3

batch_size = 64

# Output dimensions
num_classes = 5

dims = [batch_size,num_frms,num_pxs,num_chanls]

num_epochs = 25
print ('No of epochs =', num_epochs)
# model
model_7 = Sequential()

input_shape = (num_frms,num_pxs,num_pxs,num_chanls) # input shape = (num_frms, img_rows, img_cols, num_chnls)

# first conv3d layer
model_7.add(Conv3D(16, kernel_size=(2,2,2),padding='same',
                 activation='relu',input_shape=input_shape))
model_7.add(BatchNormalization())
model_7.add(MaxPooling3D(pool_size=(2,2,2)))

# second conv3d layer
model_7.add(Conv3D(32, kernel_size=(2,2,2),padding='same',
                 activation='relu'))
model_7.add(BatchNormalization())
model_7.add(MaxPooling3D(pool_size=(2,2,2)))

# third conv3d layer
model_7.add(Conv3D(64, kernel_size=(2,2,2),padding='same',
                 activation='relu'))
model_7.add(BatchNormalization())
model_7.add(MaxPooling3D(pool_size=(2,2,2)))

model_7.add(Conv3D(128, kernel_size=(2,2,2),padding='same',
                 activation='relu'))
model_7.add(BatchNormalization())
model_7.add(MaxPooling3D(pool_size=(2,2,2)))


# Flatten the layers
model_7.add(Flatten())

# Dense layer 
model_7.add(Dense(128,activation='relu'))
model_7.add(BatchNormalization())
model_7.add(Dropout(0.4))

# Dense layer (good64)
model_7.add(Dense(128,activation='relu'))
model_7.add(BatchNormalization())
model_7.add(Dropout(0.45))

# softmax layer
model_7.add(Dense(num_classes, activation='softmax'))

# Compile the model
optimiser = optimizers.Adam(lr=0.0001)
model_7.compile(optimizer=optimiser, loss='categorical_crossentropy', metrics=['categorical_accuracy'])

print(model_7.summary())

train_generator = generator(train_path, train_doc, dims,img_aug=False)
val_generator = generator(val_path, val_doc, dims,img_aug=False)
model_name = 'model_7' + '_' + str(curr_dt_time).replace(' ','').replace(':','_') + '/'
    
if not os.path.exists(model_name):
    os.mkdir(model_name)
        
filepath = model_name + 'model-{epoch:05d}-{loss:.5f}-{categorical_accuracy:.5f}-{val_loss:.5f}-{val_categorical_accuracy:.5f}.h5'

cp = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=False, save_weights_only=False, mode='auto', period=1)

lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1 , patience=3, min_delta=0.000004, mode='auto', verbose=1,min_lr=1e-9)

es = EarlyStopping( monitor='val_loss', patience=6, verbose=1)

callbacks_list = [cp, lr]
if (num_train_sequences%batch_size) == 0:
    steps_per_epoch = int(num_train_sequences/batch_size)
else:
    steps_per_epoch = (num_train_sequences//batch_size) + 1

if (num_val_sequences%batch_size) == 0:
    validation_steps = int(num_val_sequences/batch_size)
else:
    validation_steps = (num_val_sequences//batch_size) + 1
model_7_history = model_7.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=num_epochs, verbose=1, 
                    validation_data=val_generator, callbacks=callbacks_list,
                    validation_steps=validation_steps, class_weight=None, workers=1, initial_epoch=0)
metric_comp(model_7_history)<jupyter_output><empty_output><jupyter_text>CNN(Conv3d)<jupyter_code># Input dimensions
num_frms = 8
num_pxs = 80
num_chanls = 3

batch_size = 128

# Output dimensions
num_classes = 5

dims = [batch_size,num_frms,num_pxs,num_chanls]

num_epochs = 25
print ('No of epochs =', num_epochs)
# model
model_8 = Sequential()

input_shape = (num_frms,num_pxs,num_pxs,num_chanls) # input shape = (num_frms, img_rows, img_cols, num_chnls)

# first conv3d layer
model_8.add(Conv3D(16, kernel_size=(2,2,2),padding='same',
                 activation='relu',input_shape=input_shape))
model_8.add(BatchNormalization())
model_8.add(MaxPooling3D(pool_size=(2,2,2)))

# second conv3d layer
model_8.add(Conv3D(32, kernel_size=(2,2,2),padding='same',
                 activation='relu'))
model_8.add(BatchNormalization())
model_8.add(MaxPooling3D(pool_size=(2,2,2)))

# third conv3d layer
model_8.add(Conv3D(64, kernel_size=(2,2,2),padding='same',
                 activation='relu'))
model_8.add(BatchNormalization())
model_8.add(MaxPooling3D(pool_size=(2,2,2)))

# Flatten the layers
model_8.add(Flatten())

# Dense layer 
model_8.add(Dense(128,activation='relu'))
model_8.add(BatchNormalization())
model_8.add(Dropout(0.4))

# Dense layer (good64)
model_8.add(Dense(128,activation='relu'))
model_8.add(BatchNormalization())
model_8.add(Dropout(0.45))

# softmax layer
model_8.add(Dense(num_classes, activation='softmax'))

# Compile the model
optimiser = optimizers.Adam(lr=0.0001)
model_8.compile(optimizer=optimiser, loss='categorical_crossentropy', metrics=['categorical_accuracy'])

print(model_8.summary())

train_generator = generator(train_path, train_doc, dims,img_aug=False)
val_generator = generator(val_path, val_doc, dims,img_aug=False)
model_name = 'model_8' + '_' + str(curr_dt_time).replace(' ','').replace(':','_') + '/'
    
if not os.path.exists(model_name):
    os.mkdir(model_name)
        
filepath = model_name + 'model-{epoch:05d}-{loss:.5f}-{categorical_accuracy:.5f}-{val_loss:.5f}-{val_categorical_accuracy:.5f}.h5'

cp = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=False, save_weights_only=False, mode='auto', period=1)

lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1 , patience=3, min_delta=0.000004, mode='auto', verbose=1,min_lr=1e-9)

es = EarlyStopping( monitor='val_loss', patience=6, verbose=1)

callbacks_list = [cp, lr]
if (num_train_sequences%batch_size) == 0:
    steps_per_epoch = int(num_train_sequences/batch_size)
else:
    steps_per_epoch = (num_train_sequences//batch_size) + 1

if (num_val_sequences%batch_size) == 0:
    validation_steps = int(num_val_sequences/batch_size)
else:
    validation_steps = (num_val_sequences//batch_size) + 1
model_8_history = model_8.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=num_epochs, verbose=1, 
                    validation_data=val_generator, callbacks=callbacks_list,
                    validation_steps=validation_steps, class_weight=None, workers=1, initial_epoch=0)
metric_comp(model_8_history)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1334071966358623, 'fraction_numerical': 0.029486566111852543, 'mean_word_length': 4.32859251308198, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '293887', 'license': 'Apache-2.0', 'n_tokens_mistral': 14760, 'n_tokens_neox': 14125, 'n_words': 2397, 'path': 'Deep_Learning/Gesture_Recognition/Neural_Nets_Project_Starter_Code_Juhi_Kalyan_Augmentation_Final.ipynb', 'repo_name': 'lsunku/DataScience', 'size': '39736'}