{"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":45867,"databundleVersionId":6924515,"sourceType":"competition"},{"sourceId":7257233,"sourceType":"datasetVersion","datasetId":4205493},{"sourceId":7269222,"sourceType":"datasetVersion","datasetId":4213842},{"sourceId":7279643,"sourceType":"datasetVersion","datasetId":4220768},{"sourceId":7285701,"sourceType":"datasetVersion","datasetId":4224849},{"sourceId":5861,"sourceType":"modelInstanceVersion","modelInstanceId":4634}],"dockerImageVersionId":30627,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 1. Import Libraries","metadata":{}},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings('ignore')\n\nimport pandas as pd\nimport numpy as np\nimport os\nfrom PIL import Image \nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import LabelBinarizer\nimport tensorflow as tf\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.models import Sequential, load_model\nfrom tensorflow.keras.layers import Dense, Conv2D , MaxPool2D , Flatten , Dropout , BatchNormalization, Activation, MaxPooling2D, GlobalAveragePooling2D\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import LearningRateScheduler, ModelCheckpoint\nfrom tensorflow.keras import layers, models\nfrom keras_core import ops\nimport matplotlib.pyplot as plt\n\nImage.MAX_IMAGE_PIXELS = 7000 * 7000","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:44:09.703732Z","iopub.execute_input":"2023-12-26T15:44:09.704127Z","iopub.status.idle":"2023-12-26T15:44:22.296949Z","shell.execute_reply.started":"2023-12-26T15:44:09.704098Z","shell.execute_reply":"2023-12-26T15:44:22.295966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = True","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:26:09.466888Z","iopub.execute_input":"2023-12-26T17:26:09.467854Z","iopub.status.idle":"2023-12-26T17:26:09.47196Z","shell.execute_reply.started":"2023-12-26T17:26:09.467818Z","shell.execute_reply":"2023-12-26T17:26:09.470989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. Inspect The Data","metadata":{}},{"cell_type":"code","source":"if not submission:\n    # Set the path to the train and test datasets\n    train_csv_path = \"/kaggle/input/UBC-OCEAN/train.csv\"\n    test_csv_path = \"/kaggle/input/UBC-OCEAN/test.csv\"\n\n    # Load the train and test CSV files\n    train_df = pd.read_csv(train_csv_path)\n    test_df = pd.read_csv(test_csv_path)\n\n    train_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:44:22.305362Z","iopub.execute_input":"2023-12-26T15:44:22.305715Z","iopub.status.idle":"2023-12-26T15:44:22.362923Z","shell.execute_reply.started":"2023-12-26T15:44:22.305682Z","shell.execute_reply":"2023-12-26T15:44:22.362175Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    train_df['label'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:44:22.365439Z","iopub.execute_input":"2023-12-26T15:44:22.366162Z","iopub.status.idle":"2023-12-26T15:44:22.380358Z","shell.execute_reply.started":"2023-12-26T15:44:22.366127Z","shell.execute_reply":"2023-12-26T15:44:22.379305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Dataset has a good amount of data belonging to 3 of the 5 classes. LGSC and MC are under-represented.","metadata":{}},{"cell_type":"code","source":"if not submission:\n    # Separate TMA images from WSI\n    train_df_tma = train_df[train_df['is_tma']==True]\n    train_df_wsi = train_df[train_df['is_tma']==False]\n\n    train_df_tma.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:44:22.381524Z","iopub.execute_input":"2023-12-26T15:44:22.381801Z","iopub.status.idle":"2023-12-26T15:44:22.396308Z","shell.execute_reply.started":"2023-12-26T15:44:22.381777Z","shell.execute_reply":"2023-12-26T15:44:22.395457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    train_df_wsi.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:44:22.398381Z","iopub.execute_input":"2023-12-26T15:44:22.398638Z","iopub.status.idle":"2023-12-26T15:44:22.406747Z","shell.execute_reply.started":"2023-12-26T15:44:22.398616Z","shell.execute_reply":"2023-12-26T15:44:22.405839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Append image paths to df\n    train_df_wsi['image_id_path'] = [f\"{i}_thumbnail.png\" for i in train_df_wsi['image_id']]\n    train_df_wsi.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:44:22.407846Z","iopub.execute_input":"2023-12-26T15:44:22.409893Z","iopub.status.idle":"2023-12-26T15:44:22.418433Z","shell.execute_reply.started":"2023-12-26T15:44:22.409868Z","shell.execute_reply":"2023-12-26T15:44:22.417579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Append image paths to df\n    train_df_tma['image_id_path'] = [f\"{i}.png\" for i in train_df_tma['image_id']]\n    train_df_tma.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:44:22.419446Z","iopub.execute_input":"2023-12-26T15:44:22.419765Z","iopub.status.idle":"2023-12-26T15:44:22.430598Z","shell.execute_reply.started":"2023-12-26T15:44:22.419741Z","shell.execute_reply":"2023-12-26T15:44:22.429882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3. Pre-process The Images","metadata":{}},{"cell_type":"code","source":"if not submission:\n    train_images_path = \"/kaggle/input/UBC-OCEAN/train_images/\"\n    test_images_path = \"/kaggle/input/UBC-OCEAN/test_images/\"\n\n    train_thumbnails_path = \"/kaggle/input/UBC-OCEAN/train_thumbnails/\"\n    test_thumbnails_path = \"/kaggle/input/UBC-OCEAN/test_thumbnails/\"","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:44:22.431462Z","iopub.execute_input":"2023-12-26T15:44:22.431781Z","iopub.status.idle":"2023-12-26T15:44:22.441443Z","shell.execute_reply.started":"2023-12-26T15:44:22.431748Z","shell.execute_reply":"2023-12-26T15:44:22.440627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    data = []\n    labels = []\n    # Pair the images and labels for both the thumbnails and images. The images will be resized and converted to RGB format\n    for img , label in zip(train_df_wsi['image_id_path'],train_df_wsi['label']):\n        try:\n            # Opens the image\n            image = Image.open(train_thumbnails_path+img)\n            # Resizes to 480x480 for now\n            image = image.resize((600,600))\n            # RGB format\n            image = image.convert(\"RGB\")\n            # Converts to an NumPy array\n            image = np.array(image)\n            # Appends to the array of data and images\n            data.append(image)\n            labels.append(label)\n        except:\n            print(\"Failed to train WSI image\")\n\n    for img , label in zip(train_df_tma['image_id_path'],train_df_tma['label']):\n        try:\n            image = Image.open(train_images_path+img)\n            image = image.resize((600,600))\n            image = image.convert(\"RGB\")\n            image = np.array(image)\n            data.append(image)\n            labels.append(label)\n        except:\n            print(\"Failed to train TMA image\")","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:46:57.599287Z","iopub.execute_input":"2023-12-26T15:46:57.599594Z","iopub.status.idle":"2023-12-26T15:49:04.582436Z","shell.execute_reply.started":"2023-12-26T15:46:57.599568Z","shell.execute_reply":"2023-12-26T15:49:04.581417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:    \n    print(len(labels))\n    print(data[0].shape)","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:49:04.583769Z","iopub.execute_input":"2023-12-26T15:49:04.584094Z","iopub.status.idle":"2023-12-26T15:49:04.589251Z","shell.execute_reply.started":"2023-12-26T15:49:04.584047Z","shell.execute_reply":"2023-12-26T15:49:04.588375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Scale the data\n    scaled_data = np.array(data)/255","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:49:04.590402Z","iopub.execute_input":"2023-12-26T15:49:04.590718Z","iopub.status.idle":"2023-12-26T15:49:06.228146Z","shell.execute_reply.started":"2023-12-26T15:49:04.590684Z","shell.execute_reply":"2023-12-26T15:49:06.227314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    scaled_data.shape","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:49:06.229266Z","iopub.execute_input":"2023-12-26T15:49:06.22956Z","iopub.status.idle":"2023-12-26T15:49:06.233923Z","shell.execute_reply.started":"2023-12-26T15:49:06.229535Z","shell.execute_reply":"2023-12-26T15:49:06.233001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Do the same for test set","metadata":{"execution":{"iopub.status.busy":"2023-12-23T16:30:09.871613Z","iopub.execute_input":"2023-12-23T16:30:09.872496Z","iopub.status.idle":"2023-12-23T16:30:09.878905Z","shell.execute_reply.started":"2023-12-23T16:30:09.87245Z","shell.execute_reply":"2023-12-23T16:30:09.877484Z"}}},{"cell_type":"code","source":"if not submission:\n    test_data = []\n\n    for img in os.listdir(test_thumbnails_path):\n        try:\n            image = Image.open(test_thumbnails_path+img)\n            image = image.resize((480,480))\n            image = image.convert(\"RGB\")\n            image = np.array(image)\n            test_data.append(image)\n        except:\n            print(\"Failed to process test data\")\n    scaled_test_data = np.array(test_data)","metadata":{"execution":{"iopub.status.busy":"2023-12-25T18:02:06.8053Z","iopub.execute_input":"2023-12-25T18:02:06.805571Z","iopub.status.idle":"2023-12-25T18:02:07.080094Z","shell.execute_reply.started":"2023-12-25T18:02:06.805548Z","shell.execute_reply":"2023-12-25T18:02:07.079168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    scaled_test_data.shape","metadata":{"execution":{"iopub.status.busy":"2023-12-25T18:02:07.08148Z","iopub.execute_input":"2023-12-25T18:02:07.081873Z","iopub.status.idle":"2023-12-25T18:02:07.086845Z","shell.execute_reply.started":"2023-12-25T18:02:07.081836Z","shell.execute_reply":"2023-12-25T18:02:07.085898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 4. Split The Images","metadata":{}},{"cell_type":"code","source":"if not submission:\n    # One hot encoding\n    label_binarizer = LabelBinarizer()\n\n    # Fit and transform the labels\n    labels_one_hot = label_binarizer.fit_transform(labels)\n\n    # Convert the result to a list if needed\n    labels_one_hot_list = labels_one_hot.tolist()\n\n    # Convert to a NumPy array if needed\n    labels_one_hot_array = np.array(labels_one_hot_list)","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:49:06.235238Z","iopub.execute_input":"2023-12-26T15:49:06.235511Z","iopub.status.idle":"2023-12-26T15:49:06.251866Z","shell.execute_reply.started":"2023-12-26T15:49:06.235488Z","shell.execute_reply":"2023-12-26T15:49:06.251018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    len(labels_one_hot_array)","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:49:06.252979Z","iopub.execute_input":"2023-12-26T15:49:06.253287Z","iopub.status.idle":"2023-12-26T15:49:06.257677Z","shell.execute_reply.started":"2023-12-26T15:49:06.253258Z","shell.execute_reply":"2023-12-26T15:49:06.256703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Split the data\n    X_train, X_val, y_train, y_val = train_test_split(scaled_data, labels_one_hot_array, test_size=0.2, random_state=69)","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:49:06.26045Z","iopub.execute_input":"2023-12-26T15:49:06.260749Z","iopub.status.idle":"2023-12-26T15:49:07.885232Z","shell.execute_reply.started":"2023-12-26T15:49:06.260723Z","shell.execute_reply":"2023-12-26T15:49:07.884444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Ensure the shape matches\n    print(X_train.shape)\n    print(y_train.shape)\n    print(X_val.shape)\n    print(y_val.shape)","metadata":{"execution":{"iopub.status.busy":"2023-12-26T15:49:07.886408Z","iopub.execute_input":"2023-12-26T15:49:07.886668Z","iopub.status.idle":"2023-12-26T15:49:07.892114Z","shell.execute_reply.started":"2023-12-26T15:49:07.886646Z","shell.execute_reply":"2023-12-26T15:49:07.891109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 5. Create A Model","metadata":{}},{"cell_type":"code","source":"# Define Residual Block\ndef residual_block(x, filters, kernel_size=3, stride=1):\n    shortcut = x\n\n    x = layers.Conv2D(filters, kernel_size, strides=stride, padding='same')(x)\n    x = layers.BatchNormalization()(x)\n    x = layers.Activation('relu')(x)\n\n    x = layers.Dropout(0.4)(x)\n\n    x = layers.Conv2D(filters, kernel_size, padding='same')(x)\n    x = layers.BatchNormalization()(x)\n\n    # Use 1x1 convolution for shortcut if the dimensions don't match\n    if stride != 1 or shortcut.shape[-1] != filters:\n        shortcut = layers.Conv2D(filters, 1, strides=stride, padding='same')(shortcut)\n        shortcut = layers.BatchNormalization()(shortcut)\n\n    x = layers.Add()([x, shortcut])\n    x = layers.Activation('relu')(x)\n\n    return x\n\n# Build ResNet50 model\ndef build_resnet50(input_shape, num_classes):\n    input_tensor = layers.Input(shape=input_shape)\n\n    x = layers.Conv2D(64, 7, strides=2, padding='same')(input_tensor)\n    x = layers.BatchNormalization()(x)\n    x = layers.Activation('relu')(x)\n    x = layers.MaxPooling2D(3, strides=2, padding='same')(x)\n\n    # Residual blocks\n    x = residual_block(x, 64)\n    x = residual_block(x, 64)\n    x = residual_block(x, 128, stride=2)\n    x = residual_block(x, 128)\n    x = residual_block(x, 256, stride=2)\n    x = residual_block(x, 256)\n    x = residual_block(x, 512, stride=2)\n    x = residual_block(x, 512)\n\n    x = layers.GlobalAveragePooling2D()(x)\n    x = layers.Dense(num_classes, activation='softmax')(x)\n\n    model = models.Model(inputs=input_tensor, outputs=x, name='resnet50')\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-12-23T23:40:54.174744Z","iopub.execute_input":"2023-12-23T23:40:54.175147Z","iopub.status.idle":"2023-12-23T23:40:54.190113Z","shell.execute_reply.started":"2023-12-23T23:40:54.175109Z","shell.execute_reply":"2023-12-23T23:40:54.189111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Build the ResNet50 model\n    resnet50_model = build_resnet50(input_shape=(480, 480, 3), num_classes=5)\n\n    # Compile the model\n    resnet50_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-12-23T23:40:54.191421Z","iopub.execute_input":"2023-12-23T23:40:54.191795Z","iopub.status.idle":"2023-12-23T23:40:58.789967Z","shell.execute_reply.started":"2023-12-23T23:40:54.19176Z","shell.execute_reply":"2023-12-23T23:40:58.789204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Callbacks that will be used\n\n    # Define a callback to save the best model weights\n    checkpoint_path = \"best_model_resnet_checkpoints.h5\"\n    checkpoint_callback = ModelCheckpoint(checkpoint_path, monitor='val_accuracy', save_best_only=True, mode='max', verbose=1)\n\n    # Define the learning rate schedule function\n    def lr_schedule(epoch):\n        \"\"\"Learning Rate Schedule\n\n        # Arguments\n            epoch (int): The number of epochs\n\n        # Returns\n            lr (float32): learning rate\n        \"\"\"\n        lr = 0.001  # Initial learning rate\n\n        if epoch > 19:\n            lr *= 0.1\n        if epoch > 39:\n            lr *= 0.1\n\n        return lr\n\n    # Define the learning rate scheduler callback\n    lr_scheduler = LearningRateScheduler(lr_schedule)","metadata":{"execution":{"iopub.status.busy":"2023-12-23T23:40:58.791105Z","iopub.execute_input":"2023-12-23T23:40:58.791384Z","iopub.status.idle":"2023-12-23T23:40:58.797795Z","shell.execute_reply.started":"2023-12-23T23:40:58.791358Z","shell.execute_reply":"2023-12-23T23:40:58.796888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Train the model\n    history = resnet50_model.fit(\n            X_train, y_train,\n            epochs=50,\n            validation_data=(X_val, y_val),\n            callbacks=[checkpoint_callback, lr_scheduler]\n        )","metadata":{"execution":{"iopub.status.busy":"2023-12-23T23:40:58.798905Z","iopub.execute_input":"2023-12-23T23:40:58.79919Z","iopub.status.idle":"2023-12-23T23:48:52.923098Z","shell.execute_reply.started":"2023-12-23T23:40:58.799165Z","shell.execute_reply":"2023-12-23T23:48:52.922118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Plot the results\n    plt.plot(history.history['accuracy'])\n    plt.plot(history.history['val_accuracy'])\n    plt.legend(['train','valid'])\n    plt.title('Accuracy')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-23T23:49:14.227658Z","iopub.execute_input":"2023-12-23T23:49:14.228044Z","iopub.status.idle":"2023-12-23T23:49:14.572862Z","shell.execute_reply.started":"2023-12-23T23:49:14.228014Z","shell.execute_reply":"2023-12-23T23:49:14.571781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 5.1 Transfer Learning - DenseNet201","metadata":{}},{"cell_type":"code","source":"if not submission:\n    from tensorflow.keras.applications import DenseNet201\n\n    # Using DenseNet201 as the base model\n    weights_path = \"/kaggle/input/densenet201-weights/densenet201_weights_tf_dim_ordering_tf_kernels_notop.h5\"\n    base_model = DenseNet201(weights=weights_path, include_top=False, input_shape=(480, 480, 3))\n\n    # Adding extra layers to integrate our custom dataset\n    model = Sequential([\n        base_model,\n        GlobalAveragePooling2D(),\n        BatchNormalization(),\n        Dense(1024, activation='relu'),\n        Dropout(0.1),\n        Dense(512, activation='relu'),\n        Dropout(0.1),\n        Dense(256, activation='relu'),\n        Dense(5, activation='softmax')  # Adjust the number of output classes based on your problem\n    ])\n    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-12-25T19:26:42.314184Z","iopub.execute_input":"2023-12-25T19:26:42.314966Z","iopub.status.idle":"2023-12-25T19:26:50.82074Z","shell.execute_reply.started":"2023-12-25T19:26:42.314931Z","shell.execute_reply":"2023-12-25T19:26:50.819871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-25T19:26:50.822202Z","iopub.execute_input":"2023-12-25T19:26:50.824328Z","iopub.status.idle":"2023-12-25T19:26:50.921783Z","shell.execute_reply.started":"2023-12-25T19:26:50.824299Z","shell.execute_reply":"2023-12-25T19:26:50.920856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Callbacks that will be used\n\n    # Define a callback to save the best model weights\n    checkpoint_path = \"best_model_densenet201_checkpoints.h5\"\n    checkpoint_callback = ModelCheckpoint(checkpoint_path, monitor='val_accuracy', save_best_only=True, mode='max', verbose=1)\n\n    # Define the learning rate schedule function\n    def lr_schedule(epoch):\n        \"\"\"Learning Rate Schedule\n\n        # Arguments\n            epoch (int): The number of epochs\n\n        # Returns\n            lr (float32): learning rate\n        \"\"\"\n        lr = 0.001  # Initial learning rate\n\n        if epoch > 29:\n            lr *= 0.1\n        if epoch > 69:\n            lr *= 0.1\n\n        return lr\n\n    # Define the learning rate scheduler callback\n    lr_scheduler = LearningRateScheduler(lr_schedule)","metadata":{"execution":{"iopub.status.busy":"2023-12-25T19:26:50.923136Z","iopub.execute_input":"2023-12-25T19:26:50.923522Z","iopub.status.idle":"2023-12-25T19:26:50.930716Z","shell.execute_reply.started":"2023-12-25T19:26:50.923487Z","shell.execute_reply":"2023-12-25T19:26:50.929564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n    # Define ImageDataGenerator for data augmentation\n    train_datagen = ImageDataGenerator(\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        vertical_flip=True,\n        fill_mode='nearest'\n    )\n\n    # Create image generators\n    train_generator = train_datagen.flow(\n        X_train,\n        y_train,\n        batch_size=8,\n        shuffle=True,\n        seed=42\n    )","metadata":{"execution":{"iopub.status.busy":"2023-12-25T19:28:42.411723Z","iopub.execute_input":"2023-12-25T19:28:42.412127Z","iopub.status.idle":"2023-12-25T19:28:42.886709Z","shell.execute_reply.started":"2023-12-25T19:28:42.412095Z","shell.execute_reply":"2023-12-25T19:28:42.885872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Train the model\n    history = model.fit(\n            train_generator,\n            epochs=80,\n            validation_data=(X_val, y_val),\n            callbacks=[checkpoint_callback, lr_scheduler]\n        )","metadata":{"execution":{"iopub.status.busy":"2023-12-25T19:29:09.875024Z","iopub.execute_input":"2023-12-25T19:29:09.875656Z","iopub.status.idle":"2023-12-25T20:02:43.692313Z","shell.execute_reply.started":"2023-12-25T19:29:09.875622Z","shell.execute_reply":"2023-12-25T20:02:43.69127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Plot the results\n    plt.plot(history.history['accuracy'])\n    plt.plot(history.history['val_accuracy'])\n    plt.legend(['train','valid'])\n    plt.title('Accuracy')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-25T20:17:26.570985Z","iopub.execute_input":"2023-12-25T20:17:26.571439Z","iopub.status.idle":"2023-12-25T20:17:26.817967Z","shell.execute_reply.started":"2023-12-25T20:17:26.571382Z","shell.execute_reply":"2023-12-25T20:17:26.816809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 5.2 EfficientNetV2B3","metadata":{}},{"cell_type":"code","source":"if not submission:\n    from tensorflow.keras.applications import EfficientNetV2B3 \n    \n    # Using DenseNet201 as the base model\n    base_model = EfficientNetV2B3 (weights='imagenet', include_top=False, input_shape=(600, 600, 3))\n\n    # Adding extra layers to integrate our custom dataset\n    model = Sequential([\n        base_model,\n        GlobalAveragePooling2D(),\n        BatchNormalization(),\n        Dense(2048, activation='relu'),\n        Dropout(0.3),\n        Dense(1024, activation='relu'),\n        Dropout(0.3),\n        Dense(512, activation='relu'),\n        Dense(5, activation='softmax')  # Adjust the number of output classes based on your problem\n    ])\n    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:02:27.438132Z","iopub.execute_input":"2023-12-26T17:02:27.438532Z","iopub.status.idle":"2023-12-26T17:02:33.962782Z","shell.execute_reply.started":"2023-12-26T17:02:27.438502Z","shell.execute_reply":"2023-12-26T17:02:33.961756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Callbacks that will be used\n\n    # Define a callback to save the best model weights\n    checkpoint_path = \"best_model_EffNetV2B3_checkpoints.h5\"\n    checkpoint_callback = ModelCheckpoint(checkpoint_path, monitor='val_accuracy', save_best_only=True, mode='max', verbose=1)\n\n    # Define the learning rate schedule function\n    def lr_schedule(epoch):\n        \"\"\"Learning Rate Schedule\n\n        # Arguments\n            epoch (int): The number of epochs\n\n        # Returns\n            lr (float32): learning rate\n        \"\"\"\n        lr = 0.0001  # Initial learning rate\n\n        if epoch > 9:\n            lr *= 0.1\n        if epoch > 19:\n            lr *= 0.1\n\n        return lr\n\n    # Define the learning rate scheduler callback\n    lr_scheduler = LearningRateScheduler(lr_schedule)","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:02:33.964414Z","iopub.execute_input":"2023-12-26T17:02:33.964712Z","iopub.status.idle":"2023-12-26T17:02:33.970927Z","shell.execute_reply.started":"2023-12-26T17:02:33.964688Z","shell.execute_reply":"2023-12-26T17:02:33.970016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n    # Define ImageDataGenerator for data augmentation\n    train_datagen = ImageDataGenerator(\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        fill_mode='nearest'\n    )\n\n    # Create image generators\n    train_generator = train_datagen.flow(\n        X_train,\n        y_train,\n        batch_size=8,\n        shuffle=True,\n        seed=42\n    )","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:02:33.97199Z","iopub.execute_input":"2023-12-26T17:02:33.972334Z","iopub.status.idle":"2023-12-26T17:02:35.085727Z","shell.execute_reply.started":"2023-12-26T17:02:33.972309Z","shell.execute_reply":"2023-12-26T17:02:35.084809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Train the model\n    history = model.fit(\n            train_generator,\n            epochs=30,\n            validation_data=(X_val, y_val),\n            callbacks=[checkpoint_callback, lr_scheduler]\n        )","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:02:35.08777Z","iopub.execute_input":"2023-12-26T17:02:35.08815Z","iopub.status.idle":"2023-12-26T17:20:57.118207Z","shell.execute_reply.started":"2023-12-26T17:02:35.088121Z","shell.execute_reply":"2023-12-26T17:20:57.117116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not submission:\n    # Plot the results\n    plt.plot(history.history['accuracy'])\n    plt.plot(history.history['val_accuracy'])\n    plt.legend(['train','valid'])\n    plt.title('Accuracy')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:23:28.818372Z","iopub.execute_input":"2023-12-26T17:23:28.819347Z","iopub.status.idle":"2023-12-26T17:23:29.083973Z","shell.execute_reply.started":"2023-12-26T17:23:28.819312Z","shell.execute_reply":"2023-12-26T17:23:29.083099Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 6. Predictions","metadata":{}},{"cell_type":"code","source":"if submission:\n    try:\n        test_thumbnail_path = \"/kaggle/input/UBC-OCEAN/test_thumbnails\"\n        test_csv_path = \"/kaggle/input/UBC-OCEAN/test.csv\"\n        df = pd.read_csv(test_csv_path)\n        df[\"image_path\"] = df[\"image_id\"].apply(lambda x: f\"{test_thumbnail_path}/{x}_thumbnail.png\")\n        df.head()\n    except:\n        print(\"Failed to read test thumbnails and CSV\")","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:28:37.039023Z","iopub.execute_input":"2023-12-26T17:28:37.039845Z","iopub.status.idle":"2023-12-26T17:28:37.051663Z","shell.execute_reply.started":"2023-12-26T17:28:37.039813Z","shell.execute_reply":"2023-12-26T17:28:37.050766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if submission:\n    # Load the best weights\n    loaded_model = load_model(\"/kaggle/input/ubc-ocean-tf-effnet/best_model_EffNetV2B3_checkpoints.h5\")","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:28:53.479795Z","iopub.execute_input":"2023-12-26T17:28:53.480213Z","iopub.status.idle":"2023-12-26T17:29:04.128102Z","shell.execute_reply.started":"2023-12-26T17:28:53.480182Z","shell.execute_reply":"2023-12-26T17:29:04.127121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if submission:\n    def read_image(path):\n        file = tf.io.read_file(path)\n        image = tf.io.decode_png(file, 3)\n        image = tf.image.resize(image, (600, 600))\n        image = tf.image.per_image_standardization(image)\n        return image","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:29:04.130508Z","iopub.execute_input":"2023-12-26T17:29:04.130861Z","iopub.status.idle":"2023-12-26T17:29:04.136566Z","shell.execute_reply.started":"2023-12-26T17:29:04.130834Z","shell.execute_reply":"2023-12-26T17:29:04.135477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if submission:\n    predicted_labels = []\n    class_labels = ['CC', 'EC', 'HGSC', 'LGSC', 'MC']\n\n    for index, row in df.iterrows():\n        # Get the image path\n        image_path = row[\"image_path\"]\n\n        try:\n            # Get the image\n            image = read_image(image_path)[None, ...]\n        except:\n            print(\"Failed to make inference\")\n\n        try:\n            # Predict the label\n            predictions = loaded_model.predict(image)\n            pred = [np.argmax(i) for i in predictions]\n#             print(class_labels[pred[0]])\n\n            # Map the pred to the name\n            label = class_labels[pred[0]]\n\n            predicted_labels.append(label)\n        except:\n            print(\"Failed to make prediction\")\n\n    # Add the predicted labels to the csv\n    df[\"label\"] = predicted_labels","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:29:58.720143Z","iopub.execute_input":"2023-12-26T17:29:58.720871Z","iopub.status.idle":"2023-12-26T17:29:58.936365Z","shell.execute_reply.started":"2023-12-26T17:29:58.720841Z","shell.execute_reply":"2023-12-26T17:29:58.935483Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if submission:\n    # Create the submission\n    submission_df = df[[\"image_id\", \"label\"]]\n    submission_df.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:30:00.734749Z","iopub.execute_input":"2023-12-26T17:30:00.735785Z","iopub.status.idle":"2023-12-26T17:30:00.74283Z","shell.execute_reply.started":"2023-12-26T17:30:00.735738Z","shell.execute_reply":"2023-12-26T17:30:00.741687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if submission:\n    submission_df","metadata":{"execution":{"iopub.status.busy":"2023-12-26T17:30:02.214726Z","iopub.execute_input":"2023-12-26T17:30:02.215115Z","iopub.status.idle":"2023-12-26T17:30:02.219381Z","shell.execute_reply.started":"2023-12-26T17:30:02.215086Z","shell.execute_reply":"2023-12-26T17:30:02.218391Z"},"trusted":true},"execution_count":null,"outputs":[]}]}