{"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":"none","dataSources":[{"sourceId":45867,"databundleVersionId":6924515,"sourceType":"competition"},{"sourceId":3731,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":2658}],"dockerImageVersionId":30588,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Optional Assignment on UBC Ovarian Cancer Subtype Classification and Outlier Detection (UBC-OCEAN)\n\n## Team Members:\n\n### Sujay Shrivastava - 50496221\n\n### Venkata Lakshmi Krishna Tejaswi Gudimetla - 50496378","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nfrom PIL import Image\nfrom scipy.signal import find_peaks, savgol_filter\nimport seaborn as sns\nimport os\nimport random\nimport cv2 as cv\nimport matplotlib.patches as patches\nimport re\n\n\n\nimport os\nimport gc\n# import cv2\nimport math\nimport copy\nimport time\nimport random\nimport glob\nfrom matplotlib import pyplot as plt\n\n# For data manipulation\nimport numpy as np\nimport pandas as pd\n\n# Pytorch Imports\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.optim import lr_scheduler\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.cuda import amp\nimport torchvision\n\n# Utils\nimport joblib\nfrom tqdm import tqdm\nfrom collections import defaultdict\n\n# Sklearn Imports\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.metrics import balanced_accuracy_score, confusion_matrix, f1_score\n\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\n# For Image Models\nimport timm\n\n# Albumentations for augmentations\n# import albumentations as A\n# from albumentations.pytorch import ToTensorV2\n\n# For colored terminal text\nfrom colorama import Fore, Back, Style\nb_ = Fore.BLUE\nsr_ = Style.RESET_ALL\n\nimport warnings\n# warnings.filterwarnings(\"ignore\")\n\n# For descriptive error messages\nos.environ['CUDA_LAUNCH_BLOCKING'] = \"1\"","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:21.986304Z","iopub.execute_input":"2023-12-06T04:05:21.986764Z","iopub.status.idle":"2023-12-06T04:05:21.998049Z","shell.execute_reply.started":"2023-12-06T04:05:21.98672Z","shell.execute_reply":"2023-12-06T04:05:21.996353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set random seed\nrandom.seed(41)\n\n# Set max pixels\nImage.MAX_IMAGE_PIXELS = None","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.021235Z","iopub.execute_input":"2023-12-06T04:05:22.021885Z","iopub.status.idle":"2023-12-06T04:05:22.026575Z","shell.execute_reply.started":"2023-12-06T04:05:22.02185Z","shell.execute_reply":"2023-12-06T04:05:22.025631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We stored the directory in variables for easy access.","metadata":{}},{"cell_type":"code","source":"ROOT_DIR = '/kaggle/input/UBC-OCEAN'\nTRAIN_DIR = '/kaggle/input/UBC-OCEAN/train_thumbnails'\nTEST_DIR = '/kaggle/input/UBC-OCEAN/test_thumbnails'\nALT_TEST_DIR = '/kaggle/input/UBC-OCEAN/test_images'\nTMA_TRAIN_DIR = '/kaggle/input/UBC-OCEAN/train_images'","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.028275Z","iopub.execute_input":"2023-12-06T04:05:22.028903Z","iopub.status.idle":"2023-12-06T04:05:22.041342Z","shell.execute_reply.started":"2023-12-06T04:05:22.028876Z","shell.execute_reply":"2023-12-06T04:05:22.039691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train annotations overview\ntrain_df = pd.read_csv(TRAIN_ANN_PATH)\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.043714Z","iopub.execute_input":"2023-12-06T04:05:22.044021Z","iopub.status.idle":"2023-12-06T04:05:22.066825Z","shell.execute_reply.started":"2023-12-06T04:05:22.043997Z","shell.execute_reply":"2023-12-06T04:05:22.065951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Since it would be very difficult and non efficient to pass the path at the time of training, we decided to put the path to the image in the data itself, so it would be easy and fast to access.","metadata":{}},{"cell_type":"code","source":"def path_column(image_id, path=\"/kaggle/input/UBC-OCEAN/train_images/\"):\n    return path + str(image_id) + \".png\"\n\ntrain_df[\"file_path\"] = train_df[\"image_id\"].map(path_column)","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.068537Z","iopub.execute_input":"2023-12-06T04:05:22.069791Z","iopub.status.idle":"2023-12-06T04:05:22.077148Z","shell.execute_reply.started":"2023-12-06T04:05:22.06975Z","shell.execute_reply":"2023-12-06T04:05:22.075114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We made this config to call any constant using the same diction so we don;t need to call anything again and again.","metadata":{"execution":{"iopub.status.busy":"2023-12-06T03:31:05.885591Z","iopub.execute_input":"2023-12-06T03:31:05.886346Z","iopub.status.idle":"2023-12-06T03:31:12.365748Z","shell.execute_reply.started":"2023-12-06T03:31:05.886305Z","shell.execute_reply":"2023-12-06T03:31:12.364339Z"}}},{"cell_type":"code","source":"CONFIG = {\n    \"is_submission\": False,                # Flag for submission or validation\n    \"n_fold\": 5,                           # Number of folds for cross-validation\n    'fold': 1,                             # Current fold\n    \"seed\": 42,                            # Random seed\n    \"img_size\": 512,                       # Image size (height and width)\n    \"crop_vertical\":True,                  # Crop images vertically\n    \"model_name\": \"tf_efficientnet_b0_ns\", # Model name\n    \"num_classes\": 5,                      # Number of classification classes\n    \"valid_batch_size\": 16,                # Validation batch size\n    \"device\": torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\"),  # Device (GPU or CPU)\n#     \"model_path\" : \"/kaggle/input/tf-efficientnet/pytorch/tf-efficientnet-b2/1/tf_efficientnet_b2_aa-60c94f97.pth\"   # Pre-trained model path\n#     \"encoder_path\": \"/kaggle/input/tf-efficientnet/pytorch/tf-efficientnet-b2/1/tf_efficientnet_b2_aa-60c94f97.pth\"  # Pre-trained model path\n}","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.078925Z","iopub.execute_input":"2023-12-06T04:05:22.079299Z","iopub.status.idle":"2023-12-06T04:05:22.094751Z","shell.execute_reply.started":"2023-12-06T04:05:22.079254Z","shell.execute_reply":"2023-12-06T04:05:22.092631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"defined Functions to map to dataset to store the file path. (better than traversing the entire data column and then adding it in new column) ","metadata":{}},{"cell_type":"code","source":"def get_train_file_path(df_train_row):\n    if df_train_row.is_tma == False:\n        return f\"{TRAIN_DIR}/{df_train_row.image_id}_thumbnail.png\"\n    else:\n        return f\"{TMA_TRAIN_DIR}/{df_train_row.image_id}.png\"\n\n\n\ndef get_test_file_path(image_id):\n    if os.path.exists(f\"{TEST_DIR}/{image_id}_thumbnail.png\"):\n        return f\"{TEST_DIR}/{image_id}_thumbnail.png\"\n    else:\n        return f\"{ALT_TEST_DIR}/{image_id}.png\"\n","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.09777Z","iopub.execute_input":"2023-12-06T04:05:22.098376Z","iopub.status.idle":"2023-12-06T04:05:22.107364Z","shell.execute_reply.started":"2023-12-06T04:05:22.098345Z","shell.execute_reply":"2023-12-06T04:05:22.105735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test = pd.read_csv(\"/kaggle/input/UBC-OCEAN/test.csv\")\ndf_test['file_path'] = df_test['image_id'].apply(get_test_file_path)\ndf_test[\"target_label\"] = 0 \ndf_test","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.108891Z","iopub.execute_input":"2023-12-06T04:05:22.110151Z","iopub.status.idle":"2023-12-06T04:05:22.131046Z","shell.execute_reply.started":"2023-12-06T04:05:22.110114Z","shell.execute_reply":"2023-12-06T04:05:22.130143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now, some functions to do the preprocessing before ingesting the data in the model","metadata":{}},{"cell_type":"markdown","source":"Also, we tried to used numpy instead of tensors because of their mutablity, if at the last we want better performance then we could convert all these to tensors","metadata":{"execution":{"iopub.status.busy":"2023-12-06T03:47:00.445751Z","iopub.execute_input":"2023-12-06T03:47:00.446192Z","iopub.status.idle":"2023-12-06T03:47:00.45536Z","shell.execute_reply.started":"2023-12-06T03:47:00.446133Z","shell.execute_reply":"2023-12-06T03:47:00.452982Z"}}},{"cell_type":"code","source":"class UBCDataset(Dataset):\n    def __init__(self, df, transforms=None):\n        self.df = df\n        self.filenames = df.file_path.values\n        self.labels =  df.target_label.values\n        self.transforms = transforms\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        img_path = self.filenames[idx]\n        img = cv2.imread(img_path)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        \n        if CONFIG[\"crop_vertical\"]:\n            img = crop_vertical(img)\n        \n        # img = custom_center_crop_or_resize(img, (1024, 1024))\n        \n        if self.transforms:\n            img = self.transforms(image=img)[\"image\"]\n            \n        return {\n            \"image\": img,\n            \"label\": torch.tensor(self.labels[idx], dtype=torch.long)\n               }\n    \ndef crop_vertical(image):\n    \"\"\"\n    Function crops images if multiple slices contained and separated by black vertical background.\n    \"\"\"\n    vertical_sum = np.sum(image, axis=(0, 2))\n\n    # Identify the positions where the sum is zero\n    zero_positions = np.where(vertical_sum == 0)[0]\n\n    if len(zero_positions)==0:\n        cropped_images = [image]\n    else:\n        # If the image does not start with a black area, add index 0\n        if zero_positions[0] != 0:\n            zero_positions = np.insert(zero_positions, 0, 0)\n\n        # If the image does not end with a black area, add the image width\n        if zero_positions[-1] != image.shape[1] - 1:\n            zero_positions = np.append(zero_positions, image.shape[1] - 1)\n\n        start_idx = zero_positions[0]\n        cropped_images = []\n\n        for idx in range(1, len(zero_positions)):\n            end_idx = zero_positions[idx]\n            if end_idx - start_idx > 1:  # If the width of the cropped section is greater than 1\n                cropped = image[:, start_idx:end_idx]\n                # only include samples which are of min size\n                if cropped.shape[1]>200:  \n                    cropped_images.append(cropped)\n                    # cv2.imwrite(f\"{save_prefix}_{idx}.jpg\", cropped)\n            start_idx = end_idx\n            \n\ndef crop_vertical(image):\n    \"\"\"\n    Function crops images if multiple slices contained and separated by black vertical background.\n    \"\"\"\n    vertical_sum = np.sum(image, axis=(0, 2))\n\n    # Identify the positions where the sum is zero\n    zero_positions = np.where(vertical_sum == 0)[0]\n\n    if len(zero_positions)==0:\n        cropped_images = [image]\n    else:\n        # If the image does not start with a black area, add index 0\n        if zero_positions[0] != 0:\n            zero_positions = np.insert(zero_positions, 0, 0)\n\n        # If the image does not end with a black area, add the image width\n        if zero_positions[-1] != image.shape[1] - 1:\n            zero_positions = np.append(zero_positions, image.shape[1] - 1)\n\n        start_idx = zero_positions[0]\n        cropped_images = []\n\n        for idx in range(1, len(zero_positions)):\n            end_idx = zero_positions[idx]\n            if end_idx - start_idx > 1:  # If the width of the cropped section is greater than 1\n                cropped = image[:, start_idx:end_idx]\n                # only include samples which are of min size\n                if cropped.shape[1]>200:  \n                    cropped_images.append(cropped)\n#                     print(cropped.shape)\n                    # cv2.imwrite(f\"{save_prefix}_{idx}.jpg\", cropped)\n            start_idx = end_idx\n    final_crops = []\n    # remove black bars above/below the crops \n    for cropped in cropped_images:\n        horizontal_sum = np.sum(cropped, axis=(1, 2))\n#         print(horizontal_sum)\n        zero_positions = np.where(horizontal_sum == 0)[0]\n        img_ = np.delete(cropped, zero_positions, axis=0)\n        final_crops.append(img_)\n    if len(final_crops)==0:\n        return image\n    return final_crops[0]\n\n\ndef custom_center_crop_or_resize(image, crop_size):\n    # If both dimensions of the image are greater than or equal to the desired size, apply CenterCrop\n    if image.shape[0] >= crop_size[0] and image.shape[1] >= crop_size[1]:\n        return A.CenterCrop(crop_size[0], crop_size[1])(image=image)[\"image\"]\n    # Else, just resize the image to the desired size\n    else:\n        return A.Resize(crop_size[0], crop_size[1])(image=image)[\"image\"]","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.132967Z","iopub.execute_input":"2023-12-06T04:05:22.133756Z","iopub.status.idle":"2023-12-06T04:05:22.152888Z","shell.execute_reply.started":"2023-12-06T04:05:22.133715Z","shell.execute_reply":"2023-12-06T04:05:22.15115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_transforms = {\n    \"train\": A.Compose([\n        A.RandomResizedCrop(CONFIG['img_size'], CONFIG['img_size'], scale=(0.8, 1.0)),\n        A.HorizontalFlip(p=0.5),\n        A.RandomBrightnessContrast(p=0.2),\n        A.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.2, rotate_limit=15, p=0.2),\n        A.HueSaturationValue(hue_shift_limit=20, sat_shift_limit=30, val_shift_limit=20, p=0.5),\n        A.CoarseDropout(p=0.2),\n        A.Cutout(p=0.2),\n        A.Normalize(\n            mean=[0.485, 0.456, 0.406], \n            std=[0.229, 0.224, 0.225], \n            max_pixel_value=255.0, \n            p=1.0\n        ),\n        ToTensorV2()], p=1.),\n    \n    \"valid\": A.Compose([\n        A.Resize(CONFIG['img_size'], CONFIG['img_size']),\n        A.Normalize(\n            mean=[0.485, 0.456, 0.406], \n            std=[0.229, 0.224, 0.225], \n            max_pixel_value=255.0, \n            p=1.0\n        ),\n        ToTensorV2()], p=1.)\n}","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.156111Z","iopub.execute_input":"2023-12-06T04:05:22.156498Z","iopub.status.idle":"2023-12-06T04:05:22.171536Z","shell.execute_reply.started":"2023-12-06T04:05:22.156468Z","shell.execute_reply":"2023-12-06T04:05:22.170536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class GeM(nn.Module):\n    def __init__(self, p=3, eps=1e-6):\n        super(GeM, self).__init__()\n        self.p = nn.Parameter(torch.ones(1)*p)\n        self.eps = eps\n\n    def forward(self, x):\n        return self.gem(x, p=self.p, eps=self.eps)\n        \n    def gem(self, x, p=3, eps=1e-6):\n        return F.avg_pool2d(x.clamp(min=eps).pow(p), (x.size(-2), x.size(-1))).pow(1./p)\n        \n    def __repr__(self):\n        return self.__class__.__name__ + \\\n                '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + \\\n                ', ' + 'eps=' + str(self.eps) + ')'\n\nclass EfficientNetB0(nn.Module):\n    '''\n    EfficientNet B0 fine-tune.\n    '''\n    def __init__(self, model_name, num_classes, pretrained=True, checkpoint_path=None):\n        '''\n        Fine tune for EfficientNetB0\n        Args\n            n_classes : int - Number of classification categories.\n            learnable_modules : tuple - Names of the modules to fine-tune.\n        Return\n            \n        '''\n        super(EfficientNetB0, self).__init__()\n        self.model = timm.create_model(model_name, pretrained=pretrained, checkpoint_path=checkpoint_path)\n\n        in_features = self.model.classifier.in_features\n        self.model.classifier = nn.Identity()\n        self.model.global_pool = nn.Identity()\n        self.pooling = GeM()\n        self.linear = nn.Linear(in_features, num_classes)\n        self.softmax = nn.Softmax(dim=1)\n    \n    \n    def forward(self, images):\n        \"\"\"\n        Forward function for the fine-tuned model\n        Args\n            x: \n        Return\n            result\n        \"\"\"\n        features = self.model(images)\n        pooled_features = self.pooling(features).flatten(1)\n        output = self.linear(pooled_features)\n        return output","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.173074Z","iopub.execute_input":"2023-12-06T04:05:22.173488Z","iopub.status.idle":"2023-12-06T04:05:22.186718Z","shell.execute_reply.started":"2023-12-06T04:05:22.173451Z","shell.execute_reply":"2023-12-06T04:05:22.185674Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn.functional as F\n","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.188053Z","iopub.execute_input":"2023-12-06T04:05:22.188625Z","iopub.status.idle":"2023-12-06T04:05:22.203903Z","shell.execute_reply.started":"2023-12-06T04:05:22.188587Z","shell.execute_reply":"2023-12-06T04:05:22.202242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Encoding the categorical values of the label","metadata":{}},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\nlabel_encoder = LabelEncoder()","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.206453Z","iopub.execute_input":"2023-12-06T04:05:22.207315Z","iopub.status.idle":"2023-12-06T04:05:22.215685Z","shell.execute_reply.started":"2023-12-06T04:05:22.207277Z","shell.execute_reply":"2023-12-06T04:05:22.2142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict_val_dataset(model, CONFIG, df_validate, TRAIN_DIR=None, val_size=1.0):\n    if not CONFIG[\"is_submission\"]:\n        valid_dataset = UBCDataset(df_validate, transforms=data_transforms[\"valid\"])\n        valid_loader = DataLoader(valid_dataset, batch_size=CONFIG['valid_batch_size'], \n                              num_workers=2, shuffle=False, pin_memory=True)\n        \n        preds = []\n        labels_list = []\n\n        with torch.no_grad():\n            bar = tqdm(enumerate(valid_loader), total=len(valid_loader))\n            for step, data in bar: \n                images = data['image'].to(CONFIG[\"device\"], dtype=torch.float)\n                labels = data['label'].to(CONFIG[\"device\"], dtype=torch.long)\n                batch_size = images.size(0)\n                outputs = model(images)\n                _, predicted = torch.max(outputs, dim=1)\n                preds.extend(predicted.cpu().numpy())\n                labels_list.extend(labels.cpu().numpy())\n\n        preds = np.array(preds)\n        labels_list = np.array(labels_list)\n\n        # Calculate Balanced Accuracy\n        bal_acc = balanced_accuracy_score(labels_list, preds)\n        # Calculate Confusion Matrix\n        conf_matrix = confusion_matrix(labels_list, preds)\n        macro_f1 = f1_score(labels_list, preds, average='macro')\n        micro_f1 = f1_score(labels_list, preds, average='micro')\n        weighted_f1 = f1_score(labels_list, preds, average='weighted')\n\n        print(f\"Balanced Accuracy: {bal_acc}\")\n        print(f\"Macro F1-Score: {macro_f1}\")\n        print(f\"Micro F1-Score: {micro_f1}\")\n        print(f\"Weighted F1-Score: {weighted_f1}\")\n        print(f\"Confusion Matrix:\\n{conf_matrix}\")\n        return bal_acc, macro_f1, weighted_f1\n    else:\n        print(\"Skip validation on training set due to submission!\")\n        return None\n","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.217281Z","iopub.execute_input":"2023-12-06T04:05:22.218256Z","iopub.status.idle":"2023-12-06T04:05:22.231262Z","shell.execute_reply.started":"2023-12-06T04:05:22.218202Z","shell.execute_reply":"2023-12-06T04:05:22.229352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Loading the efficent net model.","metadata":{}},{"cell_type":"code","source":"import timm\nmodel = timm.create_model('tf_efficientnet_b2',pretrained = True,num_classes = 5)","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.234297Z","iopub.execute_input":"2023-12-06T04:05:22.235131Z","iopub.status.idle":"2023-12-06T04:05:22.596796Z","shell.execute_reply.started":"2023-12-06T04:05:22.235079Z","shell.execute_reply":"2023-12-06T04:05:22.595371Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not CONFIG[\"is_submission\"]: \n    df_train = pd.read_csv(\"/kaggle/input/UBC-OCEAN/train.csv\")\n    print(df_train.shape)\n    print(df_train)\n    df_train['file_path'] = df_train.apply(lambda row: get_train_file_path(row), axis=1)\n    df_train['target_label'] = label_encoder.fit_transform(df_train['label'])\n    print(df_train[\"target_label\"])\n    # use stratified K Fold for crossvalidation \n    skf = StratifiedKFold(n_splits=CONFIG['n_fold'], shuffle=True, random_state=CONFIG[\"seed\"])\n    for fold, ( _, val_) in enumerate(skf.split(X=df_train, y=df_train.target_label)):\n        df_train.loc[val_ , \"kfold\"] = int(fold)\n        \n    all_labels = []\n    all_predictions = []\n#     for fold in range(3):\n    fold = 1\n    print(\"Evaluate Fold: \", fold)\n\n    model.eval()\n    model.to(CONFIG[\"device\"])\n    df_train_fold = df_train[df_train[\"kfold\"]!=fold].reset_index(drop=True)\n    df_valid_fold = df_train[df_train[\"kfold\"]==fold].reset_index(drop=True)\n\n    #train_dataset = UBCDataset(df_train_fold, transforms=data_transforms[\"train\"])\n    #train_loader = DataLoader(train_dataset, batch_size=CONFIG['train_batch_size'], \n    #                          num_workers=2, shuffle=False, pin_memory=True)\n    valid_dataset = UBCDataset(df_valid_fold, transforms=data_transforms[\"valid\"])\n    valid_loader = DataLoader(valid_dataset, batch_size=CONFIG['valid_batch_size'], \n                              num_workers=2, shuffle=False, pin_memory=True)\n\n    df_validate, predictions, labels = predict_val_dataset(model, CONFIG, df_valid_fold, TRAIN_DIR, val_size=1)\n    all_labels.extend([labels] if isinstance(labels, float) else labels.tolist())\n    if isinstance(predictions, float):\n        all_predictions.append(predictions)\n    else:\n        all_predictions.extend(predictions)\n    display(df_validate)","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:05:22.599252Z","iopub.execute_input":"2023-12-06T04:05:22.599951Z","iopub.status.idle":"2023-12-06T04:06:07.875143Z","shell.execute_reply.started":"2023-12-06T04:05:22.599913Z","shell.execute_reply":"2023-12-06T04:06:07.87349Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[\"label\"]","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:06:07.878686Z","iopub.execute_input":"2023-12-06T04:06:07.879068Z","iopub.status.idle":"2023-12-06T04:06:07.890585Z","shell.execute_reply.started":"2023-12-06T04:06:07.879035Z","shell.execute_reply":"2023-12-06T04:06:07.888932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# Predict on Test Dataset\ntest_dataset = UBCDataset(df_test, transforms=data_transforms[\"valid\"])\ntest_loader = DataLoader(test_dataset, batch_size=CONFIG['valid_batch_size'], \n                          num_workers=2, shuffle=False, pin_memory=True)\n\npreds = []\nmodel.eval()\nmodel.to(CONFIG[\"device\"])\n\nwith torch.no_grad():\n    bar = tqdm(enumerate(test_loader), total=len(test_loader))\n    for step, data in bar: \n        images = data['image'].to(CONFIG[\"device\"], dtype=torch.float)\n        outputs = model(images)\n        probabilities = torch.softmax(outputs, dim=1)\n        _, predicted = torch.max(probabilities, dim=1)\n        preds.extend(predicted.detach().cpu().numpy())\n\n\npreds = np.array(preds)\npred_labels = preds \n\n","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:06:07.892788Z","iopub.execute_input":"2023-12-06T04:06:07.893143Z","iopub.status.idle":"2023-12-06T04:06:08.774157Z","shell.execute_reply.started":"2023-12-06T04:06:07.893114Z","shell.execute_reply":"2023-12-06T04:06:08.773024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_labels","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:06:08.775614Z","iopub.execute_input":"2023-12-06T04:06:08.77595Z","iopub.status.idle":"2023-12-06T04:06:08.7853Z","shell.execute_reply.started":"2023-12-06T04:06:08.775918Z","shell.execute_reply":"2023-12-06T04:06:08.783026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Submission created","metadata":{}},{"cell_type":"code","source":"df_sub = pd.read_csv(f\"{ROOT_DIR}/sample_submission.csv\")\ndf_sub[\"label\"] = pred_labels\ndf_sub.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-12-06T04:06:08.787135Z","iopub.execute_input":"2023-12-06T04:06:08.787808Z","iopub.status.idle":"2023-12-06T04:06:08.799571Z","shell.execute_reply.started":"2023-12-06T04:06:08.78777Z","shell.execute_reply":"2023-12-06T04:06:08.797834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}