{"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":3362,"databundleVersionId":31148,"sourceType":"competition"},{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"},{"sourceId":28903,"sourceType":"datasetVersion","datasetId":22535},{"sourceId":1003830,"sourceType":"datasetVersion","datasetId":550917},{"sourceId":4748798,"sourceType":"datasetVersion","datasetId":2716794}],"dockerImageVersionId":30559,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport os\nimport cv2\nimport glob as gb\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.image as mpimg\nfrom tqdm import tqdm\nfrom PIL import Image\n\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\n\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import ReduceLROnPlateau\nfrom keras.callbacks import EarlyStopping\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import classification_report, confusion_matrix\nfrom keras.optimizers import Adam\n\nfrom keras.applications import DenseNet121\nfrom keras.applications import ResNet50V2\nfrom keras.applications import ResNet152V2\nfrom keras.applications import InceptionV3\nfrom keras.applications import Xception","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2025-03-19T17:57:33.671957Z","iopub.execute_input":"2025-03-19T17:57:33.672297Z","iopub.status.idle":"2025-03-19T17:57:33.680087Z","shell.execute_reply.started":"2025-03-19T17:57:33.672271Z","shell.execute_reply":"2025-03-19T17:57:33.679249Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_path = '../input/dogs-cats-images/dog vs cat/dataset/training_set'\ntest_path = '../input/dogs-cats-images/dog vs cat/dataset/test_set'","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:57:33.681448Z","iopub.execute_input":"2025-03-19T17:57:33.681708Z","iopub.status.idle":"2025-03-19T17:57:33.688592Z","shell.execute_reply.started":"2025-03-19T17:57:33.681688Z","shell.execute_reply":"2025-03-19T17:57:33.687800Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Data augmentation for training\ntrain_datagen = ImageDataGenerator(\n    rescale=1.0/255,                # Rescale pixel values to [0, 1]\n    rotation_range=20,              # Random rotation within 20 degrees\n    width_shift_range=0.2,          # Random horizontal shift by 20% of image width\n    height_shift_range=0.2,         # Random vertical shift by 20% of image height\n    horizontal_flip=True,           # Random horizontal flipping\n    fill_mode='nearest'             # Fill mode for new pixels after shifts/rotations\n)","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:57:33.689783Z","iopub.execute_input":"2025-03-19T17:57:33.690367Z","iopub.status.idle":"2025-03-19T17:57:33.695498Z","shell.execute_reply.started":"2025-03-19T17:57:33.690337Z","shell.execute_reply":"2025-03-19T17:57:33.694791Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"images_size = 200\nbatch_size = 32","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:57:33.703130Z","iopub.execute_input":"2025-03-19T17:57:33.703382Z","iopub.status.idle":"2025-03-19T17:57:33.708276Z","shell.execute_reply.started":"2025-03-19T17:57:33.703362Z","shell.execute_reply":"2025-03-19T17:57:33.707629Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_generator = train_datagen.flow_from_directory(\n    train_path,                     # Path to the training data\n    target_size=(images_size, images_size),  # Resize images to this size\n    batch_size=batch_size,           # Number of images in each batch\n    seed=32,                         # Optional: Set a random seed for shuffling\n    shuffle=True,                    # Shuffle the data during training\n    class_mode='categorical'        # Mode for class labels (categorical for one-hot encoding)\n)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-19T17:57:33.709649Z","iopub.execute_input":"2025-03-19T17:57:33.709924Z","iopub.status.idle":"2025-03-19T17:57:39.840053Z","shell.execute_reply.started":"2025-03-19T17:57:33.709897Z","shell.execute_reply":"2025-03-19T17:57:39.839122Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Get the class labels\nclass_labels = list(train_generator.class_indices.keys())\n\n# Calculate the count of images per class\nclass_counts = {label: 0 for label in class_labels}\n\nfor i in range(len(train_generator)):\n    batch_data, batch_labels = train_generator[i]\n    for j in range(len(batch_data)):\n        class_idx = int(batch_labels[j].argmax())\n        class_label = class_labels[class_idx]\n        class_counts[class_label] += 1\n\n# Define unique colors for each class\nclass_colors = plt.cm.tab20(np.linspace(0, 1, len(class_labels)))\n\n# Create a bar chart with different colors for each class\nplt.figure(figsize=(8, 4))\nbars = plt.bar(class_counts.keys(), class_counts.values(), color=class_colors)\nplt.xlabel('Class')\nplt.ylabel('Count')\nplt.title('Number of Images per Class')\nplt.xticks(rotation=45)\n\n# Add a legend for class colors\nlegend_labels = [plt.Line2D([0], [0], color=class_colors[i], lw=4, label=class_labels[i]) for i in range(len(class_labels))]\nplt.legend(handles=legend_labels, title=\"Classes\")\n\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-19T17:57:39.841267Z","iopub.execute_input":"2025-03-19T17:57:39.841615Z","iopub.status.idle":"2025-03-19T17:58:55.084748Z","shell.execute_reply.started":"2025-03-19T17:57:39.841566Z","shell.execute_reply":"2025-03-19T17:58:55.083909Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# data augmentation for testing\ntest_datagen = ImageDataGenerator(rescale=1.0/255)  # Rescale pixel values to [0, 1]","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:58:55.086005Z","iopub.execute_input":"2025-03-19T17:58:55.086565Z","iopub.status.idle":"2025-03-19T17:58:55.090503Z","shell.execute_reply.started":"2025-03-19T17:58:55.086533Z","shell.execute_reply":"2025-03-19T17:58:55.089637Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create a generator for testing data\ntest_generator = test_datagen.flow_from_directory(\n    test_path,\n    target_size=(images_size, images_size),\n    batch_size = batch_size,\n    class_mode='categorical')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-19T17:58:55.092368Z","iopub.execute_input":"2025-03-19T17:58:55.092650Z","iopub.status.idle":"2025-03-19T17:58:58.079568Z","shell.execute_reply.started":"2025-03-19T17:58:55.092622Z","shell.execute_reply":"2025-03-19T17:58:58.078735Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Get the class labels\nclass_labels = list(test_generator.class_indices.keys())\n\n# Calculate the count of images per class\nclass_counts = {label: 0 for label in class_labels}\n\nfor i in range(len(test_generator)):\n    batch_data, batch_labels = test_generator[i]\n    for j in range(len(batch_data)):\n        class_idx = int(batch_labels[j].argmax())\n        class_label = class_labels[class_idx]\n        class_counts[class_label] += 1\n\n# Define unique colors for each class\nclass_colors = plt.cm.tab20(np.linspace(0, 1, len(class_labels)))\n\n# Create a bar chart with different colors for each class\nplt.figure(figsize=(8, 4))\nbars = plt.bar(class_counts.keys(), class_counts.values(), color=class_colors)\nplt.xlabel('Class')\nplt.ylabel('Count')\nplt.title('Number of Images per Class')\nplt.xticks(rotation=45)\n\n# Add a legend for class colors\nlegend_labels = [plt.Line2D([0], [0], color=class_colors[i], lw=4, label=class_labels[i]) for i in range(len(class_labels))]\nplt.legend(handles=legend_labels, title=\"Classes\")\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:58:58.080541Z","iopub.execute_input":"2025-03-19T17:58:58.080809Z","iopub.status.idle":"2025-03-19T17:59:02.540065Z","shell.execute_reply.started":"2025-03-19T17:58:58.080788Z","shell.execute_reply":"2025-03-19T17:59:02.539260Z"},"_kg_hide-input":true,"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 3.3 Display Images","metadata":{}},{"cell_type":"code","source":"def Show_Images(target_gen):\n    # Get a batch of images and labels\n    batch_images, batch_labels = next(target_gen)\n\n    # Get class labels\n    class_labels = list(target_gen.class_indices.keys())\n\n    # Display images with labels\n    plt.figure(figsize=(20, 20))\n    for n , i in enumerate(list(np.random.randint(0,len(batch_images),16))):\n        plt.subplot(4, 4, n + 1)\n        plt.imshow(batch_images[i])\n        plt.title(class_labels[np.argmax(batch_labels[i])])  # Display the class label\n        plt.axis('off')\n    plt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-19T17:59:02.541312Z","iopub.execute_input":"2025-03-19T17:59:02.541669Z","iopub.status.idle":"2025-03-19T17:59:02.547482Z","shell.execute_reply.started":"2025-03-19T17:59:02.541637Z","shell.execute_reply":"2025-03-19T17:59:02.546642Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Show_Images(train_generator)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-19T17:59:02.548400Z","iopub.execute_input":"2025-03-19T17:59:02.548624Z","iopub.status.idle":"2025-03-19T17:59:04.940735Z","shell.execute_reply.started":"2025-03-19T17:59:02.548584Z","shell.execute_reply":"2025-03-19T17:59:04.939612Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Show_Images(test_generator)","metadata":{"_kg_hide-input":true,"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T17:59:04.942034Z","iopub.execute_input":"2025-03-19T17:59:04.942326Z","iopub.status.idle":"2025-03-19T17:59:07.202173Z","shell.execute_reply.started":"2025-03-19T17:59:04.942300Z","shell.execute_reply":"2025-03-19T17:59:07.200870Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"early_stopping = EarlyStopping(\n    min_delta=0.001, # minimium amount of change to count as an improvement\n    patience=5, # how many epochs to wait before stopping\n    restore_best_weights=True,\n)","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:59:07.203376Z","iopub.execute_input":"2025-03-19T17:59:07.203705Z","iopub.status.idle":"2025-03-19T17:59:07.207692Z","shell.execute_reply.started":"2025-03-19T17:59:07.203681Z","shell.execute_reply":"2025-03-19T17:59:07.206878Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Configure the learning rate reduction callback\nlearning_rate_reduce = ReduceLROnPlateau(\n    monitor='val_acc',   # Metric to monitor for changes (usually validation accuracy)\n    patience=5,          # Number of epochs with no improvement after which learning rate will be reduced\n    verbose=1,           # Verbosity mode (0: silent, 1: update messages)\n    factor=0.5,          # Factor by which the learning rate will be reduced (e.g., 0.5 means halving)\n    min_lr=0.00001       # Lower bound for the learning rate (it won't go below this value)\n)","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:59:07.208634Z","iopub.execute_input":"2025-03-19T17:59:07.208857Z","iopub.status.idle":"2025-03-19T17:59:07.217054Z","shell.execute_reply.started":"2025-03-19T17:59:07.208838Z","shell.execute_reply":"2025-03-19T17:59:07.216249Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras import optimizers\n\n# Create a learning rate schedule using Exponential Decay\nlearning_rate_schedule = keras.optimizers.schedules.ExponentialDecay(\n    initial_learning_rate=0.01,  # Initial learning rate for training\n    decay_steps=1000,            # Number of steps before decaying the learning rate\n    decay_rate=0.5,              # Rate at which the learning rate decreases\n)\n\n# learning_rate = initial_learning_rate * decay_rate ^ (global_step / decay_steps)\n","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:59:07.218186Z","iopub.execute_input":"2025-03-19T17:59:07.218465Z","iopub.status.idle":"2025-03-19T17:59:07.228841Z","shell.execute_reply.started":"2025-03-19T17:59:07.218440Z","shell.execute_reply":"2025-03-19T17:59:07.227961Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from keras.callbacks import LearningRateScheduler\n\n# Create a Learning Rate Scheduler callback using a pre-defined schedule\nlr_callback = LearningRateScheduler(learning_rate_schedule)\ncallback=[ lr_callback , learning_rate_reduce ,early_stopping ]","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:59:07.231738Z","iopub.execute_input":"2025-03-19T17:59:07.231970Z","iopub.status.idle":"2025-03-19T17:59:07.239119Z","shell.execute_reply.started":"2025-03-19T17:59:07.231950Z","shell.execute_reply":"2025-03-19T17:59:07.238224Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Collect all TL models\nTL_Models =[\n    ResNet50V2(input_shape=(images_size, images_size, 3), weights='imagenet', include_top=False),\n    ResNet152V2(input_shape=(images_size, images_size, 3), weights='imagenet', include_top=False),\n    InceptionV3(input_shape=(images_size, images_size, 3), weights='imagenet', include_top=False),\n    Xception(input_shape=(images_size, images_size, 3), weights='imagenet', include_top=False),\n    DenseNet121( input_shape=(images_size, images_size, 3) ,weights='imagenet', include_top=False),\n]\n\n# Define all the TL models names. This will be later used during visualization\nTL_Models_NAMES = [\n    'ResNet50V2',\n    'ResNet152V2',\n    'InceptionV3',\n    'Xception',\n    'DenseNet121',\n]\n\n# Freeze the weights of all the TL models\nfor tl_model in TL_Models:\n    tl_model.trainable = False","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:59:07.240201Z","iopub.execute_input":"2025-03-19T17:59:07.240404Z","iopub.status.idle":"2025-03-19T17:59:18.672663Z","shell.execute_reply.started":"2025-03-19T17:59:07.240387Z","shell.execute_reply":"2025-03-19T17:59:18.671921Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 5.1 Get subset from training data","metadata":{}},{"cell_type":"code","source":"# Create variables to collect images and labels\nsubset_images = []\nsubset_labels = []\n\n# Set the desired number of images you want in the subset\ndesired_count = 1000\n\n# Loop through the generator until you have collected the desired number of images\nfor i in range(desired_count):\n    # Generate a batch of data (images and labels)\n    batch = train_generator.next()\n    images, labels = batch\n    subset_images.extend(images)\n    subset_labels.extend(labels)\n\n    # Check if you've collected enough images\n    if len(subset_images) >= desired_count:\n        break\n\n# Convert the collected images and labels to numpy arrays\nX_sub = np.array(subset_images)\ny_sub = np.array(subset_labels)","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:59:18.673731Z","iopub.execute_input":"2025-03-19T17:59:18.673970Z","iopub.status.idle":"2025-03-19T17:59:28.757779Z","shell.execute_reply.started":"2025-03-19T17:59:18.673949Z","shell.execute_reply":"2025-03-19T17:59:28.757024Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 5.2 Training the Models and get Histories ","metadata":{}},{"cell_type":"code","source":"# Initialize an empty list to hold the histories of each TL_models architecture.\nHISTORIES = []\n\n# Loop over every backbone in the BACKBONES list.\nfor tl_model in tqdm(TL_Models, desc=\"Training Tl Models\"):\n    \n    # Create the simplest model architecture using the current backbone.\n    model = keras.Sequential([\n        tl_model,\n        layers.GlobalAveragePooling2D(),\n        layers.Dropout(0.5),\n        layers.Dense(2, activation='softmax')\n    ])\n    \n    # Compile the model with the specified loss function, optimizer, and metrics.\n    model.compile(\n        loss='categorical_crossentropy',\n        optimizer=Adam(learning_rate = learning_rate_schedule),\n        metrics='accuracy'\n    )\n    \n    # Train the model on a subset of the training data.\n    history = model.fit(\n        X_sub, y_sub,\n        epochs=10,\n        validation_split=0.2,\n        batch_size=batch_size\n    )\n        \n    # Store the history of the trained model.\n    HISTORIES.append(history.history)","metadata":{"execution":{"iopub.status.busy":"2025-03-19T17:59:28.758840Z","iopub.execute_input":"2025-03-19T17:59:28.759065Z","iopub.status.idle":"2025-03-19T18:03:00.944574Z","shell.execute_reply.started":"2025-03-19T17:59:28.759046Z","shell.execute_reply":"2025-03-19T18:03:00.943674Z"},"_kg_hide-output":true,"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 5.3 Analyze the performance of TL Models","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Define the metrics to plot (e.g., 'accuracy' and 'loss')\nmetrics_to_plot = ['accuracy', 'loss']\n\n# Create subplots for each metric\nfig, axes = plt.subplots(len(metrics_to_plot), 1, figsize=(10, 6))\n\nfor i, metric in enumerate(metrics_to_plot):\n    plt.subplot(2, 1, i+1)  # Create subplots for each metric\n    for idx, history in enumerate(HISTORIES):\n        plt.plot(history[metric], label=TL_Models_NAMES[idx])\n    plt.title(f'Training and Validation {metric}')\n    plt.xlabel('Epochs')\n    plt.ylabel(metric)\n    plt.legend()\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-03-19T18:03:00.945768Z","iopub.execute_input":"2025-03-19T18:03:00.946003Z","iopub.status.idle":"2025-03-19T18:03:01.481699Z","shell.execute_reply.started":"2025-03-19T18:03:00.945981Z","shell.execute_reply":"2025-03-19T18:03:01.480860Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 6.1 Get the weights from Xception","metadata":{}},{"cell_type":"code","source":"base_model = Xception(weights='imagenet', include_top=False, input_shape=(images_size, images_size, 3))","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2025-03-19T18:03:01.482982Z","iopub.execute_input":"2025-03-19T18:03:01.483759Z","iopub.status.idle":"2025-03-19T18:03:02.674970Z","shell.execute_reply.started":"2025-03-19T18:03:01.483723Z","shell.execute_reply":"2025-03-19T18:03:02.674141Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 6.2 Freeze the layers of Xception","metadata":{}},{"cell_type":"code","source":"# Freeze the layers of the base model\nfor layer in base_model.layers:\n    layer.trainable = False","metadata":{"execution":{"iopub.status.busy":"2025-03-19T18:03:02.676055Z","iopub.execute_input":"2025-03-19T18:03:02.676332Z","iopub.status.idle":"2025-03-19T18:03:02.683072Z","shell.execute_reply.started":"2025-03-19T18:03:02.676309Z","shell.execute_reply":"2025-03-19T18:03:02.682083Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = tf.keras.models.Sequential([\n    base_model,\n    \n    layers.Flatten(),\n    \n    layers.Dense(256,activation='relu'),\n    layers.Dropout(0.5),\n    layers.Dense(2,activation='softmax'),\n])\n\nmodel.summary()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-19T18:03:02.683962Z","iopub.execute_input":"2025-03-19T18:03:02.684197Z","iopub.status.idle":"2025-03-19T18:03:04.020304Z","shell.execute_reply.started":"2025-03-19T18:03:02.684176Z","shell.execute_reply":"2025-03-19T18:03:04.019352Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 7.1 Set the optimizer","metadata":{}},{"cell_type":"code","source":"optimizer = optimizers.Adam(learning_rate=learning_rate_schedule)","metadata":{"execution":{"iopub.status.busy":"2025-03-19T18:03:04.021691Z","iopub.execute_input":"2025-03-19T18:03:04.022028Z","iopub.status.idle":"2025-03-19T18:03:04.033431Z","shell.execute_reply.started":"2025-03-19T18:03:04.021998Z","shell.execute_reply":"2025-03-19T18:03:04.032648Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(optimizer=optimizer,\n             loss=\"categorical_crossentropy\",\n              metrics=['accuracy']\n             )","metadata":{"execution":{"iopub.status.busy":"2025-03-19T18:03:04.036478Z","iopub.execute_input":"2025-03-19T18:03:04.036757Z","iopub.status.idle":"2025-03-19T18:03:04.047679Z","shell.execute_reply.started":"2025-03-19T18:03:04.036729Z","shell.execute_reply":"2025-03-19T18:03:04.046871Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 7.2 Training the model","metadata":{}},{"cell_type":"code","source":"history = model.fit(\n    train_generator,\n    steps_per_epoch=train_generator.samples // batch_size,\n    epochs=20,\n    validation_data=test_generator,\n    validation_steps=test_generator.samples // batch_size,\n    callbacks=[callback]\n)","metadata":{"execution":{"iopub.status.busy":"2025-03-19T18:03:04.048656Z","iopub.execute_input":"2025-03-19T18:03:04.048953Z","iopub.status.idle":"2025-03-19T18:32:33.194294Z","shell.execute_reply.started":"2025-03-19T18:03:04.048922Z","shell.execute_reply":"2025-03-19T18:32:33.193664Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 8.1 Evaluate the validation","metadata":{}},{"cell_type":"code","source":"# Evaluate on test dataset\nscore = model.evaluate(test_generator, verbose=False)\nprint('Test loss:', score[0])\nprint('Test accuracy:', score[1])","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-19T18:32:33.195484Z","iopub.execute_input":"2025-03-19T18:32:33.195751Z","iopub.status.idle":"2025-03-19T18:32:41.012342Z","shell.execute_reply.started":"2025-03-19T18:32:33.195728Z","shell.execute_reply":"2025-03-19T18:32:41.011414Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 8.2 Accuracy graph ","metadata":{}},{"cell_type":"code","source":"# Accuracy\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nepochs = range(len(acc))\n\nplt.plot(epochs, acc, 'b', label='Training Accuracy')\nplt.plot(epochs, val_acc, 'r', label='Validation Accuracy')\nplt.title('Accuracy Graph')\nplt.legend()\nplt.figure()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-19T18:32:41.013448Z","iopub.execute_input":"2025-03-19T18:32:41.013736Z","iopub.status.idle":"2025-03-19T18:32:41.311677Z","shell.execute_reply.started":"2025-03-19T18:32:41.013714Z","shell.execute_reply":"2025-03-19T18:32:41.310753Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 8.3 Loss graph ","metadata":{}},{"cell_type":"code","source":"# Loss\nloss = history.history['loss']\nval_loss = history.history['val_loss']\nplt.plot(epochs, loss, 'b', label='Training Loss')\nplt.plot(epochs, val_loss, 'r', label='Validation Loss')\nplt.title('Loss Graph')\nplt.legend()\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-19T18:32:41.312946Z","iopub.execute_input":"2025-03-19T18:32:41.313347Z","iopub.status.idle":"2025-03-19T18:32:41.584221Z","shell.execute_reply.started":"2025-03-19T18:32:41.313314Z","shell.execute_reply":"2025-03-19T18:32:41.583202Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 8.4 Confusion Matrix","metadata":{}},{"cell_type":"code","source":"# Confusion Matrix\nimport itertools\n\n# Make predictions on the test data\npredictions = model.predict(test_generator)\n\n# Convert probabilities to class labels\npredicted_labels = np.argmax(predictions, axis=1)\n\n# Get true labels from the test_generator\ntrue_labels = test_generator.classes\n\n# Calculate confusion matrix\ncm = confusion_matrix(true_labels, predicted_labels)\n\n# Define class names (assuming you have class_names defined)\nclass_names = test_generator.class_indices.keys()\n\n# Plot confusion matrix\ndef plot_confusion_matrix(cm, classes, normalize=False, title=\"Confusion Matrix\", cmap=plt.cm.Blues):\n    plt.imshow(cm, interpolation=\"nearest\", cmap=cmap)\n    plt.title(title)\n    plt.colorbar()\n    tick_marks = np.arange(len(classes))\n    plt.xticks(tick_marks, classes, rotation=45)\n    plt.yticks(tick_marks, classes)\n\n    if normalize:\n        cm = cm.astype(\"float\") / cm.sum(axis=1)[:, np.newaxis]\n\n    thresh = cm.max() / 2.0\n    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n        plt.text(j, i, cm[i, j], horizontalalignment=\"center\", color=\"white\" if cm[i, j] > thresh else \"black\")\n\n    plt.tight_layout()\n    plt.ylabel(\"True label\")\n    plt.xlabel(\"Predicted label\")\n\n# Plot non-normalized confusion matrix\nplt.figure(figsize=(8, 6))\nplot_confusion_matrix(cm, classes=class_names, title=\"Confusion Matrix\")\nplt.show()\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-19T18:32:41.585437Z","iopub.execute_input":"2025-03-19T18:32:41.585759Z","iopub.status.idle":"2025-03-19T18:32:50.180504Z","shell.execute_reply.started":"2025-03-19T18:32:41.585735Z","shell.execute_reply":"2025-03-19T18:32:50.179623Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 8.5 Generate predictions for the test data","metadata":{}},{"cell_type":"code","source":"# Collect true labels and model predictions\ntrue_labels = []\npredicted_labels = []\nclass_names = test_generator.class_indices.keys()    \nclass_names = list(class_names)\nnum_batches = len(test_generator)\nfor i in range(10):\n    x_batch, y_batch = test_generator[i]\n    predictions = model.predict(x_batch)\n    true_labels.extend(np.argmax(y_batch, axis=1))  # Convert one-hot encoded labels to class indices\n    predicted_labels.extend(np.argmax(predictions, axis=1))\n\n\ntrue_class_labels = [class_names[i] for i in true_labels]\npredicted_class_labels = [class_names[i] for i in predicted_labels]\n\n# Plot true labels and predicted labels\nplt.figure(figsize=(10, 5))\nnum_samples_to_display = min(10, len(x_batch))  # Display up to 10 samples or less if available\nfor i in range(num_samples_to_display):\n    plt.subplot(2, 5, i + 1)\n    plt.imshow(x_batch[i])\n    plt.title(f'True: {true_class_labels[i]}\\nPredicted: {predicted_class_labels[i]}', fontsize=8)\n    plt.axis('off')\n\nplt.tight_layout()\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-19T18:32:50.181479Z","iopub.execute_input":"2025-03-19T18:32:50.181735Z","iopub.status.idle":"2025-03-19T18:32:54.092151Z","shell.execute_reply.started":"2025-03-19T18:32:50.181714Z","shell.execute_reply":"2025-03-19T18:32:54.091289Z"},"trusted":true},"outputs":[],"execution_count":null}]}