{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":29762,"databundleVersionId":2541532,"sourceType":"competition"}],"dockerImageVersionId":30528,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"The code begins by setting up the necessary libraries required for data manipulation, image processing, and building a deep learning model. Notebook referenced from this user: https://www.kaggle.com/mrigendrachauhan\nOngoing Progress: Experimenting to find the best custom model architecture.","metadata":{"execution":{"iopub.status.busy":"2023-08-21T12:02:29.517148Z","iopub.execute_input":"2023-08-21T12:02:29.517474Z","iopub.status.idle":"2023-08-21T12:02:47.031807Z","shell.execute_reply.started":"2023-08-21T12:02:29.517445Z","shell.execute_reply":"2023-08-21T12:02:47.030533Z"}}},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport cv2\nimport tensorflow as tf\nfrom tensorflow.keras.applications import MobileNetV2\nfrom tensorflow.keras.layers import Dense, Dropout\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom sklearn.metrics import confusion_matrix\nimport seaborn as sns\nimport matplotlib.pyplot as plt","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:21:44.523177Z","iopub.execute_input":"2024-12-09T16:21:44.523512Z","iopub.status.idle":"2024-12-09T16:21:44.529096Z","shell.execute_reply.started":"2024-12-09T16:21:44.523487Z","shell.execute_reply":"2024-12-09T16:21:44.528168Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Loading the data**","metadata":{}},{"cell_type":"code","source":"traindf = pd.read_csv(\"../input/landmark-recognition-2021/train.csv\")","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:44.530917Z","iopub.execute_input":"2024-12-09T16:21:44.531177Z","iopub.status.idle":"2024-12-09T16:21:45.351723Z","shell.execute_reply.started":"2024-12-09T16:21:44.531157Z","shell.execute_reply":"2024-12-09T16:21:45.351035Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"traindf.head()","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:45.352664Z","iopub.execute_input":"2024-12-09T16:21:45.352907Z","iopub.status.idle":"2024-12-09T16:21:45.360558Z","shell.execute_reply.started":"2024-12-09T16:21:45.352888Z","shell.execute_reply":"2024-12-09T16:21:45.359781Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"traindf.shape # 1.5M Images","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:21:45.361587Z","iopub.execute_input":"2024-12-09T16:21:45.362134Z","iopub.status.idle":"2024-12-09T16:21:45.371574Z","shell.execute_reply.started":"2024-12-09T16:21:45.362102Z","shell.execute_reply":"2024-12-09T16:21:45.370880Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Extracting Limited(50) Unique Landmarks and Corresponding Image IDs**","metadata":{}},{"cell_type":"code","source":"landmark_unique = traindf['landmark_id'].unique()[0:50]\nimage_ids = []\nlabels = []\ntemp_labels = []\n\nfor i, id_ in enumerate(landmark_unique):\n    for iid in traindf['id'][traindf['landmark_id'] == id_]:\n        image_ids.append(iid)\n        labels.append(id_)\n        temp_labels.append(i)","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:45.373614Z","iopub.execute_input":"2024-12-09T16:21:45.373868Z","iopub.status.idle":"2024-12-09T16:21:45.477337Z","shell.execute_reply.started":"2024-12-09T16:21:45.373850Z","shell.execute_reply":"2024-12-09T16:21:45.476717Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Image Loading and Resizing for Landmark Recognition Dataset**","metadata":{}},{"cell_type":"code","source":"mainpath = '../input/landmark-recognition-2021/train'\nimages_pixels = []\n\nfor iid in image_ids:\n    first_dir = os.path.join(mainpath, iid[0])\n    second_dir = os.path.join(first_dir, iid[1])\n    third_dir = os.path.join(second_dir, iid[2])\n    finalpath = os.path.join(third_dir, iid + '.jpg')\n    \n    img_pix = cv2.imread(finalpath, 1)\n    images_pixels.append(cv2.resize(img_pix, (100, 100)))","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:45.478309Z","iopub.execute_input":"2024-12-09T16:21:45.478548Z","iopub.status.idle":"2024-12-09T16:21:52.696402Z","shell.execute_reply.started":"2024-12-09T16:21:45.478529Z","shell.execute_reply":"2024-12-09T16:21:52.695732Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_data = np.array(images_pixels) / 255.0\nY_data = to_categorical(temp_labels, num_classes=50)","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:52.697349Z","iopub.execute_input":"2024-12-09T16:21:52.697590Z","iopub.status.idle":"2024-12-09T16:21:52.800987Z","shell.execute_reply.started":"2024-12-09T16:21:52.697569Z","shell.execute_reply":"2024-12-09T16:21:52.800215Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# We are in the development phase and only care about training and validation for now.\n# We will create a separate test set later or use a different dataset for testing.\nX_train, X_val, Y_train, Y_val = train_test_split(X_data, Y_data, test_size=0.3, random_state=101)","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:52.802040Z","iopub.execute_input":"2024-12-09T16:21:52.802291Z","iopub.status.idle":"2024-12-09T16:21:52.890648Z","shell.execute_reply.started":"2024-12-09T16:21:52.802271Z","shell.execute_reply":"2024-12-09T16:21:52.889614Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(X_train.shape)\nprint(X_val.shape)\nprint(Y_train.shape)\nprint(Y_val.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:27:37.062728Z","iopub.execute_input":"2024-12-09T16:27:37.063063Z","iopub.status.idle":"2024-12-09T16:27:37.068332Z","shell.execute_reply.started":"2024-12-09T16:27:37.063031Z","shell.execute_reply":"2024-12-09T16:27:37.067415Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Displaying a Subset of Training Images with Labels**","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nplt.figure(figsize=(12, 8))\nfor i in range(16):\n    plt.subplot(4, 4, i + 1)\n    plt.imshow(X_train[i])\n    plt.title(f\"Label: {np.argmax(Y_train[i])}\")\n    plt.axis('off')\n    \nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:21:52.892369Z","iopub.execute_input":"2024-12-09T16:21:52.892726Z","iopub.status.idle":"2024-12-09T16:21:54.143504Z","shell.execute_reply.started":"2024-12-09T16:21:52.892694Z","shell.execute_reply":"2024-12-09T16:21:54.142711Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**MobileNetV2 Model Initialization**\n\nMobileNetV2 architecture, a lightweight deep learning model known for its efficiency in mobile vision applications, recognizes landmarks from images.","metadata":{}},{"cell_type":"code","source":"base_model = MobileNetV2(input_shape=(100,100,3), include_top=False, weights='imagenet', pooling='avg')\nbase_model.trainable = False # Feature extractor is freezed, only newly added layers will be trained","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:54.144710Z","iopub.execute_input":"2024-12-09T16:21:54.145279Z","iopub.status.idle":"2024-12-09T16:21:59.379223Z","shell.execute_reply.started":"2024-12-09T16:21:54.145244Z","shell.execute_reply":"2024-12-09T16:21:59.378283Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Other Model Test**","metadata":{}},{"cell_type":"code","source":"pretrained_model = tf.keras.applications.DenseNet201(input_shape=(100,100,3),\n                                                      include_top=False,\n                                                      weights='imagenet',\n                                                      pooling='avg')\npretrained_model.trainable = False","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:58:25.961640Z","iopub.execute_input":"2024-12-09T16:58:25.962007Z","iopub.status.idle":"2024-12-09T16:58:31.223981Z","shell.execute_reply.started":"2024-12-09T16:58:25.961982Z","shell.execute_reply":"2024-12-09T16:58:31.222971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"inputs = pretrained_model.input\ndrop_layer = tf.keras.layers.Dropout(0.25)(pretrained_model.output)\nx_layer = tf.keras.layers.Dense(512, activation='relu')(drop_layer)\nx_layer1 = tf.keras.layers.Dense(128, activation='relu')(x_layer)\ndrop_layer1 = tf.keras.layers.Dropout(0.20)(x_layer1)\noutputs = tf.keras.layers.Dense(50, activation='softmax')(drop_layer1)\n\n\nmodel2 = tf.keras.Model(inputs=inputs, outputs=outputs)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:59:19.415505Z","iopub.execute_input":"2024-12-09T16:59:19.415836Z","iopub.status.idle":"2024-12-09T16:59:19.485437Z","shell.execute_reply.started":"2024-12-09T16:59:19.415811Z","shell.execute_reply":"2024-12-09T16:59:19.484819Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# model2.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T17:00:19.121829Z","iopub.execute_input":"2024-12-09T17:00:19.122727Z","iopub.status.idle":"2024-12-09T17:00:19.126268Z","shell.execute_reply.started":"2024-12-09T17:00:19.122662Z","shell.execute_reply":"2024-12-09T17:00:19.125383Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)\nmodel2.compile(optimizer=optimizer,loss='categorical_crossentropy',metrics=['acc'])\nhistory = model2.fit(datagen.flow(X_train,Y_train,batch_size=32),validation_data=(X_val,Y_val),epochs=30)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T17:00:31.909845Z","iopub.execute_input":"2024-12-09T17:00:31.910161Z","iopub.status.idle":"2024-12-09T17:02:00.383859Z","shell.execute_reply.started":"2024-12-09T17:00:31.910136Z","shell.execute_reply":"2024-12-09T17:02:00.383034Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Adding Custom Layers to MobileV2 architecture**","metadata":{}},{"cell_type":"code","source":"x = base_model.output\nx = Dropout(0.25)(x)\nx = Dense(128, activation='relu')(x)\npredictions = Dense(50, activation='softmax')(x)","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:59.380458Z","iopub.execute_input":"2024-12-09T16:21:59.380817Z","iopub.status.idle":"2024-12-09T16:21:59.417154Z","shell.execute_reply.started":"2024-12-09T16:21:59.380786Z","shell.execute_reply":"2024-12-09T16:21:59.416504Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Compiling the Landmark Recognition Model**","metadata":{}},{"cell_type":"code","source":"model = Model(inputs=base_model.input, outputs=predictions)","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:59.418202Z","iopub.execute_input":"2024-12-09T16:21:59.418510Z","iopub.status.idle":"2024-12-09T16:21:59.432064Z","shell.execute_reply.started":"2024-12-09T16:21:59.418482Z","shell.execute_reply":"2024-12-09T16:21:59.431356Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"optimizer = Adam(learning_rate=0.001)\nmodel.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['acc'])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:59.433206Z","iopub.execute_input":"2024-12-09T16:21:59.433516Z","iopub.status.idle":"2024-12-09T16:21:59.450568Z","shell.execute_reply.started":"2024-12-09T16:21:59.433489Z","shell.execute_reply":"2024-12-09T16:21:59.449981Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Image Data Augmentation Configuration**","metadata":{}},{"cell_type":"code","source":"datagen = ImageDataGenerator(horizontal_flip=False,\n                             vertical_flip=False,\n                             rotation_range=0,\n                             zoom_range=0.2,\n                             width_shift_range=0,\n                             height_shift_range=0,\n                             shear_range=0,\n                             fill_mode=\"nearest\")","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:59.453108Z","iopub.execute_input":"2024-12-09T16:21:59.453343Z","iopub.status.idle":"2024-12-09T16:21:59.457503Z","shell.execute_reply.started":"2024-12-09T16:21:59.453324Z","shell.execute_reply":"2024-12-09T16:21:59.456637Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Training the Landmark Recognition Model with Data Augmentation**","metadata":{}},{"cell_type":"code","source":"history = model.fit(datagen.flow(X_train, Y_train, batch_size=32),\n                    validation_data=(X_val, Y_val),\n                    epochs=30)","metadata":{"execution":{"iopub.status.busy":"2024-12-09T16:21:59.458634Z","iopub.execute_input":"2024-12-09T16:21:59.458949Z","iopub.status.idle":"2024-12-09T16:23:08.179232Z","shell.execute_reply.started":"2024-12-09T16:21:59.458922Z","shell.execute_reply":"2024-12-09T16:23:08.178354Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred = model.predict(X_val) # Make predictions on X_val data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:23:08.180532Z","iopub.execute_input":"2024-12-09T16:23:08.181379Z","iopub.status.idle":"2024-12-09T16:23:09.164913Z","shell.execute_reply.started":"2024-12-09T16:23:08.181354Z","shell.execute_reply":"2024-12-09T16:23:09.164054Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Y_val.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:23:09.166209Z","iopub.execute_input":"2024-12-09T16:23:09.167062Z","iopub.status.idle":"2024-12-09T16:23:09.172125Z","shell.execute_reply.started":"2024-12-09T16:23:09.167036Z","shell.execute_reply":"2024-12-09T16:23:09.171141Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Convert Y_val (one-hot) to class indices\ny_true = np.argmax(Y_val, axis=1) # Derived from Y_val\n\n# The raw predictions (probabilities) from the model\ny_pred_classes = np.argmax(y_pred, axis=1)\n\n# Ensure y_pred_classes is already in class indices format\nprint(\"y_true shape:\", y_true.shape)\nprint(\"y_pred_classes shape:\", y_pred_classes.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:26:18.615074Z","iopub.execute_input":"2024-12-09T16:26:18.615921Z","iopub.status.idle":"2024-12-09T16:26:18.622330Z","shell.execute_reply.started":"2024-12-09T16:26:18.615881Z","shell.execute_reply":"2024-12-09T16:26:18.621251Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Compute confusion matrix\ncm = confusion_matrix(y_true, y_pred_classes)\n\n# Print or visualize the confusion matrix\nprint(\"Confusion Matrix:\\n\", cm)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:26:21.307231Z","iopub.execute_input":"2024-12-09T16:26:21.307576Z","iopub.status.idle":"2024-12-09T16:26:21.316131Z","shell.execute_reply.started":"2024-12-09T16:26:21.307548Z","shell.execute_reply":"2024-12-09T16:26:21.315162Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Plot confusion matrix as a heatmap\nplt.figure(figsize=(10, 8))\nsns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=True, yticklabels=True)\n\n# Add labels and title\nplt.xlabel('Predicted Labels')\nplt.ylabel('True Labels')\nplt.title('Confusion Matrix Heatmap')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:26:31.713348Z","iopub.execute_input":"2024-12-09T16:26:31.713999Z","iopub.status.idle":"2024-12-09T16:26:35.552397Z","shell.execute_reply.started":"2024-12-09T16:26:31.713968Z","shell.execute_reply":"2024-12-09T16:26:35.551526Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Initialize arrays to store metrics for each class\nnum_classes = cm.shape[0]  # Number of classes (50 in this case)\nTP = []\nTN = []\nFP = []\nFN = []\n\n# Calculate metrics for each class\nfor i in range(num_classes):\n    tp = cm[i, i]  # True Positives\n    fp = cm[:, i].sum() - tp  # False Positives\n    fn = cm[i, :].sum() - tp  # False Negatives\n    tn = cm.sum() - (tp + fp + fn)  # True Negatives\n\n    # Append to lists\n    TP.append(tp)\n    TN.append(tn)\n    FP.append(fp)\n    FN.append(fn)\n\n# Convert to arrays for easier handling if needed\nTP = np.array(TP)\nTN = np.array(TN)\nFP = np.array(FP)\nFN = np.array(FN)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:26:44.009895Z","iopub.execute_input":"2024-12-09T16:26:44.010219Z","iopub.status.idle":"2024-12-09T16:26:44.017414Z","shell.execute_reply.started":"2024-12-09T16:26:44.010191Z","shell.execute_reply":"2024-12-09T16:26:44.016427Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Display the metrics for each class\nfor i in range(num_classes):\n    print(f\"Class {i}: TP={TP[i]}, TN={TN[i]}, FP={FP[i]}, FN={FN[i]}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:26:48.253972Z","iopub.execute_input":"2024-12-09T16:26:48.254561Z","iopub.status.idle":"2024-12-09T16:26:48.259932Z","shell.execute_reply.started":"2024-12-09T16:26:48.254531Z","shell.execute_reply":"2024-12-09T16:26:48.258918Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Model Visualization**","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Plotting training and validation accuracy\nplt.figure(figsize=(12, 4))\nplt.subplot(1, 2, 1)\nplt.plot(history.history['acc'], label='Training Accuracy')\nplt.plot(history.history['val_acc'], label='Validation Accuracy')\nplt.legend()\nplt.title('Training and Validation Accuracy')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:26:50.743491Z","iopub.execute_input":"2024-12-09T16:26:50.744095Z","iopub.status.idle":"2024-12-09T16:26:50.971930Z","shell.execute_reply.started":"2024-12-09T16:26:50.744062Z","shell.execute_reply":"2024-12-09T16:26:50.971086Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Plotting training and validation loss\nplt.subplot(1, 2, 2)\nplt.plot(history.history['loss'], label='Training Loss')\nplt.plot(history.history['val_loss'], label='Validation Loss')\nplt.legend()\nplt.title('Training and Validation Loss')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T16:26:53.141436Z","iopub.execute_input":"2024-12-09T16:26:53.141785Z","iopub.status.idle":"2024-12-09T16:26:53.419474Z","shell.execute_reply.started":"2024-12-09T16:26:53.141759Z","shell.execute_reply":"2024-12-09T16:26:53.418640Z"}},"outputs":[],"execution_count":null}]}