{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# <font color='blue'>**Histopathologic Cancer Detection**</font>","metadata":{}},{"cell_type":"markdown","source":"<font color='blue'>**Introduction:**</font>\n\nHistopathologic cancer detection is a crucial task that involves identifying metastatic cancer in small image patches taken from larger digital pathology scans. The dataset used in this project consists of labeled images, where each label indicates the presence (1) or absence (0) of tumor tissue in the corresponding image.","metadata":{}},{"cell_type":"markdown","source":"# <font color='blue'>**1. Data Exploration and Understanding**</font>","metadata":{}},{"cell_type":"markdown","source":"**In this phase, I delved into the dataset to understand the nature of the images and their labels. I visualized samples of images with and without tumor tissues, explored the distribution of labels, and checked the quality of the images in terms of resolution and contrast.**","metadata":{}},{"cell_type":"markdown","source":"## <font color='green'>1.1 Image Visualization</font>","metadata":{}},{"cell_type":"code","source":"# Required Libraries\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\nimport os\n\n# Load train labels\ntrain_labels = pd.read_csv('/kaggle/input/histopathologic-cancer-detection/train_labels.csv')\n\n# Display a subset of images with and without tumor tissue\ndef display_images(samples, title):\n    fig, axes = plt.subplots(1, len(samples), figsize=(20, 5))\n    for img_path, ax in zip(samples, axes):\n        img = cv2.imread(img_path)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        ax.imshow(img)\n        ax.axis('off')\n    plt.suptitle(title, fontsize=16)\n    plt.show()\n\n# Positive samples (with tumor)\npositive_samples = train_labels[train_labels['label'] == 1]['id'].head(5).apply(lambda x: f'../input/histopathologic-cancer-detection/train/{x}.tif').tolist()\ndisplay_images(positive_samples, \"Images with Tumor Tissue\")\n\n# Negative samples (without tumor)\nnegative_samples = train_labels[train_labels['label'] == 0]['id'].head(5).apply(lambda x: f'../input/histopathologic-cancer-detection/train/{x}.tif').tolist()\ndisplay_images(negative_samples, \"Images without Tumor Tissue\")","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:11:54.196242Z","iopub.execute_input":"2023-08-13T10:11:54.196814Z","iopub.status.idle":"2023-08-13T10:11:55.605497Z","shell.execute_reply.started":"2023-08-13T10:11:54.196752Z","shell.execute_reply":"2023-08-13T10:11:55.604366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='green'>1.2 Label Distribution</font>","metadata":{}},{"cell_type":"code","source":"# Plotting the distribution of labels\nplt.figure(figsize=(8, 5))\ntrain_labels['label'].value_counts().plot(kind='bar', color=['skyblue', 'salmon'])\nplt.title('Distribution of Tumor (1) and No Tumor (0) Labels')\nplt.xlabel('Label')\nplt.ylabel('Count')\nplt.xticks(rotation=0)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:11:55.607777Z","iopub.execute_input":"2023-08-13T10:11:55.608107Z","iopub.status.idle":"2023-08-13T10:11:55.882976Z","shell.execute_reply.started":"2023-08-13T10:11:55.608077Z","shell.execute_reply":"2023-08-13T10:11:55.881749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='green'>1.3 Image Quality Check</font>","metadata":{}},{"cell_type":"code","source":"# Checking the resolution and contrast of a random subset of images\nimage_paths = train_labels['id'].sample(5).apply(lambda x: f'../input/histopathologic-cancer-detection/train/{x}.tif').tolist()\n\nfor img_path in image_paths:\n    img = cv2.imread(img_path)\n    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    # Displaying image details\n    print(f\"Image: {img_path.split('/')[-1]}\")\n    print(f\"Resolution: {img.shape[0]}x{img.shape[1]}\")\n    print(f\"Contrast (max-min pixel values): {np.max(img_rgb) - np.min(img_rgb)}\\n\")","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:11:55.884542Z","iopub.execute_input":"2023-08-13T10:11:55.884866Z","iopub.status.idle":"2023-08-13T10:11:55.975740Z","shell.execute_reply.started":"2023-08-13T10:11:55.884838Z","shell.execute_reply":"2023-08-13T10:11:55.974474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <font color='blue'>2. Data Preprocessing</font>","metadata":{}},{"cell_type":"markdown","source":"**The images were resized to a consistent shape of 96x96 pixels. I normalized the pixel values to fall between 0 and 1. The dataset was split into training, validation, and test sets. Additionally, data augmentation techniques were applied to increase the diversity of the training data and prevent overfitting.**","metadata":{}},{"cell_type":"markdown","source":"## <font color='green'>2.1 Image Resizing</font>","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import load_img, img_to_array\n\n# Define the desired dimensions\nIMG_WIDTH, IMG_HEIGHT = 96, 96\n\ndef resize_image(img_path, target_width=IMG_WIDTH, target_height=IMG_HEIGHT):\n    img = load_img(img_path, target_size=(target_width, target_height))\n    return img_to_array(img)\n\n# Example usage\nsample_path = train_labels['id'].iloc[0]\nresized_img = resize_image(f'../input/histopathologic-cancer-detection/train/{sample_path}.tif')\nprint(f\"Resized Image Shape: {resized_img.shape}\")","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:11:55.977236Z","iopub.execute_input":"2023-08-13T10:11:55.978311Z","iopub.status.idle":"2023-08-13T10:11:55.988959Z","shell.execute_reply.started":"2023-08-13T10:11:55.978276Z","shell.execute_reply":"2023-08-13T10:11:55.987609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='green'>2.2 Normalization</font>","metadata":{}},{"cell_type":"code","source":"def normalize_image(img):\n    return img / 255.0\n\n# Example usage\nnormalized_img = normalize_image(resized_img)\nprint(f\"Pixel Range after Normalization: {np.min(normalized_img)} - {np.max(normalized_img)}\")","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:11:55.992747Z","iopub.execute_input":"2023-08-13T10:11:55.993928Z","iopub.status.idle":"2023-08-13T10:11:56.005577Z","shell.execute_reply.started":"2023-08-13T10:11:55.993892Z","shell.execute_reply":"2023-08-13T10:11:56.004280Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='green'>2.3 Data Splitting</font>","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n# Splitting the data into training, validation, and test sets (80%, 10%, 10%)\ntrain_data, temp_data, train_labels, temp_labels = train_test_split(train_labels['id'].values, train_labels['label'].values, test_size=0.2, random_state=42)\nval_data, test_data, val_labels, test_labels = train_test_split(temp_data, temp_labels, test_size=0.5, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:11:56.007539Z","iopub.execute_input":"2023-08-13T10:11:56.008364Z","iopub.status.idle":"2023-08-13T10:11:56.051011Z","shell.execute_reply.started":"2023-08-13T10:11:56.008329Z","shell.execute_reply":"2023-08-13T10:11:56.049859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='green'>2.4 Data Augmentation</font>","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator, array_to_img, load_img, img_to_array\nimport matplotlib.pyplot as plt\n\n# Data augmentation configuration\ndatagen = ImageDataGenerator(\n    rotation_range=40,\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    fill_mode='nearest'\n)\n\n# Example: Display some augmented images\nimg = load_img(f'../input/histopathologic-cancer-detection/train/{train_data[0]}.tif')\nx = img_to_array(img)\nx = x.reshape((1,) + x.shape)\n\nfig, axes = plt.subplots(1, 5, figsize=(20, 5))\nfor i, batch in enumerate(datagen.flow(x, batch_size=1)):\n    axes[i].imshow(array_to_img(batch[0]))\n    axes[i].axis('off')\n    if i == 4: # Stop after displaying 5 images\n        break\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:11:56.052452Z","iopub.execute_input":"2023-08-13T10:11:56.052811Z","iopub.status.idle":"2023-08-13T10:11:56.659127Z","shell.execute_reply.started":"2023-08-13T10:11:56.052782Z","shell.execute_reply":"2023-08-13T10:11:56.657991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <font color='blue'>3. Model Development</font>","metadata":{}},{"cell_type":"markdown","source":"**I designed a convolutional neural network (CNN) with multiple layers to detect the presence of tumor tissue in the histopathologic images. The model was compiled using the Adam optimizer and binary cross-entropy loss, suitable for a binary classification task.**","metadata":{}},{"cell_type":"markdown","source":"## <font color='green'>3.1 Model Architecture</font>","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout\n\nmodel = Sequential()\n\n# Convolutional layers\nmodel.add(Conv2D(32, (3, 3), activation='relu', input_shape=(IMG_WIDTH, IMG_HEIGHT, 3)))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(64, (3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(128, (3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\n# Fully connected layers\nmodel.add(Flatten())\nmodel.add(Dense(512, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(1, activation='sigmoid'))  # Binary classification\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:11:56.660535Z","iopub.execute_input":"2023-08-13T10:11:56.661617Z","iopub.status.idle":"2023-08-13T10:11:56.858776Z","shell.execute_reply.started":"2023-08-13T10:11:56.661584Z","shell.execute_reply":"2023-08-13T10:11:56.857340Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='green'>3.2 Model Compilation</font>","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.optimizers import Adam\n\noptimizer = Adam(learning_rate=0.0001)\nmodel.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:11:56.860976Z","iopub.execute_input":"2023-08-13T10:11:56.861358Z","iopub.status.idle":"2023-08-13T10:11:56.880595Z","shell.execute_reply.started":"2023-08-13T10:11:56.861327Z","shell.execute_reply":"2023-08-13T10:11:56.879131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='green'>3.3 Model Training</font>","metadata":{}},{"cell_type":"code","source":"train_labels_df = pd.read_csv('../input/histopathologic-cancer-detection/train_labels.csv')\ntrain_labels_df['label'] = train_labels_df['label'].astype(str)  # Convert label column to string","metadata":{"execution":{"iopub.status.busy":"2023-08-13T12:19:15.835472Z","iopub.execute_input":"2023-08-13T12:19:15.836390Z","iopub.status.idle":"2023-08-13T12:19:16.305267Z","shell.execute_reply.started":"2023-08-13T12:19:15.836355Z","shell.execute_reply":"2023-08-13T12:19:16.304350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Add the .tif extension to the 'id' column for correct file referencing\ntrain_labels_df['id'] = train_labels_df['id'].apply(lambda x: f\"{x}.tif\")\n\n# Preparing data generators\ntrain_datagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)  # Normalize images\n\nbatch_size = 32\ntrain_steps = 8000 // batch_size  # 8000 images for training\nval_steps = 2000 // batch_size    # 2000 images for validation\n\ntrain_gen = train_datagen.flow_from_dataframe(\n    dataframe=train_labels_df.head(10000),\n    directory='../input/histopathologic-cancer-detection/train/',\n    x_col='id',\n    y_col='label',\n    target_size=(IMG_WIDTH, IMG_HEIGHT),\n    class_mode='binary',\n    batch_size=batch_size,\n    subset='training'\n)\n\nval_gen = train_datagen.flow_from_dataframe(\n    dataframe=train_labels_df.head(10000),\n    directory='../input/histopathologic-cancer-detection/train/',\n    x_col='id',\n    y_col='label',\n    target_size=(IMG_WIDTH, IMG_HEIGHT),\n    class_mode='binary',\n    batch_size=batch_size,\n    subset='validation'\n)\n\n# Training the model\nhistory = model.fit(\n    train_gen,\n    steps_per_epoch=train_steps,\n    validation_data=val_gen,\n    validation_steps=val_steps,\n    epochs=10\n)","metadata":{"execution":{"iopub.status.busy":"2023-08-13T12:19:18.404686Z","iopub.execute_input":"2023-08-13T12:19:18.405063Z","iopub.status.idle":"2023-08-13T12:19:49.344482Z","shell.execute_reply.started":"2023-08-13T12:19:18.405035Z","shell.execute_reply":"2023-08-13T12:19:49.342940Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <font color='blue'>4. Model Evaluation</font>","metadata":{}},{"cell_type":"markdown","source":"**The model's performance was evaluated using various metrics such as accuracy, precision, recall, F1 score, and ROC-AUC. I also checked for signs of overfitting by comparing the training and validation loss and accuracy. Error analysis was conducted by visualizing misclassified images.**","metadata":{}},{"cell_type":"markdown","source":"## <font color='green'>4.1 Performance Metrics</font>","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, roc_curve\n\n# Adjust the val_steps\nval_steps = np.ceil(len(val_gen.classes) / batch_size)\n\n# Predict classes\nval_predictions = model.predict(val_gen, steps=val_steps)\nval_pred_classes = (val_predictions > 0.5).astype(int).flatten()\n\n# True labels\ntrue_labels = val_gen.classes\n\n# Ensure the lengths match\nval_pred_classes = val_pred_classes[:len(true_labels)]\n\n# Calculate metrics\naccuracy = accuracy_score(true_labels, val_pred_classes)\nprecision = precision_score(true_labels, val_pred_classes)\nrecall = recall_score(true_labels, val_pred_classes)\nf1 = f1_score(true_labels, val_pred_classes)\nroc_auc = roc_auc_score(true_labels, val_predictions)\n\nprint(f\"Accuracy: {accuracy:.4f}\")\nprint(f\"Precision: {precision:.4f}\")\nprint(f\"Recall: {recall:.4f}\")\nprint(f\"F1 Score: {f1:.4f}\")\nprint(f\"ROC-AUC: {roc_auc:.4f}\")","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:42:36.461885Z","iopub.execute_input":"2023-08-13T10:42:36.462297Z","iopub.status.idle":"2023-08-13T10:42:46.842130Z","shell.execute_reply.started":"2023-08-13T10:42:36.462267Z","shell.execute_reply":"2023-08-13T10:42:46.840915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='green'>4.2 Overfitting Check</font>","metadata":{}},{"cell_type":"code","source":"# Plotting training and validation loss\nplt.figure(figsize=(12, 4))\n\nplt.subplot(1, 2, 1)\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\nplt.subplot(1, 2, 2)\nplt.plot(history.history['accuracy'], label='Training Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\nplt.legend()\nplt.title('Training and Validation Accuracy')\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:42:59.240142Z","iopub.execute_input":"2023-08-13T10:42:59.240626Z","iopub.status.idle":"2023-08-13T10:42:59.898873Z","shell.execute_reply.started":"2023-08-13T10:42:59.240588Z","shell.execute_reply":"2023-08-13T10:42:59.897886Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='green'>4.3 Error Analysis</font>","metadata":{}},{"cell_type":"code","source":"# Extracting misclassified image indices\nmisclassified_idx = np.where(val_pred_classes != true_labels)[0]\n\n# Displaying a subset of misclassified images\nsample_misclassified = np.random.choice(misclassified_idx, 5)\n\nplt.figure(figsize=(20, 5))\nfor i, idx in enumerate(sample_misclassified):\n    img = load_img(val_gen.filepaths[idx])\n    plt.subplot(1, 5, i+1)\n    plt.imshow(img)\n    plt.title(f\"True: {true_labels[idx]}, Pred: {val_pred_classes[idx]}\")\n    plt.axis('off')\nplt.suptitle(\"Misclassified Images\", fontsize=16)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:43:35.859077Z","iopub.execute_input":"2023-08-13T10:43:35.859525Z","iopub.status.idle":"2023-08-13T10:43:36.716424Z","shell.execute_reply.started":"2023-08-13T10:43:35.859491Z","shell.execute_reply":"2023-08-13T10:43:36.715275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <font color='blue'>5. Fine-tuning and Optimization</font>","metadata":{}},{"cell_type":"markdown","source":"**Hyperparameter tuning was performed to find the optimal configuration for the model. I also explored transfer learning by leveraging the VGG16 model pre-trained on ImageNet. Regularization techniques were applied to prevent overfitting.**","metadata":{}},{"cell_type":"markdown","source":"## <font color='green'>5.1 Hyperparameter Tuning</font>","metadata":{}},{"cell_type":"code","source":"!pip install keras-tuner\n\nfrom kerastuner import RandomSearch\nfrom kerastuner.engine.hyperparameters import HyperParameters","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:44:46.565030Z","iopub.execute_input":"2023-08-13T10:44:46.566138Z","iopub.status.idle":"2023-08-13T10:45:01.440367Z","shell.execute_reply.started":"2023-08-13T10:44:46.566100Z","shell.execute_reply":"2023-08-13T10:45:01.439012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def build_model(hp):\n    model = Sequential()\n    \n    # Convolutional layers\n    model.add(Conv2D(hp.Int('input_units', min_value=32, max_value=64, step=32), (3, 3), activation='relu', input_shape=(IMG_WIDTH, IMG_HEIGHT, 3)))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    \n    for i in range(hp.Int('n_layers', 1, 3)):  # adding between 1 and 3 convolutional layers\n        model.add(Conv2D(hp.Int(f'conv_{i}_units', min_value=32, max_value=64, step=32), (3, 3), activation='relu'))\n        model.add(MaxPooling2D(pool_size=(2, 2)))\n    \n    # Fully connected layers\n    model.add(Flatten())\n    model.add(Dense(256, activation='relu'))\n    model.add(Dropout(0.5))\n    model.add(Dense(1, activation='sigmoid'))  # Binary classification\n    \n    optimizer = Adam(learning_rate=hp.Choice('learning_rate', [1e-3, 1e-4]))\n    model.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=['accuracy'])\n    \n    return model\n\ntuner = RandomSearch(\n    build_model,\n    objective='val_accuracy',\n    max_trials=3,  # reduced number of model configurations to test\n    executions_per_trial=1,\n    directory='output',\n    project_name='HistoPathologicCancerDetection'\n)\n\n# Train for fewer epochs during hyperparameter tuning\ntuner.search(train_gen, epochs=5, validation_data=val_gen)","metadata":{"execution":{"iopub.status.busy":"2023-08-13T10:48:16.256230Z","iopub.execute_input":"2023-08-13T10:48:16.256629Z","iopub.status.idle":"2023-08-13T11:12:11.718779Z","shell.execute_reply.started":"2023-08-13T10:48:16.256599Z","shell.execute_reply":"2023-08-13T11:12:11.717469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='green'>5.2 Transfer Learning</font>","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import VGG16\n\n# Load the VGG16 model with weights pre-trained on ImageNet\nbase_model = VGG16(weights='imagenet', include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))\n\n# Freeze the layers of the base model\nfor layer in base_model.layers:\n    layer.trainable = False\n\n# Create a custom model on top\nmodel = Sequential()\nmodel.add(base_model)\nmodel.add(Flatten())\nmodel.add(Dense(512, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(1, activation='sigmoid'))\n\nmodel.compile(optimizer=Adam(learning_rate=0.0001), loss='binary_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-08-13T11:12:39.751770Z","iopub.execute_input":"2023-08-13T11:12:39.752208Z","iopub.status.idle":"2023-08-13T11:12:40.876166Z","shell.execute_reply.started":"2023-08-13T11:12:39.752180Z","shell.execute_reply":"2023-08-13T11:12:40.875094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='green'>5.3 Regularization</font>","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import VGG16\nfrom tensorflow.keras.regularizers import l2\n\n# Load the VGG16 model with weights pre-trained on ImageNet\nbase_model = VGG16(weights='imagenet', include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, 3))\n\n# Freeze the layers of the base model\nfor layer in base_model.layers:\n    layer.trainable = False\n\nmodel = Sequential()\nmodel.add(base_model)\n\n# Convolutional layers\n# Removed pooling layers and adjusted convolutional layers\nmodel.add(Conv2D(32, (3, 3), activation='relu', kernel_regularizer=l2(0.01), padding='same'))\nmodel.add(Conv2D(64, (3, 3), activation='relu', kernel_regularizer=l2(0.01), padding='same'))\nmodel.add(Conv2D(128, (3, 3), activation='relu', kernel_regularizer=l2(0.01), padding='same'))\n\n# Fully connected layers\nmodel.add(Flatten())\nmodel.add(Dense(512, activation='relu', kernel_regularizer=l2(0.01)))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(1, activation='sigmoid'))  # Binary classification\n\noptimizer = Adam(learning_rate=0.0001)\nmodel.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-08-13T11:14:21.808268Z","iopub.execute_input":"2023-08-13T11:14:21.808689Z","iopub.status.idle":"2023-08-13T11:14:22.431900Z","shell.execute_reply.started":"2023-08-13T11:14:21.808656Z","shell.execute_reply":"2023-08-13T11:14:22.430558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <font color='blue'>6. Interpretation and Communication of Results</font>","metadata":{}},{"cell_type":"markdown","source":"**Visualizations were created to depict the training progress, showing how the loss and accuracy evolved over epochs. I also utilized Grad-CAM to provide insights into which regions of the images the model focuses on when making predictions.**","metadata":{}},{"cell_type":"markdown","source":"## <font color='green'>6.1 Visualization of Training Progress</font>","metadata":{}},{"cell_type":"code","source":"# Plotting training and validation loss and accuracy\nplt.figure(figsize=(12, 4))\n\nplt.subplot(1, 2, 1)\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\nplt.subplot(1, 2, 2)\nplt.plot(history.history['accuracy'], label='Training Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\nplt.legend()\nplt.title('Training and Validation Accuracy')\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-13T11:40:31.353943Z","iopub.execute_input":"2023-08-13T11:40:31.354367Z","iopub.status.idle":"2023-08-13T11:40:31.963867Z","shell.execute_reply.started":"2023-08-13T11:40:31.354335Z","shell.execute_reply":"2023-08-13T11:40:31.962685Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <font color='blue'>Conclusion:</font>\nAfter rigorous training, evaluation, and optimization, our model achieved an accuracy of **0.7944%**. While the model performs well, there's always room for improvement. Future work could explore deeper architectures, ensemble methods, or more advanced augmentation techniques.\n\n# <font color='blue'>References:</font>\n\nHistopathologic Cancer Detection Dataset","metadata":{}}]}