{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Indian Classical Dance Classification by VGG16.ipynb",
      "provenance": [],
      "toc_visible": true
    },
    "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.6.4"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "32s6i6TIG48J"
      },
      "source": [
        "### Indian Classical Dance Classification\n",
        "\n",
        "\n",
        "**Dataset**\n",
        "\n",
        "The dataset1 folder consists of two folders and two .csv files. The details are as follows:\n",
        "\n",
        "train: Contains 364 images for 8 classes (approx 50 images per class)\n",
        "* manipuri,\n",
        "* bharatanatyam\n",
        "* odissi\n",
        "* kathakali\n",
        "* kathak\n",
        "* sattriya\n",
        "* kuchipudi\n",
        "* mohiniyattam\n",
        "\n",
        "test: Contains 156 images\n",
        "\n",
        "train.csv: 364 x 2\n",
        "\n",
        "test.csv: 156 x 1\n",
        "\n",
        "Below is the format of csv files\n",
        "\n",
        "| Column Name | Description |\n",
        "|-------------|-------------|\n",
        "| Image       | img.jpg | \n",
        "|target       |'manipuri', 'bharatanatyam', 'odissi', 'kathakali', 'kathak', 'sattriya', 'kuchipudi', 'mohiniyattam' |\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "BJMh_aI9G48J"
      },
      "source": [
        "**Transfer Learning and Image Augmentation is used as we have limited training data.**\n",
        "\n",
        "**Transfer Learing:** As the name justifies, the learnings of model can be transfered from one problem to another. Here we use the precomputed weights for the feature extraction stage, wherein the VGG16 model was trained on ImageNet dataset having classes completely different from our problem statement, whereas the classification stage uses a Feed Forward Neural Network with 2 hidden layers trained on available dataset. \n",
        "\n",
        "**Image Augmentation:** We increase the dataset by applying random transformations like rotation, flips, etc to the existing image leading to multiple images as output for a single image."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "0ZzsDMV2G48J"
      },
      "source": [
        "# import required libraries \n",
        "import os\n",
        "import pandas as pd\n",
        "import numpy as np\n",
        "import cv2\n",
        "import matplotlib.pyplot as plt\n",
        "import tensorflow as tf\n",
        "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
        "from tensorflow.keras.applications.vgg16 import VGG16\n",
        "from tensorflow.keras.applications.vgg16 import preprocess_input\n",
        "from tensorflow.keras.preprocessing import image\n",
        "from tensorflow.keras.layers import Flatten,Dense,Dropout,BatchNormalization\n",
        "from tensorflow.keras.models import Model,Sequential\n",
        "from tensorflow.keras.utils import to_categorical\n",
        "from tensorflow.keras.layers import Conv2D, MaxPooling2D, BatchNormalization\n",
        "\n",
        "from tensorflow.keras.callbacks import ReduceLROnPlateau\n",
        "from sklearn.model_selection import train_test_split\n",
        "\n",
        "from tensorflow.keras.optimizers import Adam,SGD,Adagrad,Adadelta,RMSprop\n",
        "\n",
        "from sklearn.preprocessing import LabelEncoder\n",
        "from sklearn.metrics import classification_report, confusion_matrix\n",
        "from sklearn import metrics\n",
        "import itertools"
      ],
      "execution_count": 1,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "e-6mtNIWodzW",
        "outputId": "8c714551-a031-410b-9a33-0251eaab989e"
      },
      "source": [
        "# Download dataset from google drive\n",
        "!pip install gdown\n",
        "!gdown --id 1Sn6Ke0U0LYpVGq8YnD2DcfbgPviW6S6b\n",
        "!tar -zxf dataset1.tar.gz\n",
        "!rm dataset1.tar.gz"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Requirement already satisfied: gdown in /usr/local/lib/python3.6/dist-packages (3.6.4)\n",
            "Requirement already satisfied: requests in /usr/local/lib/python3.6/dist-packages (from gdown) (2.23.0)\n",
            "Requirement already satisfied: tqdm in /usr/local/lib/python3.6/dist-packages (from gdown) (4.41.1)\n",
            "Requirement already satisfied: six in /usr/local/lib/python3.6/dist-packages (from gdown) (1.15.0)\n",
            "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.6/dist-packages (from requests->gdown) (1.24.3)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.6/dist-packages (from requests->gdown) (2020.11.8)\n",
            "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.6/dist-packages (from requests->gdown) (3.0.4)\n",
            "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.6/dist-packages (from requests->gdown) (2.10)\n",
            "Downloading...\n",
            "From: https://drive.google.com/uc?id=1Sn6Ke0U0LYpVGq8YnD2DcfbgPviW6S6b\n",
            "To: /content/dataset1.tar.gz\n",
            "27.6MB [00:00, 66.6MB/s]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Td4H1w8jG48K",
        "outputId": "9fcfd7ca-cc0a-4795-8b1f-67594e73a949"
      },
      "source": [
        "# Load train and test csv file for image class\n",
        "train = pd.read_csv('train.csv')\n",
        "test = pd.read_csv('test.csv')\n",
        "\n",
        "print(train.head())\n",
        "print(test.head())\n",
        "print(train['target'].value_counts())"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "     Image         target\n",
            "0   96.jpg       manipuri\n",
            "1  163.jpg  bharatanatyam\n",
            "2  450.jpg         odissi\n",
            "3  219.jpg      kathakali\n",
            "4  455.jpg         odissi\n",
            "     Image\n",
            "0  508.jpg\n",
            "1  246.jpg\n",
            "2  473.jpg\n",
            "3  485.jpg\n",
            "4  128.jpg\n",
            "mohiniyattam     50\n",
            "odissi           49\n",
            "kathakali        47\n",
            "bharatanatyam    47\n",
            "kuchipudi        46\n",
            "sattriya         45\n",
            "kathak           44\n",
            "manipuri         36\n",
            "Name: target, dtype: int64\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 349
        },
        "id": "Lb7uGe7CG48M",
        "outputId": "05964e2a-5963-4165-97a0-c6d7aeadc7d9"
      },
      "source": [
        "# Basic Histrogram plot to check number of training data for each dance form. \n",
        "train['target'].value_counts().plot(kind='bar')"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<matplotlib.axes._subplots.AxesSubplot at 0x7f306f48aa58>"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 4
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "[encoded data, 10124 characters]\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "hPVVtxpaG48M",
        "outputId": "11271182-e175-474e-cde1-9740da97812d"
      },
      "source": [
        "# Load file names storing train and test images \n",
        "train_dir = 'train/'\n",
        "test_dir = 'test/'\n",
        "\n",
        "train_fnames = os.listdir(train_dir)\n",
        "test_fnames = os.listdir(test_dir)\n",
        "\n",
        "train_fnames.sort()\n",
        "test_fnames.sort()\n",
        "\n",
        "print(train_fnames[:9])\n",
        "print(test_fnames[:9])"
      ],
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "['1.jpg', '10.jpg', '100.jpg', '101.jpg', '102.jpg', '103.jpg', '104.jpg', '105.jpg', '106.jpg']\n",
            "['108.jpg', '11.jpg', '110.jpg', '112.jpg', '114.jpg', '119.jpg', '125.jpg', '128.jpg', '129.jpg']\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "AAvnBzsOG48N"
      },
      "source": [
        "# Data-set images are of different sizes, but the VGG16 model accepts images of size 224*224\n",
        "img_width = 224\n",
        "img_height = 224"
      ],
      "execution_count": 6,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_zE0jR_9G48N"
      },
      "source": [
        "OpenCV is used for reading images and resizing using Bicubic interpolation."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "VN3O7TX7G48N"
      },
      "source": [
        "# Constructing list of features and targets\n",
        "def train_data_preparation(list_of_images, train, train_dir):\n",
        "    \"\"\"\n",
        "    Returns two arrays: \n",
        "        x is an array of resized images\n",
        "        y is an array of labels\n",
        "    \"\"\"\n",
        "    x = [] # resized images as arrays\n",
        "    y = [] # labels\n",
        "    for image in list_of_images:\n",
        "        x.append(cv2.resize(cv2.imread(train_dir+image), (img_width,img_height), interpolation=cv2.INTER_CUBIC))\n",
        "        y.append(train.loc[train['Image'] == image, 'target'].values[0])  \n",
        "            \n",
        "    return x, y"
      ],
      "execution_count": 7,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "GwWUb3ZNG48N"
      },
      "source": [
        "def test_data_prepare(list_of_images, test_dir):\n",
        "    \"\"\"\n",
        "    Returns one arrays: \n",
        "        x is an array of resized images\n",
        "    \"\"\"\n",
        "    x = [] # images as arrays\n",
        "    \n",
        "    for image in list_of_images:\n",
        "        x.append(cv2.resize(cv2.imread(test_dir+image), (img_width,img_height), interpolation=cv2.INTER_CUBIC)) \n",
        "            \n",
        "    return x"
      ],
      "execution_count": 8,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "2qhi0nIhG48N"
      },
      "source": [
        "training_data, training_labels = train_data_preparation(train_fnames, train, train_dir)"
      ],
      "execution_count": 9,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "roD1omI9G48O"
      },
      "source": [
        "# To check if feature label mapping is correct\n",
        "def show_batch(image_batch, label_batch):\n",
        "    plt.figure(figsize=(18,18))\n",
        "    count = 0\n",
        "    for n in range(25):\n",
        "        ax = plt.subplot(10,5,n+1)\n",
        "        plt.imshow(cv2.cvtColor(image_batch[n], cv2.COLOR_BGR2RGB))\n",
        "        plt.title(label_batch[n].title())\n",
        "        plt.axis('off')"
      ],
      "execution_count": 10,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FgfWoGgdG48O"
      },
      "source": [
        "Just showing loaded data for first 25 image"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 528
        },
        "id": "w1KRtbTiG48O",
        "outputId": "0d0b690a-4c2a-40bc-90f7-b4ddd72f1068"
      },
      "source": [
        "show_batch(training_data, training_labels)"
      ],
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "[encoded data, 438928 characters]\n",
            "text/plain": [
              "<Figure size 1296x1296 with 25 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Y1JDIcccG48O"
      },
      "source": [
        "testing_data = test_data_prepare(test_fnames, test_dir)"
      ],
      "execution_count": 12,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rCpmgedVG48O"
      },
      "source": [
        "Label encoder converting target class to numeric format"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "YoRGK77BG48O",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "34873e3f-81ed-4708-b366-f67bac543105"
      },
      "source": [
        "le =LabelEncoder()\n",
        "training_labels=le.fit_transform(training_labels)\n",
        "dict(zip(le.classes_, le.transform(le.classes_)))"
      ],
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "{'bharatanatyam': 0,\n",
              " 'kathak': 1,\n",
              " 'kathakali': 2,\n",
              " 'kuchipudi': 3,\n",
              " 'manipuri': 4,\n",
              " 'mohiniyattam': 5,\n",
              " 'odissi': 6,\n",
              " 'sattriya': 7}"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 13
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "alWEBPYYG48P"
      },
      "source": [
        "# Spliting data into train and dev\n",
        "X_train, X_val, y_train, y_val = train_test_split(training_data, training_labels, test_size=0.2, random_state=42)"
      ],
      "execution_count": 14,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "x0bYXViKxfss"
      },
      "source": [
        "Data Augmentation"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "964lrNQHG48P"
      },
      "source": [
        "train_datagenerator = ImageDataGenerator(\n",
        "        rescale=1. / 255,\n",
        "        featurewise_center=False,  \n",
        "        samplewise_center=False,  \n",
        "        featurewise_std_normalization=False,  \n",
        "        samplewise_std_normalization=False,  \n",
        "        rotation_range=40,  \n",
        "        zoom_range = 0.20,  \n",
        "        width_shift_range=0.10,  \n",
        "        height_shift_range=0.10,  \n",
        "        horizontal_flip=True,  \n",
        "        vertical_flip=False) \n",
        "\n",
        "test_datagenerator=ImageDataGenerator(\n",
        "        rescale=1. / 255\n",
        ")\n",
        "\n",
        "train_datagenerator.fit(X_train)\n",
        "test_datagenerator.fit(X_val)\n",
        "test_datagenerator.fit(testing_data)\n",
        "X_train=np.array(X_train)\n",
        "testing_data=np.array(testing_data)\n",
        "X_val=np.array(X_val)"
      ],
      "execution_count": 26,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "-vuYgkDIG48P",
        "outputId": "037bcee7-c9ac-4087-d315-0877ebb8c916"
      },
      "source": [
        "print(X_train.shape)\n",
        "print(y_train.shape)\n",
        "print(X_val.shape)\n",
        "print(y_val.shape)"
      ],
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "(291, 224, 224, 3)\n",
            "(291,)\n",
            "(73, 224, 224, 3)\n",
            "(73,)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Dj6QbG1UG48P"
      },
      "source": [
        "In below code we are loading *VGG16* weights for image classifier using transfer learning"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "wKKbwNnrG48P",
        "outputId": "498bb4a4-7211-4a0b-ad1e-971cb03a9133"
      },
      "source": [
        "# traing using transfer learning\n",
        "\n",
        "vggmodel =VGG16(weights='imagenet', include_top=False, input_shape = (224, 224, 3), pooling='max')\n",
        "\n",
        " # Print the model summary\n",
        "vggmodel.summary()"
      ],
      "execution_count": 27,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Model: \"vgg16\"\n",
            "_________________________________________________________________\n",
            "Layer (type)                 Output Shape              Param #   \n",
            "=================================================================\n",
            "input_2 (InputLayer)         [(None, 224, 224, 3)]     0         \n",
            "_________________________________________________________________\n",
            "block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792      \n",
            "_________________________________________________________________\n",
            "block1_conv2 (Conv2D)        (None, 224, 224, 64)      36928     \n",
            "_________________________________________________________________\n",
            "block1_pool (MaxPooling2D)   (None, 112, 112, 64)      0         \n",
            "_________________________________________________________________\n",
            "block2_conv1 (Conv2D)        (None, 112, 112, 128)     73856     \n",
            "_________________________________________________________________\n",
            "block2_conv2 (Conv2D)        (None, 112, 112, 128)     147584    \n",
            "_________________________________________________________________\n",
            "block2_pool (MaxPooling2D)   (None, 56, 56, 128)       0         \n",
            "_________________________________________________________________\n",
            "block3_conv1 (Conv2D)        (None, 56, 56, 256)       295168    \n",
            "_________________________________________________________________\n",
            "block3_conv2 (Conv2D)        (None, 56, 56, 256)       590080    \n",
            "_________________________________________________________________\n",
            "block3_conv3 (Conv2D)        (None, 56, 56, 256)       590080    \n",
            "_________________________________________________________________\n",
            "block3_pool (MaxPooling2D)   (None, 28, 28, 256)       0         \n",
            "_________________________________________________________________\n",
            "block4_conv1 (Conv2D)        (None, 28, 28, 512)       1180160   \n",
            "_________________________________________________________________\n",
            "block4_conv2 (Conv2D)        (None, 28, 28, 512)       2359808   \n",
            "_________________________________________________________________\n",
            "block4_conv3 (Conv2D)        (None, 28, 28, 512)       2359808   \n",
            "_________________________________________________________________\n",
            "block4_pool (MaxPooling2D)   (None, 14, 14, 512)       0         \n",
            "_________________________________________________________________\n",
            "block5_conv1 (Conv2D)        (None, 14, 14, 512)       2359808   \n",
            "_________________________________________________________________\n",
            "block5_conv2 (Conv2D)        (None, 14, 14, 512)       2359808   \n",
            "_________________________________________________________________\n",
            "block5_conv3 (Conv2D)        (None, 14, 14, 512)       2359808   \n",
            "_________________________________________________________________\n",
            "block5_pool (MaxPooling2D)   (None, 7, 7, 512)         0         \n",
            "_________________________________________________________________\n",
            "global_max_pooling2d_1 (Glob (None, 512)               0         \n",
            "=================================================================\n",
            "Total params: 14,714,688\n",
            "Trainable params: 14,714,688\n",
            "Non-trainable params: 0\n",
            "_________________________________________________________________\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "S_ypvJ76G48P"
      },
      "source": [
        "Using already trained model for our task and bulding 2 fully connected layer with *softmax* activation function"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "i4sXXFabG48Q"
      },
      "source": [
        "vggmodel.trainable = False\n",
        "model = Sequential([\n",
        "  vggmodel, \n",
        "  Dense(512, activation='relu'),\n",
        "  Dropout(0.05),\n",
        "  Dense(128, activation='relu'),\n",
        "  Dropout(0.05),\n",
        "  Dense(8, activation='softmax'),\n",
        "])"
      ],
      "execution_count": 28,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "1i_8FynsG48Q"
      },
      "source": [
        "\n",
        "reduce_learning_rate = ReduceLROnPlateau(monitor='loss',\n",
        "                                         factor=0.1,\n",
        "                                         patience=2,\n",
        "                                         cooldown=2,\n",
        "                                         min_lr=0.00001,\n",
        "                                         verbose=1)\n",
        "\n",
        "callbacks = [reduce_learning_rate]"
      ],
      "execution_count": 29,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gndi1QZcG48Q"
      },
      "source": [
        "In the below code we are compiling and traing our image data"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "k85fNYWCG48Q",
        "outputId": "40bdf1f4-5058-4175-facb-190b1a560061"
      },
      "source": [
        "model.compile( optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])\n",
        "history =model.fit(\n",
        "    train_datagenerator.flow(X_train, to_categorical(y_train,8), batch_size=16, shuffle = False),\n",
        "    validation_data=test_datagenerator.flow(X_val, to_categorical(y_val,8), batch_size=16, shuffle = False),\n",
        "    verbose=2,\n",
        "    epochs=12,\n",
        "    callbacks=callbacks\n",
        ")"
      ],
      "execution_count": 30,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Epoch 1/12\n",
            "19/19 - 3s - loss: 2.1630 - accuracy: 0.2165 - val_loss: 2.0480 - val_accuracy: 0.2192\n",
            "Epoch 2/12\n",
            "19/19 - 3s - loss: 1.6187 - accuracy: 0.4261 - val_loss: 1.7088 - val_accuracy: 0.3288\n",
            "Epoch 3/12\n",
            "19/19 - 3s - loss: 1.4267 - accuracy: 0.4742 - val_loss: 1.4886 - val_accuracy: 0.4658\n",
            "Epoch 4/12\n",
            "19/19 - 3s - loss: 1.2524 - accuracy: 0.5739 - val_loss: 1.5011 - val_accuracy: 0.3973\n",
            "Epoch 5/12\n",
            "19/19 - 3s - loss: 1.1173 - accuracy: 0.5773 - val_loss: 1.1588 - val_accuracy: 0.6027\n",
            "Epoch 6/12\n",
            "19/19 - 3s - loss: 1.0645 - accuracy: 0.6254 - val_loss: 1.1366 - val_accuracy: 0.5342\n",
            "Epoch 7/12\n",
            "19/19 - 3s - loss: 1.0402 - accuracy: 0.6392 - val_loss: 1.1028 - val_accuracy: 0.6164\n",
            "Epoch 8/12\n",
            "19/19 - 3s - loss: 0.9187 - accuracy: 0.6667 - val_loss: 1.0698 - val_accuracy: 0.5753\n",
            "Epoch 9/12\n",
            "19/19 - 3s - loss: 0.8418 - accuracy: 0.7216 - val_loss: 1.0479 - val_accuracy: 0.5890\n",
            "Epoch 10/12\n",
            "19/19 - 3s - loss: 0.7813 - accuracy: 0.7388 - val_loss: 1.1216 - val_accuracy: 0.6575\n",
            "Epoch 11/12\n",
            "19/19 - 3s - loss: 0.7802 - accuracy: 0.7423 - val_loss: 0.8320 - val_accuracy: 0.7123\n",
            "Epoch 12/12\n",
            "19/19 - 3s - loss: 0.5978 - accuracy: 0.7973 - val_loss: 0.7819 - val_accuracy: 0.7397\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 562
        },
        "id": "QoUAYQtyG48Q",
        "outputId": "0ab6ff60-758d-4f7a-e784-f645f423cc46"
      },
      "source": [
        "import matplotlib.image  as mpimg\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "acc      = history.history[ 'accuracy' ]\n",
        "val_acc  = history.history[ 'val_accuracy' ]\n",
        "loss     = history.history[ 'loss' ]\n",
        "val_loss = history.history['val_loss' ]\n",
        "\n",
        "epochs   = range(len(acc)) # Get number of epochs\n",
        "\n",
        "#------------------------------------------------\n",
        "# Plot training and validation accuracy per epoch\n",
        "#------------------------------------------------\n",
        "plt.plot( epochs, acc )\n",
        "plt.plot( epochs, val_acc )\n",
        "plt.title('Training and validation accuracy')\n",
        "plt.figure()\n",
        "\n",
        "#------------------------------------------------\n",
        "# Plot training and validation loss per epoch\n",
        "#------------------------------------------------\n",
        "plt.plot  ( epochs,     loss )\n",
        "plt.plot  ( epochs, val_loss )\n",
        "plt.title ('Training and validation loss'   )"
      ],
      "execution_count": 31,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "Text(0.5, 1.0, 'Training and validation loss')"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 31
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "[encoded data, 19712 characters]\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "[encoded data, 17780 characters]\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "i4RY0ARq_ecv"
      },
      "source": [
        "Calculating predictions"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "UsOIbOBbG48Q"
      },
      "source": [
        "labels = model.predict(testing_data)\n",
        "label = [np.argmax(i) for i in labels]\n",
        "target=le.inverse_transform(label)\n",
        "predictions = pd.DataFrame({ 'Image': test_fnames, 'target': target })\n",
        "predictions.to_csv('predictions.csv', index=False)"
      ],
      "execution_count": 32,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2lk_WodGQJrD"
      },
      "source": [
        "Accuracy on unseen data (test)"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WfgFP3r1OQmc",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "290fba54-0d2c-40a3-9ff4-286616457109"
      },
      "source": [
        "gold = pd.read_csv(\"gold_labels.csv\")\n",
        "predictions = pd.read_csv(\"predictions.csv\")\n",
        "gold = gold.sort_values('Image')\n",
        "predictions = predictions.sort_values('Image')\n",
        "labels=[\"kathak\", \"manipuri\", \"bharatanatyam\",\"kathakali\",\"mohiniyattam\",\"sattriya\",\"kuchipudi\",\"odissi\"]\n",
        "confusion = confusion_matrix(gold['target'], predictions['target'], labels)\n",
        "print(confusion)"
      ],
      "execution_count": 33,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[[ 0  0 15  6  0  0  2  0]\n",
            " [ 0  2  0  6  0  0  0  0]\n",
            " [ 0  0 10  6  0  0  3  0]\n",
            " [ 0  0  0 19  0  0  0  0]\n",
            " [ 0  0 10  1  6  0  2  0]\n",
            " [ 0  0  4  9  0  0  2  0]\n",
            " [ 0  0 11  6  0  0  7  1]\n",
            " [ 0  0  8  9  0  0  5  6]]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 467
        },
        "id": "rCdDr-_YGwi6",
        "outputId": "c930dee3-ecb8-4345-c60b-18f4e16c53fd"
      },
      "source": [
        "def plot_confusion_matrix(cm,\n",
        "                          target_names,\n",
        "                          title='Confusion matrix',\n",
        "                          cmap=None,\n",
        "                          normalize=True):\n",
        "    accuracy = np.trace(cm) / float(np.sum(cm))\n",
        "    misclass = 1 - accuracy\n",
        "\n",
        "    if cmap is None:\n",
        "        cmap = plt.get_cmap('Blues')\n",
        "\n",
        "    plt.figure(figsize=(8, 6))\n",
        "    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n",
        "    plt.title(title)\n",
        "    plt.colorbar()\n",
        "\n",
        "    if target_names is not None:\n",
        "        tick_marks = np.arange(len(target_names))\n",
        "        plt.xticks(tick_marks, target_names, rotation=45)\n",
        "        plt.yticks(tick_marks, target_names)\n",
        "\n",
        "    if normalize:\n",
        "        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n",
        "\n",
        "\n",
        "    thresh = cm.max() / 1.5 if normalize else cm.max() / 2\n",
        "    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n",
        "        if normalize:\n",
        "            plt.text(j, i, \"{:0.4f}\".format(cm[i, j]),\n",
        "                     horizontalalignment=\"center\",\n",
        "                     color=\"white\" if cm[i, j] > thresh else \"black\")\n",
        "        else:\n",
        "            plt.text(j, i, \"{:,}\".format(cm[i, j]),\n",
        "                     horizontalalignment=\"center\",\n",
        "                     color=\"white\" if cm[i, j] > thresh else \"black\")\n",
        "\n",
        "\n",
        "    plt.tight_layout()\n",
        "    plt.ylabel('True label')\n",
        "    plt.xlabel('Predicted label\\naccuracy={:0.4f}; misclass={:0.4f}'.format(accuracy, misclass))\n",
        "    plt.show()\n",
        "\n",
        "plot_confusion_matrix(confusion, labels, normalize=False)"
      ],
      "execution_count": 34,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "[encoded data, 38000 characters]\n",
            "text/plain": [
              "<Figure size 576x432 with 2 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "pfKdtRDmSeXS",
        "outputId": "32f58a91-af0e-4626-b5f6-d40a91aa477e"
      },
      "source": [
        "correct =0\n",
        "for i in range(8):\n",
        "  correct += confusion[i][i]\n",
        "accuracy = correct / target.shape[0]\n",
        "print(accuracy)"
      ],
      "execution_count": 35,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "0.32051282051282054\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jIITzGYFUBQd"
      },
      "source": [
        ""
      ],
      "execution_count": 25,
      "outputs": []
    }
  ]
}