{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Ship Detection using Faster R-CNN" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Importing libraries\n", "\n", "The necessary libraries required for implementing the Faster R-CNN model are imported in the code block below." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Checking System\n", "\n", "Tensorflow version : 2.11.0-dev20220812\n", "Number of replicas: 1\n", "2.11.0-dev20220812\n", "\n", "System check done in 0.0104 seconds\n", "System Checked!\n" ] } ], "source": [ "import time\n", "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", "\n", "from IPython.display import SVG\n", "# from tensorflow.python import keras\n", "from 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 keras.utils import to_categorical\n", "from keras.models import Sequential, Model\n", "from keras.layers import (Add, Input, Conv2D, Dropout, Activation, BatchNormalization, MaxPooling2D, ZeroPadding2D, AveragePooling2D, Flatten, Dense)\n", "from keras.optimizers import Adam, SGD\n", "from keras.callbacks import TensorBoard, ModelCheckpoint, Callback\n", "from keras.preprocessing.image import ImageDataGenerator\n", "from keras.initializers import *\n", "\n", "\n", "start_time = time.perf_counter()\n", "print(\"Checking System\\n\")\n", "\n", "SEED = 1337\n", "print('Tensorflow version : {}'.format(tf.__version__))\n", "\n", "try:\n", " tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n", " tf.config.experimental_connect_to_cluster(tpu)\n", " tf.tpu.experimental.initialize_tpu_system(tpu)\n", " strategy = tf.distribute.experimental.TPUStrategy(tpu)\n", "except ValueError:\n", " strategy = tf.distribute.get_strategy() # for CPU and single GPU\n", " print('Number of replicas:', strategy.num_replicas_in_sync)\n", " \n", "print(tf.__version__)\n", "\n", "end_time = time.perf_counter()\n", "\n", "print(f\"\\nSystem check done in {end_time - start_time:0.4f} seconds\")\n", "print(\"System Checked!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Utility functions\n", "\n", "1. show_final_history - For plotting the loss and accuracy of the training and validation datasets\n", "2. plot_confusion_matrix - For plotting the percentage of true positives per class for a better feel of how the model predicted the data" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "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": 6, "metadata": {}, "outputs": [], "source": [ "def plot_confusion_matrix(cm,classes,title='Confusion Matrix',cmap=plt.cm.Blues):\n", " \n", "# np.seterr(divide='ignore',invalid='ignore')\n", " cm = cm.astype('float')/cm.sum(axis=1)[:,np.newaxis]\n", " plt.figure(figsize=(10,10))\n", " plt.imshow(cm,interpolation='nearest',cmap=cmap)\n", " plt.title(title)\n", " plt.colorbar()\n", " tick_marks = np.arange(len(classes))\n", " plt.xticks(tick_marks, classes,rotation=45)\n", " plt.yticks(tick_marks, classes)\n", " \n", " fmt = '.2f'\n", " thresh = cm.max()/2.\n", " for i,j in itertools.product(range(cm.shape[0]),range(cm.shape[1])):\n", " plt.text(j,i,format(cm[i,j],fmt),\n", " horizontalalignment=\"center\",\n", " color=\"white\" if cm[i,j] > thresh else \"black\")\n", " pass\n", " \n", " plt.ylabel('True Label')\n", " plt.xlabel('Predicted Label')\n", " pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading the images\n", "\n", "The images from the SatelliteImageryofShips is loaded into numpy arrays, with labels [0,1] corresponding to the classes no-ship and ship. The data was loaded into numpy arrays as data augmentation and upsampling/downsampling is easier to perform." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'no-ship': 0, 'ship': 1}" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "datasets = ['./SatelliteImageryofShips/']\n", "\n", "class_names = [\"no-ship\",\"ship\"]\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": 17, "metadata": {}, "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.cvtColor(img,cv2.COLOR_BGR2RGB)\n", " img = cv2.resize(img, (48,48))\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": 18, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 3000/3000 [00:05<00:00, 572.93it/s]\n", "100%|██████████| 1000/1000 [00:01<00:00, 566.53it/s]\n" ] }, { "data": { "text/plain": [ "((4000, 48, 48, 3), (4000,))" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(images, labels) = load_data()\n", "images.shape, labels.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## EDA of dataset\n", "\n", "1. bar-plot - Bar plot is made to find the count of images per class\n", "2. pie-plot - Pie plot is drawn to find the percentage of class distribution in the dataset" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
| \n", " | Count | \n", "
|---|---|
| Class-Label | \n", "\n", " |
| no-ship | \n", "3000 | \n", "
| ship | \n", "1000 | \n", "