{ "cells": [ { "cell_type": "markdown", "source": [ "## Download dataset and connect your Google drive\n", "for that you need to get kaggle.json file for [here](https://www.kaggle.com/settings/account) where you will see API section under which you will have option to ```\"Create New Token\"``` ,which will download a ```kaggle.json``` file, upload that file it working dir." ], "metadata": { "id": "TZ9ndnKCKnyQ" } }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "_YzUO8UV7HgP" }, "outputs": [], "source": [ "!pip install -q kaggle\n", "!mkdir -p ~/.kaggle\n", "!cp kaggle.json ~/.kaggle/\n", "!chmod 600 ~/.kaggle/kaggle.json\n", "!kaggle datasets download -d divaxshah/cities-all\n", "!unzip /content/cities-all.zip" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "9y543mK87Gif" }, "outputs": [], "source": [ "!pip install split-folders tensorflow[torch] seaborn numpy matplotlib" ] }, { "cell_type": "code", "source": [ "from google.colab import drive\n", "drive.mount('/content/drive')" ], "metadata": { "id": "CBecy2sZBMGY" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "tvrwZoW_7Gih" }, "source": [ "### **Importing of Necessary Libraries**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "x4OJYagW7Gii" }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "import numpy as np\n", "import pandas as pd\n", "import random\n", "import cv2\n", "import os\n", "import PIL\n", "import pathlib\n", "import splitfolders\n", "\n", "import tensorflow as tf\n", "from tensorflow import keras\n", "from tensorflow.keras import layers\n", "from tensorflow.keras.models import Sequential\n", "from keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau\n", "from keras.preprocessing.image import ImageDataGenerator\n", "from keras.applications.vgg16 import VGG16" ] }, { "cell_type": "markdown", "metadata": { "id": "jk3HfsKQ7Gij" }, "source": [ "### **Dataset Loading and Splitting**\n", "Split-folders library was used to split the dataset into three parts: Training set(70%), Validation set(15%), and Test set(15%)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "KAc3avxf7Gij" }, "outputs": [], "source": [ "base_ds = '/content/Citeisall'\n", "base_ds = pathlib.Path(base_ds)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "fDH51KsE7Gik", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "88652468-e628-44fe-91f6-f093a05649b8" }, "outputs": [ { "output_type": "stream", "name": "stderr", "text": [ "Copying files: 12500 files [00:13, 928.79 files/s]\n" ] } ], "source": [ "splitfolders.ratio(base_ds, output='/content/imgs', seed=123, ratio=(.7,.15,.15), group_prefix=None)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "WFsRGuU07Gik" }, "outputs": [], "source": [ "Ahmedabad = [fn for fn in os.listdir(f'{base_ds}/Ahmedabad') if fn.endswith('.jpg')]\n", "Delhi = [fn for fn in os.listdir(f'{base_ds}/Delhi') if fn.endswith('.jpg')]\n", "Kerala = [fn for fn in os.listdir(f'{base_ds}/Kerala') if fn.endswith('.jpg')]\n", "Kolkata = [fn for fn in os.listdir(f'{base_ds}/Kolkata') if fn.endswith('.jpg')]\n", "Mumbai = [fn for fn in os.listdir(f'{base_ds}/Mumabi') ]\n", "city = [Ahmedabad, Delhi, Kerala, Kolkata, Mumbai]\n", "city_classes = []\n", "for i in os.listdir('imgs/train'):\n", " city_classes+=[i]\n", "city_classes.sort()" ] }, { "cell_type": "markdown", "metadata": { "id": "zIOajVox7Gik" }, "source": [ "### **Dataset Exploration**\n", "It can be seen here the total number of images in the dataset, the number of classes, and how well the images from each variety is distributed" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "RKugur_t7Gil" }, "outputs": [], "source": [ "image_count = len(list(base_ds.glob('*/*.jpg')))\n", "print(f'Total images: {image_count}')\n", "print(f'Total number of classes: {len(city_classes)}')\n", "count = 0\n", "city_count = []\n", "for x in city_classes:\n", " print(f'Total {x} images: {len(city[count])}')\n", " city_count.append(len(city[count]))\n", " count += 1\n", "\n", "sns.set_style('darkgrid')\n", "sns.barplot(x=city_classes, y=city_count, palette=\"Blues_d\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "K-i3dnII7Gil" }, "source": [ "### Sample Images\n", "Each image from the dataset has a dimension of 250 by 250 and a color type of RGB" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "rBjHPfUL7Gil" }, "outputs": [], "source": [ "sample_img = cv2.imread('/content/imgs/test/Ahmedabad/Ahmedabad-Test (1).jpg')\n", "plt.imshow(sample_img)\n", "print(f'Image dimensions: {sample_img.shape}')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Yy6zeno07Gim" }, "outputs": [], "source": [ "def load_random_img(dir, label):\n", " plt.figure(figsize=(10,10))\n", " i=0\n", " for label in city_classes:\n", " i+=1\n", " plt.subplot(1, 5, i)\n", " file = random.choice(os.listdir(f'{dir}/{label}'))\n", " image_path = os.path.join(f'{dir}/{label}', file)\n", " img=cv2.imread(image_path)\n", " plt.title(label)\n", " plt.imshow(img)\n", " plt.grid(None)\n", " plt.axis('off')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Mejs17hg7Gim" }, "outputs": [], "source": [ "for i in range(3):\n", " load_random_img(base_ds, city_classes)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "4x9dpaIM7Gim" }, "outputs": [], "source": [ "batch_size = 128\n", "img_height, img_width = 175, 175\n", "input_shape = (img_height, img_width, 3)" ] }, { "cell_type": "markdown", "metadata": { "id": "lEiaPL5a7Gim" }, "source": [ "### **Data Pre-processing**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "eER-2oNF7Gin" }, "outputs": [], "source": [ "datagen = ImageDataGenerator(rescale=1./255)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "lWozskns7Gin" }, "outputs": [], "source": [ "train_ds = datagen.flow_from_directory(\n", " 'imgs/train',\n", " target_size = (img_height, img_width),\n", " batch_size = batch_size,\n", " subset = \"training\",\n", " class_mode='categorical')\n", "\n", "val_ds = datagen.flow_from_directory(\n", " 'imgs/val',\n", " target_size = (img_height, img_width),\n", " batch_size = batch_size,\n", " class_mode='categorical',\n", " shuffle=False)\n", "\n", "test_ds = datagen.flow_from_directory(\n", " 'imgs/test',\n", " target_size = (img_height, img_width),\n", " batch_size = batch_size,\n", " class_mode='categorical',\n", " shuffle=False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "F4Q9lfcU7Gin" }, "outputs": [], "source": [ "def plot_train_history(history):\n", " plt.figure(figsize=(15,5))\n", " plt.subplot(1,2,1)\n", " plt.plot(history.history['accuracy'])\n", " plt.plot(history.history['val_accuracy'])\n", " plt.title('Model accuracy')\n", " plt.ylabel('accuracy')\n", " plt.xlabel('epoch')\n", " plt.legend(['train', 'validation'], loc='upper left')\n", "\n", " plt.subplot(1,2,2)\n", " plt.plot(history.history['loss'])\n", " plt.plot(history.history['val_loss'])\n", " plt.title('Model loss')\n", " plt.ylabel('loss')\n", " plt.xlabel('epoch')\n", " plt.legend(['train', 'validation'], loc='upper left')\n", " plt.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "7AmkjAds7Gin" }, "source": [ "## **Vanilla CNN Model**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "mrzY1vc17Gin" }, "outputs": [], "source": [ "model_vanilla = tf.keras.Sequential([\n", " tf.keras.layers.Conv2D(32,(3,3), activation='relu', input_shape=input_shape),\n", " tf.keras.layers.BatchNormalization(),\n", " tf.keras.layers.Conv2D(32,(3,3),activation='relu',padding='same'),\n", " tf.keras.layers.BatchNormalization(axis = 3),\n", " tf.keras.layers.MaxPooling2D(pool_size=(2,2),padding='same'),\n", " tf.keras.layers.Dropout(0.3),\n", "\n", " tf.keras.layers.Conv2D(64,(3,3),activation='relu',padding='same'),\n", " tf.keras.layers.BatchNormalization(),\n", " tf.keras.layers.Conv2D(64,(3,3),activation='relu',padding='same'),\n", " tf.keras.layers.BatchNormalization(axis = 3),\n", " tf.keras.layers.MaxPooling2D(pool_size=(2,2),padding='same'),\n", " tf.keras.layers.Dropout(0.3),\n", "\n", " tf.keras.layers.Conv2D(128,(3,3),activation='relu',padding='same'),\n", " tf.keras.layers.BatchNormalization(),\n", " tf.keras.layers.Conv2D(128,(3,3),activation='relu',padding='same'),\n", " tf.keras.layers.BatchNormalization(axis = 3),\n", " tf.keras.layers.MaxPooling2D(pool_size=(2,2),padding='same'),\n", " tf.keras.layers.Dropout(0.5),\n", "\n", " tf.keras.layers.Flatten(),\n", " tf.keras.layers.Dense(512, activation='relu'),\n", " tf.keras.layers.BatchNormalization(),\n", " tf.keras.layers.Dropout(0.5),\n", " tf.keras.layers.Dense(128, activation='relu'),\n", " tf.keras.layers.Dropout(0.25),\n", " tf.keras.layers.Dense(5, activation='softmax')\n", "])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "U8KLpKJU7Gin" }, "outputs": [], "source": [ "model_vanilla.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n", "model_vanilla.summary()" ] }, { "cell_type": "markdown", "metadata": { "id": "uUBYpTCi7Gin" }, "source": [ "## **Callbacks**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "5FEvu8Lv7Gin" }, "outputs": [], "source": [ "models_dir = \"saved_models\"\n", "if not os.path.exists(models_dir):\n", " os.makedirs(models_dir)\n", "\n", "checkpointer = ModelCheckpoint(filepath='saved_models/model_vanilla.hdf5',\n", " monitor='val_accuracy', mode='max',\n", " verbose=1, save_best_only=True)\n", "early_stopping = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=3)\n", "reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2,patience=2, min_lr=0.001)\n", "callbacks=[early_stopping, reduce_lr, checkpointer]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "KcIjH0kt7Gin" }, "outputs": [], "source": [ "history1 = model_vanilla.fit(train_ds, epochs = 40, validation_data = val_ds, callbacks=callbacks)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "ZkstY19-7Gio" }, "outputs": [], "source": [ "model_vanilla.save(\"model1\")\n", "model_vanilla.load_weights('saved_models/model_vanilla.hdf5')\n", "plot_train_history(history1)" ] }, { "cell_type": "markdown", "metadata": { "id": "4AVhC3Gu7Gio" }, "source": [ "## **Model Evaluation of Vanilla CNN**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "jzx2cCef7Gio" }, "outputs": [], "source": [ "score1 = model_vanilla.evaluate(test_ds, verbose=1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "pSYggqLK7Gio" }, "outputs": [], "source": [ "from sklearn.metrics import classification_report, confusion_matrix\n", "\n", "Y_pred = model_vanilla.predict(test_ds)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "zd8-1pAC7Gio" }, "outputs": [], "source": [ "y_pred = np.argmax(Y_pred, axis=1)\n", "confusion_mtx = confusion_matrix(y_pred, test_ds.classes)\n", "f,ax = plt.subplots(figsize=(12, 12))\n", "sns.heatmap(confusion_mtx, annot=True,\n", " linewidths=0.01,\n", " linecolor=\"white\",\n", " fmt= '.1f',ax=ax,)\n", "sns.color_palette(\"rocket\", as_cmap=True)\n", "\n", "plt.xlabel(\"Predicted Label\")\n", "plt.ylabel(\"True Label\")\n", "ax.xaxis.set_ticklabels(test_ds.class_indices)\n", "ax.yaxis.set_ticklabels(city_classes)\n", "plt.title(\"Confusion Matrix\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "YE6j5ex97Gio" }, "outputs": [], "source": [ "report1 = classification_report(test_ds.classes, y_pred, target_names=city_classes, output_dict=True)\n", "df1 = pd.DataFrame(report1).transpose()\n", "df1" ] }, { "cell_type": "markdown", "metadata": { "id": "SS8QOBdy7Gio" }, "source": [ "## **Transfer Learning**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "0sbFu6VZ7Gio" }, "outputs": [], "source": [ "vgg16 = VGG16(weights=\"imagenet\", include_top=False, input_shape=input_shape)\n", "vgg16.trainable = False\n", "inputs = tf.keras.Input(input_shape)\n", "x = vgg16(inputs, training=False)\n", "x = tf.keras.layers.GlobalAveragePooling2D()(x)\n", "x = tf.keras.layers.Dense(1024, activation='relu')(x)\n", "x = tf.keras.layers.Dense(5, activation='softmax')(x)\n", "model_vgg16 = tf.keras.Model(inputs, x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "IrQTnBef7Gip" }, "outputs": [], "source": [ "model_vgg16.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n", "model_vgg16.summary()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "nMaw_y4y7Gip" }, "outputs": [], "source": [ "checkpointer = ModelCheckpoint(filepath='saved_models/model_vgg16.hdf5',\n", " monitor='val_accuracy', mode='max',\n", " verbose=1, save_best_only=True)\n", "early_stopping = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=3)\n", "reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2,patience=2, min_lr=0.001)\n", "callbacks=[early_stopping, reduce_lr, checkpointer]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "XscbiiWE7Gip" }, "outputs": [], "source": [ "history2 = model_vgg16.fit(train_ds, epochs = 40, validation_data = val_ds, callbacks=callbacks)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "toiVgYCR7Gip" }, "outputs": [], "source": [ "model_vgg16.load_weights('saved_models/model_vgg16.hdf5')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "46M_EVvE7Gip" }, "outputs": [], "source": [ "plot_train_history(history2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "PzhAvIEE7Gip" }, "outputs": [], "source": [ "score2 = model_vgg16.evaluate(test_ds, verbose=1)\n", "print(f'Model 1 Vanilla Loss: {score1[0]}, Accuracy: {score1[1]*100}')\n", "print(f'Model 2 VGG16 Loss: {score2[0]}, Accuracy: {score2[1]*100}')\n", "model_vgg16.save(\"model2\")" ] }, { "cell_type": "markdown", "metadata": { "id": "e1Jmu8wQ7Giq" }, "source": [ "## **Fine Tuning**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "IiEIjnKp7Giv" }, "outputs": [], "source": [ "vgg16.trainable = True\n", "model_vgg16.compile(optimizer=keras.optimizers.Adam(1e-5),\n", " loss='categorical_crossentropy', metrics=['accuracy'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "D52hK12o7Giv" }, "outputs": [], "source": [ "history3 = model_vgg16.fit(train_ds, epochs = 40, validation_data = val_ds, callbacks=callbacks)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "bpEvB7Ud7Giv" }, "outputs": [], "source": [ "model_vgg16.load_weights('saved_models/model_vgg16.hdf5')\n", "model_vgg16.save(\"model3\")" ] }, { "cell_type": "markdown", "metadata": { "id": "uYUBzEgZ7Giv" }, "source": [ "## **Final Evaluation**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "8qMXiAQg7Giv" }, "outputs": [], "source": [ "score3 = model_vgg16.evaluate(test_ds, verbose=1)\n", "print(f'Model 1 Vanilla Loss: {score1[0]}, Accuracy: {score1[1]*100}')\n", "print(f'Model 2 VGG16 Loss: {score2[0]}, Accuracy: {score2[1]*100}')\n", "print(f'Model 2 VGG16 Fine-tuned Loss: {score3[0]}, Accuracy: {score3[1]*100}')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "c-yIMsfC7Giv" }, "outputs": [], "source": [ "Y_pred = model_vgg16.predict(test_ds)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "h75tyWjY7Giv" }, "outputs": [], "source": [ "y_pred = np.argmax(Y_pred, axis=1)\n", "confusion_mtx = confusion_matrix(y_pred, test_ds.classes)\n", "f,ax = plt.subplots(figsize=(12, 12))\n", "sns.heatmap(confusion_mtx, annot=True,\n", " linewidths=0.01,\n", " linecolor=\"white\",\n", " fmt= '.1f',ax=ax,)\n", "sns.color_palette(\"rocket\", as_cmap=True)\n", "\n", "plt.xlabel(\"Predicted Label\")\n", "plt.ylabel(\"True Label\")\n", "ax.xaxis.set_ticklabels(test_ds.class_indices)\n", "ax.yaxis.set_ticklabels(city_classes)\n", "plt.title(\"Confusion Matrix\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "lT-5Hwdz7Giw" }, "outputs": [], "source": [ "report2 = classification_report(test_ds.classes, y_pred, target_names=city_classes, output_dict=True)\n", "df2 = pd.DataFrame(report1).transpose()\n", "df2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "8TBoFOlT7Giw" }, "outputs": [], "source": [ "plt.figure(figsize=(100, 100))\n", "x, label= train_ds.next()\n", "for i in range(25):\n", " plt.subplot(5, 5, i+1)\n", " plt.imshow(x[i])\n", " result = np.where(label[i]==1)\n", " predict = model_vgg16(tf.expand_dims(x[i], 0))\n", " score = tf.nn.softmax(predict[0])\n", " score_label = city_classes[np.argmax(score)]\n", " plt.title(f'Truth: {city_classes[result[0][0]]}\\nPrediction:{score_label}')\n", " plt.axis(False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "UlB0X2Bu-z8T" }, "outputs": [], "source": [ "model_vgg16.save(\"/content/drive/MyDrive/model\")\n", "# Assuming your model is named model_vgg16\n", "model_vgg16.save(\"/content/drive/MyDrive/tensorflow\", save_format='tf')\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Ui__qIcFG_IA", "outputId": "04f422be-7522-45e3-b386-e00bf351a4c8" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Found 1875 images belonging to 5 classes.\n", "59/59 [==============================] - 14s 182ms/step - loss: 1.4103 - accuracy: 0.6363\n", "Test loss: 1.4102574586868286\n", "Test accuracy: 0.6362666487693787\n" ] } ], "source": [ "test_datagen = ImageDataGenerator(rescale=1./255)\n", "test_generator = test_datagen.flow_from_directory(\n", " '/content/imgs/test',\n", " target_size=(175, 175),\n", " batch_size=32,\n", " class_mode='categorical'\n", ")\n", "\n", "test_loss, test_accuracy = model_vgg16.evaluate(test_generator, steps=len(test_generator))\n", "print('Test loss:', test_loss)\n", "print('Test accuracy:', test_accuracy)" ] }, { "cell_type": "markdown", "source": [ "## **Testing single image**" ], "metadata": { "id": "gM7karcDFUq3" } }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "zqrovHxOHj8o", "outputId": "9ddc9a80-c2a4-4526-c856-1146b884ce66" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:tensorflow:5 out of the last 19 calls to .predict_function at 0x7a21dd0d7eb0> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has reduce_retracing=True option that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for more details.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "1/1 [==============================] - 0s 440ms/step\n", "Predicted class: Kolkata\n", "Accuracy: 0.8562558\n" ] } ], "source": [ "# import tensorflow.keras as keras\n", "# from tensorflow.keras.models import load_model\n", "# from tensorflow.keras.preprocessing import image\n", "# import numpy as np\n", "\n", "# model = load_model('/content/model3')\n", "\n", "\n", "\n", "# # Load and preprocess the input image\n", "# img_path = '/content/Citeisall/Kolkata/Kolkata-Test (10).jpg'\n", "# img = image.load_img(img_path, target_size=(175,175))\n", "# img = image.img_to_array(img)\n", "# img = np.expand_dims(img, axis=0)\n", "# img = img / 255.0\n", "\n", "# # Make predictions on the input image\n", "# predictions = model.predict(img)\n", "# class_labels = ['Ahmedabad', 'Delhi', 'Kerala', 'Kolkata', 'Mumbai']\n", "\n", "# # Set the threshold for minimum accuracy\n", "# threshold = 0.0\n", "\n", "# # Get the predicted class label and accuracy\n", "# predicted_class_index = np.argmax(predictions)\n", "# predicted_class_label = class_labels[predicted_class_index]\n", "# accuracy = predictions[0][predicted_class_index]\n", "\n", "# # Check if accuracy is below the threshold for all classes\n", "# if all(accuracy < threshold for accuracy in predictions[0]):\n", "# print(\"This location is not in our database.\")\n", "# else:\n", "# print('Predicted class:', predicted_class_label)\n", "# print('Accuracy:', accuracy)\n" ] }, { "cell_type": "markdown", "source": [ "## **Visulization**\n", "\n", "---\n", "\n" ], "metadata": { "id": "QYj3LdqUFGn-" } }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "ekP5VUgYISA-" }, "outputs": [], "source": [ "# import numpy as np\n", "# import matplotlib.pyplot as plt\n", "# import seaborn as sns\n", "\n", "# # Sample data from the classification report you provided\n", "# labels = [\"Ahmedabad\", \"Delhi\", \"Kerala\", \"Kolkata\", \"Mumbai\"]\n", "# precision = [0.85, 0.60, 0.64, 0.58, 0.55]\n", "# recall = [0.84, 0.65, 0.66, 0.58, 0.49]\n", "# f1 = [0.85, 0.62, 0.65, 0.58, 0.52]\n", "\n", "# # Bar Plot\n", "# plt.figure(figsize=(10, 5))\n", "# barWidth = 0.25\n", "# r1 = np.arange(len(precision))\n", "# r2 = [x + barWidth for x in r1]\n", "# r3 = [x + barWidth for x in r2]\n", "# plt.bar(r1, precision, color='b', width=barWidth, edgecolor='grey', label='precision')\n", "# plt.bar(r2, recall, color='r', width=barWidth, edgecolor='grey', label='recall')\n", "# plt.bar(r3, f1, color='g', width=barWidth, edgecolor='grey', label='f1-score')\n", "# plt.xlabel('Cities', fontweight='bold')\n", "# plt.xticks([r + barWidth for r in range(len(precision))], labels)\n", "# plt.legend()\n", "# plt.show()\n", "\n", "# # Heatmap\n", "# df = {\n", "# 'precision': precision,\n", "# 'recall': recall,\n", "# 'f1-score': f1\n", "# }\n", "# plt.figure(figsize=(10, 5))\n", "# sns.heatmap([precision, recall, f1], yticklabels=[\"precision\", \"recall\", \"f1-score\"], xticklabels=labels, cmap=\"YlGnBu\", annot=True, fmt='.2g')\n", "# plt.show()\n", "\n", "# # Spider (Radar) Plot\n", "# angles = np.linspace(0, 2 * np.pi, len(labels), endpoint=False).tolist()\n", "# precision += precision[:1]\n", "# recall += recall[:1]\n", "# f1 += f1[:1]\n", "# angles += angles[:1]\n", "# plt.figure(figsize=(10, 5))\n", "# ax = plt.subplot(111, polar=True)\n", "# ax.fill(angles, precision, color='b', alpha=0.25)\n", "# ax.fill(angles, recall, color='r', alpha=0.25)\n", "# ax.fill(angles, f1, color='g', alpha=0.25)\n", "# ax.set_theta_offset(np.pi / 2)\n", "# ax.set_theta_direction(-1)\n", "# plt.xticks(angles[:-1], labels)\n", "# ax.set_rlabel_position(30)\n", "# plt.yticks([0.2, 0.4, 0.6, 0.8], [\"0.2\", \"0.4\", \"0.6\", \"0.8\"], color=\"grey\", size=12)\n", "# plt.ylim(0, 1)\n", "# ax.plot(angles, precision, color='b', linewidth=2, linestyle='solid', label='precision')\n", "# ax.plot(angles, recall, color='r', linewidth=2, linestyle='solid', label='recall')\n", "# ax.plot(angles, f1, color='g', linewidth=2, linestyle='solid', label='f1-score')\n", "# ax.fill(angles, precision, color='b', alpha=0.4)\n", "# ax.fill(angles, recall, color='r', alpha=0.4)\n", "# ax.fill(angles, f1, color='g', alpha=0.4)\n", "# plt.legend(loc=\"upper right\", bbox_to_anchor=(0.1, 0.1))\n", "# plt.show()\n" ] }, { "cell_type": "code", "source": [ "# Import necessary libraries\n", "import numpy as np\n", "from keras.models import load_model\n", "from keras.preprocessing.image import ImageDataGenerator\n", "from sklearn.metrics import classification_report\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "\n", "# Load the pre-trained model\n", "model = load_model('/content/drive/MyDrive/model.h5')\n", "\n", "# Preprocess the test data\n", "test_datagen = ImageDataGenerator(rescale=1./255) # Assuming you rescaled your images during training\n", "test_dir = '/content/imgs/test'\n", "test_generator = test_datagen.flow_from_directory(\n", " test_dir,\n", " target_size=(175, 175), # Adjust if you used a different input size during training\n", " batch_size=1,\n", " class_mode='categorical',\n", " shuffle=False\n", ")\n", "\n", "# Predict classes using the model\n", "predictions = model.predict(test_generator, steps=test_generator.n, verbose=1)\n", "predicted_classes = np.argmax(predictions, axis=1)\n", "\n", "# Get true labels and class labels\n", "true_classes = test_generator.classes\n", "class_labels = list(test_generator.class_indices.keys())\n", "\n", "# Generate the classification report\n", "report = classification_report(true_classes, predicted_classes, target_names=class_labels, output_dict=True)\n", "report_df = pd.DataFrame(report).transpose()\n", "\n", "# Plot the metrics in the report\n", "report_df[['precision', 'recall', 'f1-score']].drop(['accuracy', 'macro avg', 'weighted avg']).plot(kind='bar', figsize=(15, 7))\n", "plt.title('Classification Report Metrics')\n", "plt.ylabel('Score')\n", "plt.xticks(rotation=45)\n", "plt.ylim(0, 1)\n", "plt.grid(axis='y')\n", "plt.tight_layout()\n", "plt.show()\n", "\n", "# Import necessary libraries\n", "# import numpy as np\n", "# from keras.models import load_model\n", "# from keras.preprocessing.image import ImageDataGenerator\n", "# from sklearn.metrics import classification_report, confusion_matrix\n", "# import matplotlib.pyplot as plt\n", "# import seaborn as sns\n", "\n", "# # Load the pre-trained model\n", "# model = load_model('/content/drive/MyDrive/model.h5')\n", "\n", "# # Preprocess the test data\n", "# test_datagen = ImageDataGenerator(rescale=1./255) # Assuming you rescaled your images during training\n", "# test_dir = '/content/imgs/test'\n", "# test_generator = test_datagen.flow_from_directory(\n", "# test_dir,\n", "# target_size=(175, 175), # Adjust if you used a different input size during training\n", "# batch_size=1,\n", "# class_mode='categorical',\n", "# shuffle=False\n", "# )\n", "\n", "# # Predict classes using the model\n", "# predictions = model.predict(test_generator, steps=test_generator.n, verbose=1)\n", "# predicted_classes = np.argmax(predictions, axis=1)\n", "\n", "# # Get true labels and class labels\n", "# true_classes = test_generator.classes\n", "# class_labels = list(test_generator.class_indices.keys())\n", "\n", "# # Generate the classification report\n", "# report = classification_report(true_classes, predicted_classes, target_names=class_labels)\n", "# print(report)\n", "\n", "# # Generate the confusion matrix\n", "# confusion_mtx = confusion_matrix(true_classes, predicted_classes)\n", "\n", "# # Plot the heatmap using Seaborn\n", "# plt.figure(figsize=(10, 8))\n", "# sns.heatmap(confusion_mtx, annot=True, fmt='d', cmap='Blues',\n", "# xticklabels=class_labels,\n", "# yticklabels=class_labels)\n", "# plt.xlabel('Predicted Label')\n", "# plt.ylabel('True Label')\n", "# plt.title('Confusion Matrix')\n", "# plt.show()\n" ], "metadata": { "id": "naosYJjSFmYA" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [], "metadata": { "id": "pM9HS2OxE4Ej" }, "execution_count": null, "outputs": [] } ], "metadata": { "accelerator": "GPU", "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3", "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" } }, "nbformat": 4, "nbformat_minor": 0 }