{"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":"gpu","dataSources":[{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"},{"sourceId":11161869,"sourceType":"datasetVersion","datasetId":6964922},{"sourceId":11175548,"sourceType":"datasetVersion","datasetId":6974946}],"dockerImageVersionId":30919,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom tensorflow.keras.applications import VGG16\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom sklearn.metrics import classification_report, confusion_matrix\nfrom sklearn.model_selection import train_test_split\n\n# Define Constants\nIMG_SIZE = 224\nBATCH_SIZE = 32\n\n# Kaggle APTOS 2019 Dataset Paths\nAPTOS_DATASET_DIR = \"/kaggle/input/aptos2019-blindness-detection\"\nAPTOS_CSV = os.path.join(APTOS_DATASET_DIR, \"train.csv\")\nAPTOS_IMAGES_DIR = os.path.join(APTOS_DATASET_DIR, \"train_images\")\n\n# Your Custom Dataset Paths\nMY_DATASET_DIR = \"/kaggle/input/mydataset\"  # Update with your dataset path\nMY_CSV = os.path.join(MY_DATASET_DIR, \"gan_test_csv.csv\")\nMY_IMAGES_DIR = os.path.join(MY_DATASET_DIR, \"generated_images\")\n\n# Validate Paths\nassert os.path.exists(APTOS_DATASET_DIR), f\"❌ Kaggle dataset not found: {APTOS_DATASET_DIR}\"\nassert os.path.exists(APTOS_CSV), f\"❌ Kaggle CSV not found: {APTOS_CSV}\"\nassert os.path.exists(APTOS_IMAGES_DIR), f\"❌ Kaggle image directory not found: {APTOS_IMAGES_DIR}\"\nassert os.path.exists(MY_DATASET_DIR), f\"❌ Custom dataset not found: {MY_DATASET_DIR}\"\nassert os.path.exists(MY_CSV), f\"❌ Custom CSV not found: {MY_CSV}\"\nassert os.path.exists(MY_IMAGES_DIR), f\"❌ Custom image directory not found: {MY_IMAGES_DIR}\"\n\n# Load CSV Files\naptos_df = pd.read_csv(APTOS_CSV)\nmy_df = pd.read_csv(MY_CSV)\n\n# Ensure image filenames have .png extension\naptos_df[\"id_code\"] = aptos_df[\"id_code\"].astype(str) + \".png\"\nmy_df[\"id_code\"] = my_df[\"id_code\"].astype(str) + \".png\"\n\n# Verify that all image files exist\naptos_images = set(os.listdir(APTOS_IMAGES_DIR))\nmy_images = set(os.listdir(MY_IMAGES_DIR))\n\naptos_df = aptos_df[aptos_df[\"id_code\"].isin(aptos_images)]\nmy_df = my_df[my_df[\"id_code\"].isin(my_images)]\n\n# Merge Both Datasets\ntrain_df = pd.concat([aptos_df, my_df], ignore_index=True)\n\n# Convert labels to string format\ntrain_df[\"diagnosis\"] = train_df[\"diagnosis\"].astype(str)\n\n# Split Data into Training & Validation (Stratified)\ntrain_df, val_df = train_test_split(train_df, test_size=0.2, random_state=42, stratify=train_df[\"diagnosis\"])\n\n# Data Augmentation & Preprocessing\ndata_gen = ImageDataGenerator(\n    rescale=1.0 / 255.0,\n    rotation_range=20,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True\n)\nval_gen = ImageDataGenerator(rescale=1.0 / 255.0)\n\n# Custom Generator to Handle Multiple Image Directories\nclass MultiDirectoryDataGenerator(tf.keras.utils.Sequence):\n    def __init__(self, dataframe, batch_size, mode=\"train\"):\n        self.dataframe = dataframe\n        self.batch_size = batch_size\n        self.mode = mode\n        self.indices = np.arange(len(self.dataframe))\n    \n    def __len__(self):\n        return int(np.ceil(len(self.dataframe) / self.batch_size))\n    \n    def __getitem__(self, index):\n        batch_indices = self.indices[index * self.batch_size:(index + 1) * self.batch_size]\n        batch_data = self.dataframe.iloc[batch_indices]\n        \n        images = []\n        labels = []\n        \n        for _, row in batch_data.iterrows():\n            img_path = os.path.join(APTOS_IMAGES_DIR, row[\"id_code\"])\n            if not os.path.exists(img_path):  # If not in Kaggle dataset, check your dataset\n                img_path = os.path.join(MY_IMAGES_DIR, row[\"id_code\"])\n            \n            img = tf.keras.preprocessing.image.load_img(img_path, target_size=(IMG_SIZE, IMG_SIZE))\n            img = tf.keras.preprocessing.image.img_to_array(img) / 255.0\n            \n            images.append(img)\n            labels.append(int(row[\"diagnosis\"]))\n        \n        return np.array(images), np.array(labels)\n\n# Use the custom generator\ntrain_gen = MultiDirectoryDataGenerator(train_df, BATCH_SIZE, mode=\"train\")\nval_gen = MultiDirectoryDataGenerator(val_df, BATCH_SIZE, mode=\"val\")\n\n# Load VGG16 Model (Transfer Learning)\nbase_model = VGG16(weights='imagenet', include_top=False, input_shape=(IMG_SIZE, IMG_SIZE, 3))\nbase_model.trainable = True  # Fine-tuning enabled\n\n# Define Model\nmodel = tf.keras.Sequential([\n    base_model,\n    tf.keras.layers.GlobalAveragePooling2D(),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(128, activation='relu'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(5, activation='softmax')  # 5 classes (0–4 for DR severity)\n])\n\n# Compile Model\nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy']\n)\n\n# Define Callbacks\nmodel_checkpoint = tf.keras.callbacks.ModelCheckpoint(\n    \"vgg16_best_model.keras\",\n    monitor='val_loss',\n    save_best_only=True,\n    verbose=1\n)\nearly_stopping = tf.keras.callbacks.EarlyStopping(\n    monitor='val_loss',\n    patience=5,\n    restore_best_weights=True\n)\n\n# Train the Model\nhistory = model.fit(\n    train_gen,\n    validation_data=val_gen,\n    epochs=14,\n    steps_per_epoch=len(train_gen),\n    validation_steps=len(val_gen),\n    callbacks=[model_checkpoint, early_stopping]\n)\n\n# Save Final Model\nmodel.save(\"vgg16_finetuned.keras\")\n\n# Evaluate Model\nval_loss, val_accuracy = model.evaluate(val_gen)\nprint(f\"Validation Loss: {val_loss:.4f}, Validation Accuracy: {val_accuracy:.4f}\")\n\n# Get Predictions\ny_true = val_df[\"diagnosis\"].astype(int).values\ny_pred = model.predict(val_gen)\ny_pred_classes = np.argmax(y_pred, axis=1)\n\n# Classification Report\nprint(\"Classification Report:\")\nprint(classification_report(y_true, y_pred_classes))\n\n# Confusion Matrix\nconf_matrix = confusion_matrix(y_true, y_pred_classes)\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt=\"d\", cmap=\"Blues\", xticklabels=range(5), yticklabels=range(5))\nplt.xlabel(\"Predicted\")\nplt.ylabel(\"True\")\nplt.title(\"Confusion Matrix\")\nplt.show()\n\n# Plot Loss and Accuracy\nfig, ax = plt.subplots(1, 2, figsize=(12, 5))\n\n# Loss plot\nax[0].plot(history.history['loss'], label='Train Loss')\nax[0].plot(history.history['val_loss'], label='Val Loss')\nax[0].set_xlabel(\"Epochs\")\nax[0].set_ylabel(\"Loss\")\nax[0].set_title(\"Loss vs Epochs\")\nax[0].legend()\n\n# Accuracy plot\nax[1].plot(history.history['accuracy'], label='Train Accuracy')\nax[1].plot(history.history['val_accuracy'], label='Val Accuracy')\nax[1].set_xlabel(\"Epochs\")\nax[1].set_ylabel(\"Accuracy\")\nax[1].set_title(\"Accuracy vs Epochs\")\nax[1].legend()\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-26T13:16:13.430882Z","iopub.execute_input":"2025-03-26T13:16:13.431207Z","iopub.status.idle":"2025-03-26T14:02:06.986968Z","shell.execute_reply.started":"2025-03-26T13:16:13.431177Z","shell.execute_reply":"2025-03-26T14:02:06.986096Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Training Accuracy\ntrain_loss, train_accuracy = model.evaluate(train_gen)\nprint(f\"Recalculated Training Accuracy: {train_accuracy:.4f}\")\n\n# Validation Accuracy\nval_loss, val_accuracy = model.evaluate(val_gen)\nprint(f\"Recalculated Validation Accuracy: {val_accuracy:.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-26T14:15:27.855066Z","iopub.execute_input":"2025-03-26T14:15:27.855401Z","iopub.status.idle":"2025-03-26T14:21:21.798987Z","shell.execute_reply.started":"2025-03-26T14:15:27.855372Z","shell.execute_reply":"2025-03-26T14:21:21.798119Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom tensorflow.keras.applications import VGG16\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom sklearn.metrics import classification_report, confusion_matrix\nfrom sklearn.model_selection import train_test_split\n\n# Define constants\nIMG_SIZE = 224\nBATCH_SIZE = 32\nDATASET_DIR = \"/kaggle/input/aptos2019-blindness-detection\"\nTRAIN_CSV = os.path.join(DATASET_DIR, \"train.csv\")\nTRAIN_IMAGES_DIR = os.path.join(DATASET_DIR, \"train_images\")\n\n# Validate dataset paths\nassert os.path.exists(DATASET_DIR), f\"❌ Dataset directory not found: {DATASET_DIR}\"\nassert os.path.exists(TRAIN_CSV), f\"❌ CSV file not found: {TRAIN_CSV}\"\nassert os.path.exists(TRAIN_IMAGES_DIR), f\"❌ Image directory not found: {TRAIN_IMAGES_DIR}\"\n\n# Load train.csv\ntrain_df = pd.read_csv(TRAIN_CSV)\n\n# Ensure image filenames have .png extension\ntrain_df[\"id_code\"] = train_df[\"id_code\"].astype(str) + \".png\"\n\n# Verify that all image files exist\nall_image_files = set(os.listdir(TRAIN_IMAGES_DIR))  # List all images in directory\ntrain_df = train_df[train_df[\"id_code\"].isin(all_image_files)]  # Keep only existing images\n\nif train_df.empty:\n    raise ValueError(\"❌ No valid image filenames found in the dataset. Check filenames and dataset directory.\")\n\n# Convert labels to string format for flow_from_dataframe()\ntrain_df[\"diagnosis\"] = train_df[\"diagnosis\"].astype(str)\n\n# Split data into training and validation sets (stratified)\ntrain_df, val_df = train_test_split(train_df, test_size=0.2, random_state=42, stratify=train_df[\"diagnosis\"])\n\n# Data Augmentation & Preprocessing\ndata_gen = ImageDataGenerator(\n    rescale=1.0 / 255.0,\n    rotation_range=20,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True\n)\nval_gen = ImageDataGenerator(rescale=1.0 / 255.0)\n\n# Create Data Generators\ntrain_gen = data_gen.flow_from_dataframe(\n    dataframe=train_df,\n    directory=TRAIN_IMAGES_DIR,\n    x_col=\"id_code\",\n    y_col=\"diagnosis\",\n    target_size=(IMG_SIZE, IMG_SIZE),\n    batch_size=BATCH_SIZE,\n    class_mode='sparse'\n)\nval_gen = val_gen.flow_from_dataframe(\n    dataframe=val_df,\n    directory=TRAIN_IMAGES_DIR,\n    x_col=\"id_code\",\n    y_col=\"diagnosis\",\n    target_size=(IMG_SIZE, IMG_SIZE),\n    batch_size=BATCH_SIZE,\n    class_mode='sparse',\n    shuffle=False\n)\n\n# Load VGG16 Model (Transfer Learning)\nbase_model = VGG16(weights='imagenet', include_top=False, input_shape=(IMG_SIZE, IMG_SIZE, 3))\nbase_model.trainable = True  # Fine-tuning enabled\n\n# Define Model\nmodel = tf.keras.Sequential([\n    base_model,\n    tf.keras.layers.GlobalAveragePooling2D(),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(128, activation='relu'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(5, activation='softmax')  # 5 classes (0–4 for DR severity)\n])\n\n# Compile Model\nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy']\n)\n\n# Define Callbacks\nmodel_checkpoint = tf.keras.callbacks.ModelCheckpoint(\n    \"vgg16_best_model.keras\",  # ✅ Use .keras instead of .h5\n    monitor='val_loss',\n    save_best_only=True,\n    verbose=1\n)\nearly_stopping = tf.keras.callbacks.EarlyStopping(\n    monitor='val_loss',\n    patience=5,  # Stops training if no improvement for 5 epochs\n    restore_best_weights=True\n)\n\n# Train the Model\nhistory = model.fit(\n    train_gen,\n    validation_data=val_gen,\n    epochs=14,\n    steps_per_epoch=train_gen.samples // BATCH_SIZE,\n    validation_steps=val_gen.samples // BATCH_SIZE,\n    callbacks=[model_checkpoint, early_stopping]  # ✅ Callbacks added\n)\n\n# Save Final Model\nmodel.save(\"vgg16_finetuned.keras\")\n\n# Evaluate Model\nval_loss, val_accuracy = model.evaluate(val_gen)\nprint(f\"Validation Loss: {val_loss:.4f}, Validation Accuracy: {val_accuracy:.4f}\")\n\n# Get Predictions\ny_true = val_df[\"diagnosis\"].astype(int).values\ny_pred = model.predict(val_gen)\ny_pred_classes = np.argmax(y_pred, axis=1)\n\n# Classification Report\nprint(\"Classification Report:\")\nprint(classification_report(y_true, y_pred_classes))\n\n# Confusion Matrix\nconf_matrix = confusion_matrix(y_true, y_pred_classes)\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt=\"d\", cmap=\"Blues\", xticklabels=range(5), yticklabels=range(5))\nplt.xlabel(\"Predicted\")\nplt.ylabel(\"True\")\nplt.title(\"Confusion Matrix\")\nplt.show()\n\n# Plot Loss and Accuracy\nfig, ax = plt.subplots(1, 2, figsize=(12, 5))\n\n# Loss plot\nax[0].plot(history.history['loss'], label='Train Loss')\nax[0].plot(history.history['val_loss'], label='Val Loss')\nax[0].set_xlabel(\"Epochs\")\nax[0].set_ylabel(\"Loss\")\nax[0].set_title(\"Loss vs Epochs\")\nax[0].legend()\n\n# Accuracy plot\nax[1].plot(history.history['accuracy'], label='Train Accuracy')\nax[1].plot(history.history['val_accuracy'], label='Val Accuracy')\nax[1].set_xlabel(\"Epochs\")\nax[1].set_ylabel(\"Accuracy\")\nax[1].set_title(\"Accuracy vs Epochs\")\nax[1].legend()\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-26T14:24:53.977905Z","iopub.execute_input":"2025-03-26T14:24:53.978260Z","execution_failed":"2025-03-26T15:22:55.952Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom tensorflow.keras.applications import VGG16\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom sklearn.metrics import classification_report, confusion_matrix\nfrom sklearn.model_selection import train_test_split\n\n# Define Constants\nIMG_SIZE = 224\nBATCH_SIZE = 32\n\n# Kaggle APTOS 2019 Dataset Paths\nAPTOS_DATASET_DIR = \"/kaggle/input/aptos2019-blindness-detection\"\nAPTOS_CSV = os.path.join(APTOS_DATASET_DIR, \"train.csv\")\nAPTOS_IMAGES_DIR = os.path.join(APTOS_DATASET_DIR, \"train_images\")\n\n# Your Custom Dataset Paths\nMY_DATASET_DIR = \"/kaggle/input/mydataset\"  # Update with your dataset path\nMY_CSV = \"/kaggle/input/vishal-images/vishal_images.csv\"\nMY_IMAGES_DIR = os.path.join(MY_DATASET_DIR, \"generated_images\")\n\n# Validate Paths\nassert os.path.exists(APTOS_DATASET_DIR), f\"❌ Kaggle dataset not found: {APTOS_DATASET_DIR}\"\nassert os.path.exists(APTOS_CSV), f\"❌ Kaggle CSV not found: {APTOS_CSV}\"\nassert os.path.exists(APTOS_IMAGES_DIR), f\"❌ Kaggle image directory not found: {APTOS_IMAGES_DIR}\"\nassert os.path.exists(MY_DATASET_DIR), f\"❌ Custom dataset not found: {MY_DATASET_DIR}\"\nassert os.path.exists(MY_CSV), f\"❌ Custom CSV not found: {MY_CSV}\"\nassert os.path.exists(MY_IMAGES_DIR), f\"❌ Custom image directory not found: {MY_IMAGES_DIR}\"\n\n# Load CSV Files\naptos_df = pd.read_csv(APTOS_CSV)\nmy_df = pd.read_csv(MY_CSV)\n\n# Ensure image filenames have .png extension\naptos_df[\"id_code\"] = aptos_df[\"id_code\"].astype(str) + \".png\"\nmy_df[\"id_code\"] = my_df[\"id_code\"].astype(str) + \".png\"\n\n# Verify that all image files exist\naptos_images = set(os.listdir(APTOS_IMAGES_DIR))\nmy_images = set(os.listdir(MY_IMAGES_DIR))\n\naptos_df = aptos_df[aptos_df[\"id_code\"].isin(aptos_images)]\nmy_df = my_df[my_df[\"id_code\"].isin(my_images)]\n\n# Merge Both Datasets\ntrain_df = pd.concat([aptos_df, my_df], ignore_index=True)\n\n# Convert labels to string format\ntrain_df[\"diagnosis\"] = train_df[\"diagnosis\"].astype(str)\n\n# Split Data into Training & Validation (Stratified)\ntrain_df, val_df = train_test_split(train_df, test_size=0.2, random_state=42, stratify=train_df[\"diagnosis\"])\n\n# Data Augmentation & Preprocessing\ndata_gen = ImageDataGenerator(\n    rescale=1.0 / 255.0,\n    rotation_range=20,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True\n)\nval_gen = ImageDataGenerator(rescale=1.0 / 255.0)\n\n# Custom Generator to Handle Multiple Image Directories\nclass MultiDirectoryDataGenerator(tf.keras.utils.Sequence):\n    def __init__(self, dataframe, batch_size, mode=\"train\"):\n        self.dataframe = dataframe\n        self.batch_size = batch_size\n        self.mode = mode\n        self.indices = np.arange(len(self.dataframe))\n    \n    def __len__(self):\n        return int(np.ceil(len(self.dataframe) / self.batch_size))\n    \n    def __getitem__(self, index):\n        batch_indices = self.indices[index * self.batch_size:(index + 1) * self.batch_size]\n        batch_data = self.dataframe.iloc[batch_indices]\n        \n        images = []\n        labels = []\n        \n        for _, row in batch_data.iterrows():\n            img_path = os.path.join(APTOS_IMAGES_DIR, row[\"id_code\"])\n            if not os.path.exists(img_path):  # If not in Kaggle dataset, check your dataset\n                img_path = os.path.join(MY_IMAGES_DIR, row[\"id_code\"])\n            \n            img = tf.keras.preprocessing.image.load_img(img_path, target_size=(IMG_SIZE, IMG_SIZE))\n            img = tf.keras.preprocessing.image.img_to_array(img) / 255.0\n            \n            images.append(img)\n            labels.append(int(row[\"diagnosis\"]))\n        \n        return np.array(images), np.array(labels)\n\n# Use the custom generator\ntrain_gen = MultiDirectoryDataGenerator(train_df, BATCH_SIZE, mode=\"train\")\nval_gen = MultiDirectoryDataGenerator(val_df, BATCH_SIZE, mode=\"val\")\n\n# Load VGG16 Model (Transfer Learning)\nbase_model = VGG16(weights='imagenet', include_top=False, input_shape=(IMG_SIZE, IMG_SIZE, 3))\nbase_model.trainable = True  # Fine-tuning enabled\n\n# Define Model\nmodel = tf.keras.Sequential([\n    base_model,\n    tf.keras.layers.GlobalAveragePooling2D(),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(128, activation='relu'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(5, activation='softmax')  # 5 classes (0–4 for DR severity)\n])\n\n# Compile Model\nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy']\n)\n\n# Define Callbacks\nmodel_checkpoint = tf.keras.callbacks.ModelCheckpoint(\n    \"vgg16_best_model.keras\",\n    monitor='val_loss',\n    save_best_only=True,\n    verbose=1\n)\nearly_stopping = tf.keras.callbacks.EarlyStopping(\n    monitor='val_loss',\n    patience=5,\n    restore_best_weights=True\n)\n\n# Train the Model\nhistory = model.fit(\n    train_gen,\n    validation_data=val_gen,\n    epochs=14,\n    steps_per_epoch=len(train_gen),\n    validation_steps=len(val_gen),\n    callbacks=[model_checkpoint, early_stopping]\n)\n\n# Save Final Model\nmodel.save(\"vgg16_finetuned.keras\")\n\n# Evaluate Model\nval_loss, val_accuracy = model.evaluate(val_gen)\nprint(f\"Validation Loss: {val_loss:.4f}, Validation Accuracy: {val_accuracy:.4f}\")\n\n# Get Predictions\ny_true = val_df[\"diagnosis\"].astype(int).values\ny_pred = model.predict(val_gen)\ny_pred_classes = np.argmax(y_pred, axis=1)\n\n# Classification Report\nprint(\"Classification Report:\")\nprint(classification_report(y_true, y_pred_classes))\n\n# Confusion Matrix\nconf_matrix = confusion_matrix(y_true, y_pred_classes)\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt=\"d\", cmap=\"Blues\", xticklabels=range(5), yticklabels=range(5))\nplt.xlabel(\"Predicted\")\nplt.ylabel(\"True\")\nplt.title(\"Confusion Matrix\")\nplt.show()\n\n# Plot Loss and Accuracy\nfig, ax = plt.subplots(1, 2, figsize=(12, 5))\n\n# Loss plot\nax[0].plot(history.history['loss'], label='Train Loss')\nax[0].plot(history.history['val_loss'], label='Val Loss')\nax[0].set_xlabel(\"Epochs\")\nax[0].set_ylabel(\"Loss\")\nax[0].set_title(\"Loss vs Epochs\")\nax[0].legend()\n\n# Accuracy plot\nax[1].plot(history.history['accuracy'], label='Train Accuracy')\nax[1].plot(history.history['val_accuracy'], label='Val Accuracy')\nax[1].set_xlabel(\"Epochs\")\nax[1].set_ylabel(\"Accuracy\")\nax[1].set_title(\"Accuracy vs Epochs\")\nax[1].legend()\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-26T15:25:59.132833Z","iopub.execute_input":"2025-03-26T15:25:59.133173Z","iopub.status.idle":"2025-03-26T16:18:51.513202Z","shell.execute_reply.started":"2025-03-26T15:25:59.133149Z","shell.execute_reply":"2025-03-26T16:18:51.512177Z"}},"outputs":[],"execution_count":null}]}