{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"### Team: <br>\n1. Dina Zakria \n2. Ahmed Sameh\n3. Abdelrhman Amr\n\n<br> **Naser City Branch - AI-Pro**","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-09T16:17:19.119010Z","iopub.execute_input":"2022-07-09T16:17:19.119997Z","iopub.status.idle":"2022-07-09T16:17:19.125925Z","shell.execute_reply.started":"2022-07-09T16:17:19.119944Z","shell.execute_reply":"2022-07-09T16:17:19.124468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Imports","metadata":{}},{"cell_type":"code","source":"# Imports\nimport cv2\nimport os\nfrom tqdm import tqdm\nfrom glob import glob\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom keras.utils import np_utils\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n\n\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential, Model\nfrom keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization, GlobalAveragePooling2D","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:17:19.808064Z","iopub.execute_input":"2022-07-09T16:17:19.810222Z","iopub.status.idle":"2022-07-09T16:17:26.198267Z","shell.execute_reply.started":"2022-07-09T16:17:19.810174Z","shell.execute_reply":"2022-07-09T16:17:26.197180Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Loading Dataset","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(\"../input/state-farm-distracted-driver-detection/driver_imgs_list.csv\")\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:16:29.850215Z","iopub.execute_input":"2022-07-09T16:16:29.851310Z","iopub.status.idle":"2022-07-09T16:16:29.897718Z","shell.execute_reply.started":"2022-07-09T16:16:29.851269Z","shell.execute_reply":"2022-07-09T16:16:29.896838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Group bt Drivers/ Test Subjects\nby_drivers = df.groupby('subject')\n\nunique_drivers = by_drivers.groups.keys()\n\nprint(\"There are: \", len(unique_drivers), \" unique drivers\")\nprint('These are the numbers of each test subject: \\n',round(by_drivers.count()['classname']))","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:50:41.766026Z","iopub.execute_input":"2022-07-09T15:50:41.766551Z","iopub.status.idle":"2022-07-09T15:50:41.797230Z","shell.execute_reply.started":"2022-07-09T15:50:41.766522Z","shell.execute_reply":"2022-07-09T15:50:41.796417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Setting the number of classes to be classified.\nNUMBER_CLASSES = 10","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:16:49.179664Z","iopub.execute_input":"2022-07-09T16:16:49.180144Z","iopub.status.idle":"2022-07-09T16:16:49.184501Z","shell.execute_reply.started":"2022-07-09T16:16:49.180109Z","shell.execute_reply":"2022-07-09T16:16:49.183258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> ### Helper Functions","metadata":{}},{"cell_type":"code","source":"# Read with opencv\ndef get_cv2_image(path, img_rows, img_cols, color_type=3):\n    \"\"\"\n    Function that return an opencv image from the path and the right number of dimension\n    \"\"\"\n    if color_type == 1: # Loading as Grayscale image\n        img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)\n    elif color_type == 3: # Loading as color image\n        img = cv2.imread(path, cv2.IMREAD_COLOR)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Converts to RGB\n\n    img = cv2.resize(img, (img_rows, img_cols)) # Reduce size\n    return img\n\n# Loading Training dataset\ndef load_train(img_rows, img_cols, color_type=3):\n    \"\"\"\n    Return train images and train labels from the original path\n    \"\"\"\n    train_images = [] \n    train_labels = []\n    # Loop over the training folder \n    for classed in tqdm(range(NUMBER_CLASSES)):\n        print('Loading directory c{}'.format(classed))\n        files = glob(os.path.join('../input/state-farm-distracted-driver-detection/imgs/train/c' + str(classed), '*.jpg'))\n        for file in files:\n            img = get_cv2_image(file, img_rows, img_cols, color_type)\n            train_images.append(img)\n            train_labels.append(classed)\n    return train_images, train_labels \n\ndef read_and_normalize_train_data(img_rows, img_cols, color_type):\n    \"\"\"\n    Load + categorical + split\n    \"\"\"\n    X, labels = load_train(img_rows, img_cols, color_type)\n    y = np_utils.to_categorical(labels, 10) #categorical train label\n    x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # split into train and test\n    x_train = np.array(x_train, dtype=np.uint8).reshape(-1,img_rows,img_cols,color_type)\n    x_test = np.array(x_test, dtype=np.uint8).reshape(-1,img_rows,img_cols,color_type)\n    \n    return x_train, x_test, y_train, y_test\n\n# Loading validation dataset\ndef load_test(size=200000, img_rows=64, img_cols=64, color_type=3):\n    \"\"\"\n    Same as above but for validation dataset\n    \"\"\"\n    path = os.path.join('../input/state-farm-distracted-driver-detection/imgs/test', '*.jpg')\n    files = sorted(glob(path))\n    X_test, X_test_id = [], []\n    total = 0\n    files_size = len(files)\n    for file in tqdm(files):\n        if total >= size or total >= files_size:\n            break\n        file_base = os.path.basename(file)\n        img = get_cv2_image(file, img_rows, img_cols, color_type)\n        X_test.append(img)\n        X_test_id.append(file_base)\n        total += 1\n    return X_test, X_test_id\n\ndef read_and_normalize_sampled_test_data(size, img_rows, img_cols, color_type=3):\n    test_data, test_ids = load_test(size, img_rows, img_cols, color_type)   \n    test_data = np.array(test_data, dtype=np.uint8)\n    test_data = test_data.reshape(-1,img_rows,img_cols,color_type)\n    return test_data, test_ids","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:16:52.717894Z","iopub.execute_input":"2022-07-09T16:16:52.718319Z","iopub.status.idle":"2022-07-09T16:16:52.736455Z","shell.execute_reply.started":"2022-07-09T16:16:52.718285Z","shell.execute_reply":"2022-07-09T16:16:52.735341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# dimension of images\nimg_rows = 128 \nimg_cols = 128\n\ncolor_type = 1 # grey\nnb_test_samples = 200","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:16:56.396428Z","iopub.execute_input":"2022-07-09T16:16:56.396772Z","iopub.status.idle":"2022-07-09T16:16:56.401407Z","shell.execute_reply.started":"2022-07-09T16:16:56.396744Z","shell.execute_reply":"2022-07-09T16:16:56.400288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# loading train images\nx_train, x_test, y_train, y_test = read_and_normalize_train_data(img_rows, img_cols, color_type)\n\n# loading validation images\ntest_files, test_targets = read_and_normalize_sampled_test_data(nb_test_samples, img_rows, img_cols, color_type)","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:57:30.036612Z","iopub.execute_input":"2022-07-09T15:57:30.036971Z","iopub.status.idle":"2022-07-09T16:00:54.542625Z","shell.execute_reply.started":"2022-07-09T15:57:30.036941Z","shell.execute_reply":"2022-07-09T16:00:54.541549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## EDA","metadata":{}},{"cell_type":"code","source":"x_train_size = len(x_train)\nx_test_size = len(x_test)\ntest_files_size = len(np.array(glob(os.path.join('../input/state-farm-distracted-driver-detection/imgs/test', '*.jpg'))))","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:01:25.590828Z","iopub.execute_input":"2022-07-09T16:01:25.591186Z","iopub.status.idle":"2022-07-09T16:01:25.889995Z","shell.execute_reply.started":"2022-07-09T16:01:25.591157Z","shell.execute_reply":"2022-07-09T16:01:25.888883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> ## Statistical numbers about the data","metadata":{}},{"cell_type":"code","source":"print('There are %s total images.' %(x_train_size + x_test_size + test_files_size))\nprint('There are %d total training categories.' %NUMBER_CLASSES )\nprint('There are %d training images.' % x_train_size)\nprint('There are %d validation images.' % x_test_size)\nprint('There are %d test images.'% test_files_size)","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:54:49.900837Z","iopub.execute_input":"2022-07-09T15:54:49.901205Z","iopub.status.idle":"2022-07-09T15:54:49.910915Z","shell.execute_reply.started":"2022-07-09T15:54:49.901164Z","shell.execute_reply":"2022-07-09T15:54:49.909698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> ## Data Visualization","metadata":{}},{"cell_type":"code","source":"import plotly.express as px\n\npx.histogram(df, x=\"classname\", color=\"classname\", title=\"Number of images by categories \")","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:54:49.914275Z","iopub.execute_input":"2022-07-09T15:54:49.914819Z","iopub.status.idle":"2022-07-09T15:54:53.067615Z","shell.execute_reply.started":"2022-07-09T15:54:49.914780Z","shell.execute_reply":"2022-07-09T15:54:53.066749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> **Comment:** As we can see from the figure above, the classes are well balanced.","metadata":{}},{"cell_type":"code","source":"# Number of Images by Drivers / Test Subject\n\ndrivers_id = pd.DataFrame((df['subject'].value_counts()).reset_index())\ndrivers_id.columns = ['driver_id', 'Counts']\npx.histogram(drivers_id, x=\"driver_id\",y=\"Counts\" ,color=\"driver_id\", title=\"Number of images by subjects \")","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:54:53.068670Z","iopub.execute_input":"2022-07-09T15:54:53.069301Z","iopub.status.idle":"2022-07-09T15:54:53.252956Z","shell.execute_reply.started":"2022-07-09T15:54:53.069262Z","shell.execute_reply":"2022-07-09T15:54:53.251642Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# np.save('./x_train.npy',x_train)\n# np.save('./y_train.npy',y_train)\n# np.save('./x_test.npy',x_test)\n# np.save('./y_test.npy',y_test)","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:54:53.254329Z","iopub.execute_input":"2022-07-09T15:54:53.254602Z","iopub.status.idle":"2022-07-09T15:54:53.259173Z","shell.execute_reply.started":"2022-07-09T15:54:53.254578Z","shell.execute_reply":"2022-07-09T15:54:53.258181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Fully connected layer","metadata":{}},{"cell_type":"code","source":"# x_train = np.load('../input/dl-project/x_train.npy').astype('float32')/255\n# y_train = np_utils.to_categorical(np.load('../input/dl-project/y_train.npy'))\n# x_val = np.load('../input/dl-project/x_test.npy').astype('float32')/255\n# y_val = np_utils.to_categorical(np.load('../input/dl-project/y_test.npy'))","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:54:53.260697Z","iopub.execute_input":"2022-07-09T15:54:53.261328Z","iopub.status.idle":"2022-07-09T15:54:53.271090Z","shell.execute_reply.started":"2022-07-09T15:54:53.261293Z","shell.execute_reply":"2022-07-09T15:54:53.270189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# x_train = tf.convert_to_tensor(x_train, dtype=tf.float32)/255\n# y_train = tf.convert_to_tensor(y_train, dtype=tf.float32)\n# x_val = tf.convert_to_tensor(x_val, dtype=tf.float32)/255\n# y_val = tf.convert_to_tensor(y_val, dtype=tf.float32)","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:54:53.272466Z","iopub.execute_input":"2022-07-09T15:54:53.272972Z","iopub.status.idle":"2022-07-09T15:54:53.279898Z","shell.execute_reply.started":"2022-07-09T15:54:53.272936Z","shell.execute_reply":"2022-07-09T15:54:53.278741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"no_epoch = 20\nbatch_size = 64\nimg_height = img_rows\nimg_width = img_cols\nchannels = 1","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:01:50.424792Z","iopub.execute_input":"2022-07-09T16:01:50.425143Z","iopub.status.idle":"2022-07-09T16:01:50.430591Z","shell.execute_reply.started":"2022-07-09T16:01:50.425115Z","shell.execute_reply":"2022-07-09T16:01:50.429512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> ## Building initial model","metadata":{}},{"cell_type":"code","source":"# temp\nx_train_FC = x_train.reshape((x_train_size, img_rows*img_cols*1))\nx_train_FC = x_train_FC.astype('float32')/255\nx_val_FC = x_test.reshape((x_test_size, img_rows*img_cols*1))\nx_val_FC = x_val_FC.astype('float32')/255\ny_val = y_test","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:54:53.294035Z","iopub.execute_input":"2022-07-09T15:54:53.294374Z","iopub.status.idle":"2022-07-09T15:54:54.976128Z","shell.execute_reply.started":"2022-07-09T15:54:53.294341Z","shell.execute_reply":"2022-07-09T15:54:54.975071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FC_init1 = Sequential()\n# FC_init.add(Flatten())\nFC_init1.add(Dense(512, activation='relu', name='Layer_1', input_shape=(img_width * img_height * channels,)))\nFC_init1.add(Dense(256, activation='relu', name='Layer_2'))\nFC_init1.add(Dense(128, activation='relu', name='Layer_3'))\nFC_init1.add(Dense(10, activation='softmax'))","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:54:54.977584Z","iopub.execute_input":"2022-07-09T15:54:54.977959Z","iopub.status.idle":"2022-07-09T15:54:55.143122Z","shell.execute_reply.started":"2022-07-09T15:54:54.977921Z","shell.execute_reply":"2022-07-09T15:54:55.142210Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"opt = keras.optimizers.Adam(learning_rate=10e-3)\nFC_init1.compile(optimizer=opt,\n                loss='categorical_crossentropy',\n                metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:54:55.144634Z","iopub.execute_input":"2022-07-09T15:54:55.145208Z","iopub.status.idle":"2022-07-09T15:54:55.156014Z","shell.execute_reply.started":"2022-07-09T15:54:55.145170Z","shell.execute_reply":"2022-07-09T15:54:55.155084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FC_init1.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:54:55.157592Z","iopub.execute_input":"2022-07-09T15:54:55.158005Z","iopub.status.idle":"2022-07-09T15:54:55.166306Z","shell.execute_reply.started":"2022-07-09T15:54:55.157968Z","shell.execute_reply":"2022-07-09T15:54:55.165225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"early_stopping = keras.callbacks.EarlyStopping(\n    monitor='val_loss',\n    min_delta=0.001,\n    patience=3,\n    verbose=1,\n    mode='min',\n    baseline=None,\n    restore_best_weights=True\n)","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:02:30.888120Z","iopub.execute_input":"2022-07-09T16:02:30.888485Z","iopub.status.idle":"2022-07-09T16:02:30.894116Z","shell.execute_reply.started":"2022-07-09T16:02:30.888455Z","shell.execute_reply":"2022-07-09T16:02:30.892981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"History = FC_init1.fit(x_train_FC,y_train, validation_data=(x_val_FC,y_val), verbose = 1, epochs = no_epoch, batch_size = batch_size,callbacks=[early_stopping])","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:54:55.178303Z","iopub.execute_input":"2022-07-09T15:54:55.178864Z","iopub.status.idle":"2022-07-09T15:55:31.245849Z","shell.execute_reply.started":"2022-07-09T15:54:55.178824Z","shell.execute_reply":"2022-07-09T15:55:31.244572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"acc = History.history['accuracy']\nval_acc = History.history['val_accuracy']\nloss = History.history['loss']\nval_loss = History.history['val_loss']\n\nepochs = range(len(acc))\n\nplt.plot(epochs, acc, 'bo', label='Training acc')\nplt.plot(epochs, val_acc, 'b', label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'bo', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:55:31.247802Z","iopub.execute_input":"2022-07-09T15:55:31.248084Z","iopub.status.idle":"2022-07-09T15:55:39.379137Z","shell.execute_reply.started":"2022-07-09T15:55:31.248058Z","shell.execute_reply":"2022-07-09T15:55:39.378214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Predict ","metadata":{}},{"cell_type":"code","source":"test_files.dtype","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:55:39.382561Z","iopub.execute_input":"2022-07-09T15:55:39.382859Z","iopub.status.idle":"2022-07-09T15:55:39.391558Z","shell.execute_reply.started":"2022-07-09T15:55:39.382832Z","shell.execute_reply":"2022-07-09T15:55:39.390385Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_files[0].shape","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:55:39.393514Z","iopub.execute_input":"2022-07-09T15:55:39.394363Z","iopub.status.idle":"2022-07-09T15:55:39.401969Z","shell.execute_reply.started":"2022-07-09T15:55:39.394325Z","shell.execute_reply":"2022-07-09T15:55:39.400974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_train.dtype","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:55:39.403242Z","iopub.execute_input":"2022-07-09T15:55:39.404097Z","iopub.status.idle":"2022-07-09T15:55:39.415623Z","shell.execute_reply.started":"2022-07-09T15:55:39.404054Z","shell.execute_reply":"2022-07-09T15:55:39.414747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(test_files))\nprint(test_files_size)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:55:39.417193Z","iopub.execute_input":"2022-07-09T15:55:39.417900Z","iopub.status.idle":"2022-07-09T15:55:39.429542Z","shell.execute_reply.started":"2022-07-09T15:55:39.417863Z","shell.execute_reply":"2022-07-09T15:55:39.428493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_imgs = test_files.reshape((nb_test_samples, img_rows*img_cols*1))\ntest_imgs = test_imgs.astype('float32')/255\n","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:55:39.431090Z","iopub.execute_input":"2022-07-09T15:55:39.431813Z","iopub.status.idle":"2022-07-09T15:55:39.445667Z","shell.execute_reply.started":"2022-07-09T15:55:39.431779Z","shell.execute_reply":"2022-07-09T15:55:39.444422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred = FC_init1.predict(test_imgs)\npred[0]","metadata":{"execution":{"iopub.status.busy":"2022-07-09T15:55:39.448410Z","iopub.execute_input":"2022-07-09T15:55:39.455895Z","iopub.status.idle":"2022-07-09T15:55:39.559705Z","shell.execute_reply.started":"2022-07-09T15:55:39.455860Z","shell.execute_reply":"2022-07-09T15:55:39.558753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Building Baseline CNN Model","metadata":{}},{"cell_type":"code","source":"# temp\nx_train_CNN = x_train.reshape((x_train_size, img_rows,img_cols,1))\nx_train_CNN = x_train_CNN.astype('float32')/255\nx_val_CNN = x_test.reshape((x_test_size, img_rows,img_cols,1))\nx_val_CNN = x_val_CNN.astype('float32')/255\ny_val = y_test","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:01:33.265451Z","iopub.execute_input":"2022-07-09T16:01:33.265810Z","iopub.status.idle":"2022-07-09T16:01:33.759647Z","shell.execute_reply.started":"2022-07-09T16:01:33.265782Z","shell.execute_reply":"2022-07-09T16:01:33.758655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CNN_model = Sequential()\nCNN_model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(img_height, img_width, channels)))\nCNN_model.add(MaxPooling2D((2, 2)))\nCNN_model.add(Conv2D(64, (3, 3), activation='relu'))\nCNN_model.add(MaxPooling2D((2, 2)))\nCNN_model.add(Conv2D(64, (3, 3), activation='relu'))\nCNN_model.add(Flatten())\nCNN_model.add(Dense(64, activation='relu'))\nCNN_model.add(Dense(10, activation='softmax'))\n","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:01:59.547360Z","iopub.execute_input":"2022-07-09T16:01:59.548298Z","iopub.status.idle":"2022-07-09T16:01:59.716768Z","shell.execute_reply.started":"2022-07-09T16:01:59.548252Z","shell.execute_reply":"2022-07-09T16:01:59.715798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"adam = tf.keras.optimizers.Adam(learning_rate=0.0001)\nCNN_model.compile(optimizer=adam,\n              loss='categorical_crossentropy',\n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:02:04.763412Z","iopub.execute_input":"2022-07-09T16:02:04.763771Z","iopub.status.idle":"2022-07-09T16:02:05.114427Z","shell.execute_reply.started":"2022-07-09T16:02:04.763742Z","shell.execute_reply":"2022-07-09T16:02:05.113462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CNN_model.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:02:06.498939Z","iopub.execute_input":"2022-07-09T16:02:06.499851Z","iopub.status.idle":"2022-07-09T16:02:06.508418Z","shell.execute_reply.started":"2022-07-09T16:02:06.499806Z","shell.execute_reply":"2022-07-09T16:02:06.507388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"History_CNN = CNN_model.fit(x_train_CNN,y_train, validation_data=(x_val_CNN,y_val), verbose = 1, epochs = no_epoch, batch_size = batch_size,callbacks=[early_stopping])","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:02:36.708788Z","iopub.execute_input":"2022-07-09T16:02:36.709128Z","iopub.status.idle":"2022-07-09T16:04:07.030014Z","shell.execute_reply.started":"2022-07-09T16:02:36.709098Z","shell.execute_reply":"2022-07-09T16:04:07.029017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"acc = History_CNN.history['accuracy']\nval_acc = History_CNN.history['val_accuracy']\nloss = History_CNN.history['loss']\nval_loss = History_CNN.history['val_loss']\n\nepochs = range(len(acc))\n\nplt.plot(epochs, acc, 'bo', label='Training acc')\nplt.plot(epochs, val_acc, 'b', label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'bo', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:04:07.032167Z","iopub.execute_input":"2022-07-09T16:04:07.032677Z","iopub.status.idle":"2022-07-09T16:04:07.454126Z","shell.execute_reply.started":"2022-07-09T16:04:07.032630Z","shell.execute_reply":"2022-07-09T16:04:07.453227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_imgs = test_files.reshape((nb_test_samples, img_rows,img_cols,1))\ntest_imgs = test_imgs.astype('float32')/255\n","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:04:07.455446Z","iopub.execute_input":"2022-07-09T16:04:07.456017Z","iopub.status.idle":"2022-07-09T16:04:07.464283Z","shell.execute_reply.started":"2022-07-09T16:04:07.455979Z","shell.execute_reply":"2022-07-09T16:04:07.463132Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred = CNN_model.predict(test_imgs)\npred[0]","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:04:07.466944Z","iopub.execute_input":"2022-07-09T16:04:07.467504Z","iopub.status.idle":"2022-07-09T16:04:07.691191Z","shell.execute_reply.started":"2022-07-09T16:04:07.467466Z","shell.execute_reply":"2022-07-09T16:04:07.690247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Augmentation","metadata":{}},{"cell_type":"code","source":"# Version 01\n\nTraindatagen = ImageDataGenerator(\n      featurewise_center = True,\n      featurewise_std_normalization = True,\n      rescale = 1.0/255,\n      rotation_range=20,\n      shear_range=0.2,\n      horizontal_flip=True,\n      vertical_flip=False,\n      fill_mode='nearest')\n\n\nValdatagen =  ImageDataGenerator(featurewise_center = True, \n                                 featurewise_std_normalization = True, \n                                 rescale=1.0/ 255, \n                                 validation_split = 0.2)","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:17:31.834161Z","iopub.execute_input":"2022-07-09T16:17:31.834906Z","iopub.status.idle":"2022-07-09T16:17:31.843200Z","shell.execute_reply.started":"2022-07-09T16:17:31.834861Z","shell.execute_reply":"2022-07-09T16:17:31.841719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Transfer learning using VGG16","metadata":{}},{"cell_type":"code","source":"# loading train images\nx_train_vgg, x_test_vgg, y_train_vgg, y_test_vgg = read_and_normalize_train_data(img_rows, img_cols, 3)\n\n# loading validation images\n# test_files, test_targets = read_and_normalize_sampled_test_data(nb_test_samples, img_rows, img_cols, 3)","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:17:40.260631Z","iopub.execute_input":"2022-07-09T16:17:40.261014Z","iopub.status.idle":"2022-07-09T16:21:57.623609Z","shell.execute_reply.started":"2022-07-09T16:17:40.260982Z","shell.execute_reply":"2022-07-09T16:21:57.622443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator = Traindatagen.flow(x_train_vgg, y_train_vgg, batch_size = 256)\nval_generator = Valdatagen.flow(x_test_vgg, y_test_vgg, batch_size = 64)","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:21:57.625513Z","iopub.execute_input":"2022-07-09T16:21:57.625857Z","iopub.status.idle":"2022-07-09T16:21:59.060350Z","shell.execute_reply.started":"2022-07-09T16:21:57.625822Z","shell.execute_reply":"2022-07-09T16:21:59.059214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 40\ntrain_bs = 256\nvaldi_bs = 64","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:21:59.061969Z","iopub.execute_input":"2022-07-09T16:21:59.062343Z","iopub.status.idle":"2022-07-09T16:21:59.067805Z","shell.execute_reply.started":"2022-07-09T16:21:59.062304Z","shell.execute_reply":"2022-07-09T16:21:59.066979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.applications.vgg16 import VGG16\n\ndef classificationModel():\n    inp = keras.layers.Input(shape=(128, 128, 3))\n    vgg = VGG16(weights='imagenet',\n                  include_top=False,\n                  input_tensor = inp,\n                  input_shape=(128, 128, 3))\n    vgg.trainable = False\n    \n    x = vgg.get_layer('block5_pool').output\n    x = tf.keras.layers.Flatten()(x)\n    # x = tf.keras.layers.GlobalAveragePooling2D()(x)\n    x = keras.layers.Dense(256, activation='relu')(x)\n    output = keras.layers.Dense(10, activation='softmax')(x)\n    \n    model = tf.keras.models.Model(inputs = inp, outputs=output)\n\n    return model\n    ","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:21:59.070594Z","iopub.execute_input":"2022-07-09T16:21:59.071311Z","iopub.status.idle":"2022-07-09T16:21:59.086322Z","shell.execute_reply.started":"2022-07-09T16:21:59.071273Z","shell.execute_reply":"2022-07-09T16:21:59.085302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"keras.backend.clear_session()\nmodel = classificationModel()\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:21:59.087968Z","iopub.execute_input":"2022-07-09T16:21:59.088382Z","iopub.status.idle":"2022-07-09T16:22:03.345855Z","shell.execute_reply.started":"2022-07-09T16:21:59.088348Z","shell.execute_reply":"2022-07-09T16:22:03.344748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# opt = tf.keras.optimizers.Adam(learning_rate=0.0001)\n# model.compile(optimizer='rmsprop',\n#                 loss='categorical_crossentropy',\n#                 metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:22:03.347852Z","iopub.execute_input":"2022-07-09T16:22:03.348232Z","iopub.status.idle":"2022-07-09T16:22:03.355815Z","shell.execute_reply.started":"2022-07-09T16:22:03.348193Z","shell.execute_reply":"2022-07-09T16:22:03.354687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"opt = tf.keras.optimizers.Adam(learning_rate=0.0001)\nmodel.compile(optimizer=opt,\n                loss='categorical_crossentropy',\n                metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:22:03.357558Z","iopub.execute_input":"2022-07-09T16:22:03.357937Z","iopub.status.idle":"2022-07-09T16:22:03.517894Z","shell.execute_reply.started":"2022-07-09T16:22:03.357887Z","shell.execute_reply":"2022-07-09T16:22:03.516929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"early_stopping = keras.callbacks.EarlyStopping(\n    monitor='val_loss',\n    min_delta=0.0001,\n    patience=3,\n    verbose=1,\n    mode='min',\n    baseline=None,\n    restore_best_weights=True\n)","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:22:03.520290Z","iopub.execute_input":"2022-07-09T16:22:03.520982Z","iopub.status.idle":"2022-07-09T16:22:03.529113Z","shell.execute_reply.started":"2022-07-09T16:22:03.520940Z","shell.execute_reply":"2022-07-09T16:22:03.528066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## CNN Visualization","metadata":{}},{"cell_type":"code","source":"%%capture\n!pip install wandb","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:22:03.530671Z","iopub.execute_input":"2022-07-09T16:22:03.531011Z","iopub.status.idle":"2022-07-09T16:22:14.987214Z","shell.execute_reply.started":"2022-07-09T16:22:03.530974Z","shell.execute_reply":"2022-07-09T16:22:14.985967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import wandb\nfrom wandb.keras import WandbCallback\n\nwandb.login()","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:22:14.991860Z","iopub.execute_input":"2022-07-09T16:22:14.992646Z","iopub.status.idle":"2022-07-09T16:22:29.234442Z","shell.execute_reply.started":"2022-07-09T16:22:14.992603Z","shell.execute_reply":"2022-07-09T16:22:29.232902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class GradCAM:\n    \"\"\"\n    Reference:\n        https://www.pyimagesearch.com/2020/03/09/grad-cam-visualize-class-activation-maps-with-keras-tensorflow-and-deep-learning/\n    \"\"\"\n\n    def __init__(self, model, layerName):\n        self.model = model\n        self.layerName = layerName\n\n        self.gradModel = tf.keras.models.Model(inputs=[self.model.inputs],\n                                               outputs=[self.model.get_layer(self.layerName).output, self.model.output])\n\n    def compute_heatmap(self, image, classIdx, eps=1e-8):\n        with tf.GradientTape() as tape:\n            tape.watch(self.gradModel.get_layer(self.layerName).variables)\n            inputs = tf.cast(image, tf.float32)\n            (convOutputs, predictions) = self.gradModel(inputs)\n\n            if len(predictions) == 1:\n                # Binary Classification\n                loss = predictions[0]\n            else:\n                loss = predictions[:, classIdx]\n\n        grads = tape.gradient(loss, convOutputs)\n\n        castConvOutputs = tf.cast(convOutputs > 0, \"float32\")\n        castGrads = tf.cast(grads > 0, \"float32\")\n        guidedGrads = castConvOutputs * castGrads * grads\n\n        convOutputs = convOutputs[0]\n        guidedGrads = guidedGrads[0]\n\n        weights = tf.reduce_mean(guidedGrads, axis=(0, 1))\n        cam = tf.reduce_sum(tf.multiply(weights, convOutputs), axis=-1)\n\n        (w, h) = (image.shape[2], image.shape[1])\n        heatmap = cv2.resize(cam.numpy(), (w, h))\n\n        numer = heatmap - np.min(heatmap)\n        denom = (heatmap.max() - heatmap.min()) + eps\n        heatmap = numer / denom\n        heatmap = (heatmap * 255).astype(\"uint8\")\n\n        return heatmap\n\n\n    def overlay_heatmap(self, heatmap, image, alpha=0.5, colormap=cv2.COLORMAP_HOT):\n        heatmap = cv2.applyColorMap(heatmap, colormap)\n        output = cv2.addWeighted(image, alpha, heatmap, 1 - alpha, 0)\n\n        return (heatmap, output)","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:22:33.129006Z","iopub.execute_input":"2022-07-09T16:22:33.129745Z","iopub.status.idle":"2022-07-09T16:22:33.144176Z","shell.execute_reply.started":"2022-07-09T16:22:33.129708Z","shell.execute_reply":"2022-07-09T16:22:33.143111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class GRADCamLogger(tf.keras.callbacks.Callback):\n    def __init__(self, validation_data, layer_name):\n      super(GRADCamLogger, self).__init__()\n      self.validation_data = validation_data\n      self.layer_name = layer_name\n\n    def on_epoch_end(self, logs, epoch):\n      images = []\n      grad_cam = []\n\n      ## Initialize GRADCam Class\n      cam = GradCAM(model, self.layer_name)\n\n      for image in self.validation_data:\n        image = np.expand_dims(image, 0)\n        pred = model.predict(image)\n        classIDx = np.argmax(pred[0])\n  \n        ## Compute Heatmap\n        heatmap = cam.compute_heatmap(image, classIDx)\n        \n        image = image.reshape(image.shape[1:])\n        image = image*255\n        image = image.astype(np.uint8)\n\n        ## Overlay heatmap on original image\n        heatmap = cv2.resize(heatmap, (image.shape[0],image.shape[1]))\n        (heatmap, output) = cam.overlay_heatmap(heatmap, image, alpha=0.5)\n\n        images.append(image)\n        grad_cam.append(output)\n\n      wandb.log({\"images\": [wandb.Image(image)\n                            for image in images]})\n      wandb.log({\"gradcam\": [wandb.Image(cam)\n                            for cam in grad_cam]})","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:22:33.906127Z","iopub.execute_input":"2022-07-09T16:22:33.907131Z","iopub.status.idle":"2022-07-09T16:22:33.916991Z","shell.execute_reply.started":"2022-07-09T16:22:33.907094Z","shell.execute_reply":"2022-07-09T16:22:33.916024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Prepare sample images to run your GradCam on. \nsample_images, sample_labels = val_generator[20]\nsample_images.shape, sample_labels.shape","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:22:38.540485Z","iopub.execute_input":"2022-07-09T16:22:38.540829Z","iopub.status.idle":"2022-07-09T16:22:38.561259Z","shell.execute_reply.started":"2022-07-09T16:22:38.540798Z","shell.execute_reply":"2022-07-09T16:22:38.560284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> ## Interactive Monitoring Window <br>\nYou can scroll up and down across charts, view system utilization, model architecture. <br>\n**First Set of Panels (Charts):** <br>\n> 1. Training accuracy, Validation accuracy vs Step\n> 2. Training loss, Validation loss vs Step\n> 3. Epochs vs Step\n\n> **Second Set of Panels (Activation maps):** <br>\n> 1. Gradient Cam activation maps per class vs Step\n> 2. Images vs Step\n> 3. Examples vs Step","metadata":{}},{"cell_type":"code","source":"wandb.init(project=\"test\", entity=\"team-7\")","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:22:43.501271Z","iopub.execute_input":"2022-07-09T16:22:43.501623Z","iopub.status.idle":"2022-07-09T16:22:46.248134Z","shell.execute_reply.started":"2022-07-09T16:22:43.501592Z","shell.execute_reply":"2022-07-09T16:22:46.246790Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> ## Accuracy <br>\n- The transfer Learning using VGG16 conv_base and the augmented data reached a validation **accuracy** of **98.59%**","metadata":{}},{"cell_type":"code","source":"# History_Rs = resnetRs.fit(train_generator,\n#          validation_data=val_generator,\n#          steps_per_epoch=len(x_train_rs) // train_bs, epochs=epochs,\n#           validation_steps =len(x_test_rs)//valdi_bs, verbose = 1)\n\n\nhistory = model.fit(train_generator,\n                          validation_data=val_generator,\n                          steps_per_epoch=len(x_train_vgg) // train_bs, \n                          epochs=epochs,\n                          validation_steps =len(x_test_vgg)//valdi_bs, \n                          verbose = 1,\n                          callbacks=[WandbCallback(data_type=\"image\", validation_data=(sample_images, sample_labels)),\n                                     GRADCamLogger(sample_images, layer_name='block5_conv3'),\n                                     early_stopping])\n","metadata":{"execution":{"iopub.status.busy":"2022-07-09T16:22:46.250367Z","iopub.execute_input":"2022-07-09T16:22:46.250975Z","iopub.status.idle":"2022-07-09T17:06:26.831983Z","shell.execute_reply.started":"2022-07-09T16:22:46.250925Z","shell.execute_reply":"2022-07-09T17:06:26.831037Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('./vgg_tl_model.h5')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_model = tf.keras.models.load_model('./my_model.h5')","metadata":{"execution":{"iopub.status.busy":"2022-07-08T15:06:00.280427Z","iopub.execute_input":"2022-07-08T15:06:00.280931Z","iopub.status.idle":"2022-07-08T15:06:00.645273Z","shell.execute_reply.started":"2022-07-08T15:06:00.280886Z","shell.execute_reply":"2022-07-08T15:06:00.644115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"acc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(len(acc))\n\nplt.plot(epochs, acc, 'bo', label='Training acc')\nplt.plot(epochs, val_acc, 'b', label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'bo', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-09T17:06:44.641604Z","iopub.execute_input":"2022-07-09T17:06:44.642092Z","iopub.status.idle":"2022-07-09T17:06:45.049529Z","shell.execute_reply.started":"2022-07-09T17:06:44.642046Z","shell.execute_reply":"2022-07-09T17:06:45.048567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Thank You !!","metadata":{"execution":{"iopub.status.busy":"2022-07-09T17:40:58.069416Z","iopub.execute_input":"2022-07-09T17:40:58.070126Z","iopub.status.idle":"2022-07-09T17:40:58.076814Z","shell.execute_reply.started":"2022-07-09T17:40:58.070088Z","shell.execute_reply":"2022-07-09T17:40:58.075524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}