{"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":"code","source":"!pip install -q /kaggle/input/rsna-resnet-50/python_gdcm-3.0.22-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl/python_gdcm-3.0.22-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\n!pip install -q /kaggle/input/rsna-resnet-50/pylibjpeg-1.4.0-py3-none-any.whl","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-09-25T14:23:01.9174Z","iopub.execute_input":"2023-09-25T14:23:01.917818Z","iopub.status.idle":"2023-09-25T14:23:46.521966Z","shell.execute_reply.started":"2023-09-25T14:23:01.917789Z","shell.execute_reply":"2023-09-25T14:23:46.520782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\")\n# Import necessary packages\n# import packages\nimport os\nimport pickle\nfrom tqdm.notebook import tqdm\nimport random\nfrom tabulate import tabulate\n\nimport cv2\nimport torch\nimport timm\nfrom glob import glob\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport numpy as np\nimport pandas as pd\nimport pydicom\nimport matplotlib.pyplot as plt\nimport torchvision.transforms.v2 as t\nimport gc\n\nfrom torch.utils.data import Dataset, DataLoader, Subset\n\nfrom os.path import join\nfrom os import makedirs, listdir\n\nimport numpy as np\nimport torch\nimport matplotlib.pyplot as plt\nfrom typing import Tuple, Union, List","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:46.525497Z","iopub.execute_input":"2023-09-25T14:23:46.526231Z","iopub.status.idle":"2023-09-25T14:23:46.535055Z","shell.execute_reply.started":"2023-09-25T14:23:46.526199Z","shell.execute_reply":"2023-09-25T14:23:46.534129Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BASE_PATH = '/kaggle/input/rsna-2023-abdominal-trauma-detection'\nIMG_DIR = '/tmp/Dataset/rsna-atd'\n!rm -r {IMG_DIR}\nos.makedirs(f'{IMG_DIR}/test_images', exist_ok = True)\ntest_df = pd.read_csv(f'{BASE_PATH}/test_series_meta.csv')\ntest_df['dicom_folder'] = BASE_PATH + '/' + 'test_images'\\\n                                    + '/' + test_df.patient_id.astype(str)\\\n                                    + '/' + test_df.series_id.astype(str)\ntest_df['tensor_path'] = IMG_DIR + '/' + 'test_images'\\\n                                    + '/' + test_df.patient_id.astype(str)\\\n                                    + '/' + test_df.series_id.astype(str)","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:46.536503Z","iopub.execute_input":"2023-09-25T14:23:46.538656Z","iopub.status.idle":"2023-09-25T14:23:47.52637Z","shell.execute_reply.started":"2023-09-25T14:23:46.538623Z","shell.execute_reply":"2023-09-25T14:23:47.525192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.makedirs(f'/tmp/corrupt/', exist_ok = True)","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:47.529308Z","iopub.execute_input":"2023-09-25T14:23:47.529626Z","iopub.status.idle":"2023-09-25T14:23:47.534632Z","shell.execute_reply.started":"2023-09-25T14:23:47.529597Z","shell.execute_reply":"2023-09-25T14:23:47.533663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\n\nfiltered_df = test_df.loc[(test_df['patient_id'] == 3124) & (test_df['series_id'] == 5842), 'dicom_folder']\n\nif not filtered_df.empty:\n    src_dir = filtered_df.values[0]\n    dest_dir = '/tmp/corrupt/'\n    \n    # Continue with your operations...\n    if os.path.exists(src_dir):\n        for item in os.listdir(src_dir):\n            s = os.path.join(src_dir, item)\n            d = os.path.join(dest_dir, item)\n            if os.path.isdir(s):\n                shutil.copytree(s, d, False, None)\n            else:\n                shutil.copy2(s, d)\n    else:\n        print(f\"The folder {src_dir} does not exist.\")\nelse:\n    print(\"No matching rows found in the DataFrame.\")","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:47.536069Z","iopub.execute_input":"2023-09-25T14:23:47.536637Z","iopub.status.idle":"2023-09-25T14:23:47.548895Z","shell.execute_reply.started":"2023-09-25T14:23:47.536605Z","shell.execute_reply":"2023-09-25T14:23:47.547987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Using .loc[] to change a cell value\ntest_df.loc[(test_df['patient_id'] == 3124) & (test_df['series_id'] == 5842), 'dicom_folder'] = \"/tmp/corrupt/\"","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:47.55022Z","iopub.execute_input":"2023-09-25T14:23:47.550793Z","iopub.status.idle":"2023-09-25T14:23:47.563985Z","shell.execute_reply.started":"2023-09-25T14:23:47.550761Z","shell.execute_reply":"2023-09-25T14:23:47.562981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"file_path = \"/tmp/corrupt/514.dcm\"\n# Check if the file exists\nif os.path.exists(file_path):\n    # Remove the file\n    os.remove(file_path)\n    print(f\"The file {file_path} has been removed.\")\nelse:\n    print(f\"The file {file_path} does not exist.\")","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:47.566535Z","iopub.execute_input":"2023-09-25T14:23:47.567212Z","iopub.status.idle":"2023-09-25T14:23:47.575373Z","shell.execute_reply.started":"2023-09-25T14:23:47.56718Z","shell.execute_reply":"2023-09-25T14:23:47.574499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE = [224,224]\nNUM_SLICES = 64\n\n\ndef standardize_pixel_array(dcm: pydicom.dataset.FileDataset) -> np.ndarray:\n    \"\"\"\n    Source : https://www.kaggle.com/competitions/rsna-2023-abdominal-trauma-detection/discussion/427217\n    \"\"\"\n    # Correct DICOM pixel_array if PixelRepresentation == 1.\n    pixel_array = dcm.pixel_array\n    if dcm.PixelRepresentation == 1:\n        bit_shift = dcm.BitsAllocated - dcm.BitsStored\n        dtype = pixel_array.dtype \n        pixel_array = (pixel_array << bit_shift).astype(dtype) >>  bit_shift\n#         pixel_array = pydicom.pixel_data_handlers.util.apply_modality_lut(new_array, dcm)\n    if dcm.PhotometricInterpretation == \"MONOCHROME1\":\n        pixel_array = 1 - pixel_array\n    intercept = float(dcm.RescaleIntercept)\n    slope = float(dcm.RescaleSlope)\n    center = int(dcm.WindowCenter)\n    width = int(dcm.WindowWidth)\n    low = center - width / 2\n    high = center + width / 2    \n    \n    pixel_array = (pixel_array * slope) + intercept\n    if pixel_array.max() == pixel_array.min():\n        pixel_array = np.zeros_like(pixel_array)  # Handle case of constant array\n    else:\n        pixel_array = np.clip(pixel_array, low, high)\n\n    return pixel_array\n\n\ndef read_xray(path, fix_monochrome = True):\n    dicom = pydicom.dcmread(path)\n    data = standardize_pixel_array(dicom)\n    data = data - np.min(data)\n    data = data / (np.max(data) + 1e-5)\n    if fix_monochrome and dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = 1.0 - data\n    IMG_SIZE = [224, 224]\n    data = cv2.resize(data, IMG_SIZE, cv2.INTER_LINEAR)\n    data = (data * 255).astype(np.uint8)\n    return data\n\ndef load_scan(paths, NUM_SLICES=64):\n    IMG_SIZE = [224, 224]\n    img = np.empty(shape=(*IMG_SIZE, NUM_SLICES), dtype=np.uint8)\n    for i, path in enumerate(paths):\n        img[...,i] = read_xray(path)\n    # Transpose the array to shape (64, 256, 256)\n    transposed_array = np.transpose(img, (2, 0, 1))\n\n    return transposed_array","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:47.57704Z","iopub.execute_input":"2023-09-25T14:23:47.577741Z","iopub.status.idle":"2023-09-25T14:23:47.591474Z","shell.execute_reply.started":"2023-09-25T14:23:47.577709Z","shell.execute_reply":"2023-09-25T14:23:47.590555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_dcm_files(path):\n    dcm_files = [os.path.join(dirpath, f)\n                 for dirpath, dirnames, filenames in os.walk(path)\n                 for f in filenames if f.endswith('.dcm')]\n    return dcm_files\n\ndef sort_dcm_files(dcm_files):\n    return sorted(dcm_files, key=lambda x: int(os.path.basename(x).split('.')[0]))\n\ndef select_evenly_spaced_files_around_center(file_list, num_files_each_side=32, step = 1):\n    center_idx = len(file_list) // 2  # Tìm chỉ số của file ở giữa\n\n    # Lấy 32 file trước và 32 file sau, cách đều nhau, từ file ở giữa\n    selected_files = [file_list[i] for i in range(center_idx - num_files_each_side * step, center_idx + num_files_each_side * step, step)]\n\n    return selected_files\ndef plot_slices(tensor):\n    # Assuming tensor shape is [64, 256, 256]\n    fig, axarr = plt.subplots(8, 8, figsize=(15, 15))\n    \n    for i in range(8):\n        for j in range(8):\n            slice_idx = i * 8 + j\n            axarr[i, j].imshow(tensor[slice_idx], cmap='gray')\n            axarr[i, j].axis('off')\n            axarr[i, j].set_title(f'Slice {slice_idx}')\n    \n    plt.subplots_adjust(wspace=0.2, hspace=0.5)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:47.592891Z","iopub.execute_input":"2023-09-25T14:23:47.593519Z","iopub.status.idle":"2023-09-25T14:23:47.606784Z","shell.execute_reply.started":"2023-09-25T14:23:47.593486Z","shell.execute_reply":"2023-09-25T14:23:47.605849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_folders = test_df.dicom_folder.tolist()\n\ntest_paths = []\nfor i, folder in enumerate(test_folders):\n    paths = sorted(glob(os.path.join(folder, '*dcm')),\n                   key=lambda x: int(x.split('/')[-1].split('.')[0]))\n    NUM_DICOM = len(paths)\n    if len(test_folders)>6: # private test; contains all dicom files/folders\n        test_paths += [paths]\n        \n        if NUM_DICOM > 64:\n            sorted_dcm_list = sort_dcm_files(paths)\n            upper_limit = len(sorted_dcm_list) // 64  # Giả sử len(sorted_dcm_list) là số lượng các phần tử trong danh sách DCM đã sắp xếp\n            space = np.random.randint(1, upper_limit + 1)\n            dcm_files = select_evenly_spaced_files_around_center(sorted_dcm_list, num_files_each_side=32, step = space)\n            img = load_scan(dcm_files)            \n            os.makedirs(test_df.iloc[i]['tensor_path'], exist_ok = True)\n            np.save(test_df.iloc[i]['tensor_path'] + \"/tensor.npy\", img)\n        else:            \n            data = load_scan(paths, NUM_SLICES=64)\n            os.makedirs(test_df.iloc[i]['tensor_path'], exist_ok = True)\n            np.save(test_df.iloc[i]['tensor_path'] + \"/tensor.npy\", data)\n       \n    else: # we can't access all the test dicom files in public test\n        test_paths += [paths]\n        if len(paths) > 0:\n            data = load_scan(paths, NUM_SLICES=64)\n            os.makedirs(test_df.iloc[i]['tensor_path'], exist_ok = True)\n            np.save(test_df.iloc[i]['tensor_path'] + \"/tensor.npy\", data)\n\ntest_df['dicom_paths'] = test_paths\ntest_df = test_df[test_df.dicom_paths.map(len)>0] # in public test not all folder contains dicom file","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:47.610759Z","iopub.execute_input":"2023-09-25T14:23:47.611011Z","iopub.status.idle":"2023-09-25T14:23:47.940916Z","shell.execute_reply.started":"2023-09-25T14:23:47.610988Z","shell.execute_reply":"2023-09-25T14:23:47.939949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AbdominalTestData(Dataset):\n    \"\"\"\n    Custom dataset class for handling abdominal trauma test data classification.\n    \n    Args:\n        img_paths (list of strings): List containing all image paths of a patient\n        target_size (tuple): The target size to resize the images to\n        ext (str): The extension of the image files\n        transform (callable, optional): A function/transform to apply to the images\n    \"\"\"\n    \n    def __init__(self, df):\n        \n        super().__init__()\n        \n        self.df = df\n        self.img_paths = self.df['tensor_path'].to_list()\n    \n    def __len__(self):\n        \"\"\"\n        Returns the total number of samples in the dataset.\n        \"\"\"\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        \"\"\"\n        Returns a sample from the dataset at the given index.\n        \n        Args:\n            idx (int): Index\n        \n        Returns:\n            tuple: (image, file_path)\n        \"\"\"\n        \n        file_path = self.img_paths[idx]\n        img = np.load(file_path + \"/tensor.npy\")\n        return torch.from_numpy(img).float()  ","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:47.942236Z","iopub.execute_input":"2023-09-25T14:23:47.942594Z","iopub.status.idle":"2023-09-25T14:23:47.951607Z","shell.execute_reply.started":"2023-09-25T14:23:47.942562Z","shell.execute_reply":"2023-09-25T14:23:47.950304Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def mc_proc(pred):\n    argmax = np.argmax(pred, axis=1).astype('uint8')\n    one_hot = tf.keras.utils.to_categorical(argmax, num_classes=3)\n    return one_hot.astype('uint8')\n\ndef sc_proc(pred, thr=0.5):\n    proc_pred = (pred > thr).astype('uint8')\n    return proc_pred\n\ndef post_proc(pred):\n    proc_pred = np.empty((pred.shape[0], 2 + 2 + 3*3), dtype=np.uint8)\n\n    # bowel, extravasation\n    proc_pred[:, 0] = sc_proc(pred[:, 0])\n    proc_pred[:, 1] = 1 - proc_pred[:, 0]\n    proc_pred[:, 2] = sc_proc(pred[:, 1])\n    proc_pred[:, 3] = 1 - proc_pred[:, 2]\n    \n    # liver, kidney, sneel\n    proc_pred[:, 4:7] = mc_proc(pred[:, 2:5])\n    proc_pred[:, 7:10] = mc_proc(pred[:, 5:8])\n    proc_pred[:, 10:13] = mc_proc(pred[:, 8:11])\n\n    return proc_pred\n\ndef post_proc_v2(pred):\n    proc_pred = np.empty((pred.shape[0], 2*2 + 3*3), dtype='float32')\n\n    # bowel, extravasation\n    proc_pred[:, 0] = 1 - pred[:, 0] # bowel-healthy\n    proc_pred[:, 1] = pred[:, 0] # bowel-injured\n    proc_pred[:, 2] = 1 - pred[:, 1] # extra-healthy\n    proc_pred[:, 3] = pred[:, 1] # extra-injured\n    \n    # liver, kidney, sneel\n    proc_pred[:, 4:7] = pred[:, 2:5]\n    proc_pred[:, 7:10] = pred[:, 5:8]\n    proc_pred[:, 10:13] = pred[:, 8:11]\n\n    return proc_pred","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:47.952938Z","iopub.execute_input":"2023-09-25T14:23:47.953409Z","iopub.status.idle":"2023-09-25T14:23:47.968116Z","shell.execute_reply.started":"2023-09-25T14:23:47.953378Z","shell.execute_reply":"2023-09-25T14:23:47.967237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MultiHeadAttention(nn.Module):\n     def __init__(self, input_dim, num_heads):\n         super(MultiHeadAttention, self).__init__()\n        \n         self.num_heads = num_heads\n         self.attention_head_size = int(input_dim / num_heads)\n        \n         self.query = nn.Linear(input_dim, input_dim)\n         self.key = nn.Linear(input_dim, input_dim)\n         self.value = nn.Linear(input_dim, input_dim)\n        \n         self.linear = nn.Linear(input_dim, input_dim)\n         self.softmax = nn.Softmax(dim=-1)\n\n     def forward(self, x):\n         batch_size = x.size(0)\n        \n         Q = self.query(x).view(batch_size, -1, self.num_heads, self.attention_head_size).transpose(1, 2)\n         K = self.key(x).view(batch_size, -1, self.num_heads, self.attention_head_size).transpose(1, 2)\n         V = self.value(x).view(batch_size, -1, self.num_heads, self.attention_head_size).transpose(1, 2)\n        \n         attention_weights = self.softmax(Q.matmul(K.transpose(-2, -1)))\n         output = attention_weights.matmul(V).transpose(1, 2).contiguous().view(batch_size, -1)\n        \n         return self.linear(output)\n\n         return x\n\nclass ChannelSqueezer(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.expand = nn.Sequential(\n            nn.Conv2d(64, 32, kernel_size=3, padding=1),\n            nn.GELU()\n        )\n        self.squeeze = nn.Sequential(\n            nn.Conv2d(32, 3, kernel_size=3, padding=1),\n            nn.GELU()\n        )\n\n    def forward(self, x):\n#         x = x.unsqueeze(dim = 1) # add channel C (B, 1, 4, 224, 224)\n        x = self.expand(x)\n        x = self.squeeze(x)\n\n        return x\nclass CNNModel(nn.Module):\n     def __init__(self, backbone, pretrained=False):\n         super().__init__()\n         self.channel_squeezer = ChannelSqueezer()\n         self.feature_extractor = timm.create_model(\n             backbone,\n             in_chans=3,\n             pretrained=pretrained\n         )\n        \n         f = self.feature_extractor.head.in_features\n         self.feature_extractor.head = nn.Identity()\n        \n         num_heads = 8  # adjust as needed\n        \n         # Multi-head attention layers\n         self.attention1 = MultiHeadAttention(f, num_heads)\n         self.attention2 = MultiHeadAttention(f, num_heads)\n         self.attention3 = MultiHeadAttention(f, num_heads)\n         self.attention4 = MultiHeadAttention(f, num_heads)\n         self.attention5 = MultiHeadAttention(f, num_heads)\n        \n         # for bowel and extravasation\n         self.logit1 = nn.Sequential(\n             nn.Linear(f, 32),\n             nn.SiLU(),\n             nn.Dropout(0.4),\n             nn.Linear(32, 1)\n         )\n         self.logit2 = nn.Sequential(\n             nn.Linear(f, 32),\n             nn.SiLU(),\n             nn.Dropout(0.4),\n             nn.Linear(32, 1)\n         )\n         # for kidney, liver, spleen\n         self.logit3 = nn.Sequential(\n             nn.Linear(f, 32),\n             nn.SiLU(),\n             nn.Dropout(0.4),\n             nn.Linear(32, 3)\n         )\n         self.logit4 = nn.Sequential(\n             nn.Linear(f, 32),\n             nn.SiLU(),\n             nn.Dropout(0.4),\n             nn.Linear(32, 3)\n         )\n         self.logit5 = nn.Sequential(\n             nn.Linear(f, 32),\n             nn.SiLU(),\n             nn.Dropout(0.4),\n             nn.Linear(32, 3)\n         )\n    \n     def forward(self, x):\n         x = self.channel_squeezer(x)\n         x = self.feature_extractor(x)\n         x = torch.flatten(x, 1)\n        \n         # Apply multi-head attention\n         x1 = self.attention1(x)\n         x2 = self.attention2(x)\n         x3 = self.attention3(x)\n         x4 = self.attention4(x)\n         x5 = self.attention5(x)\n        \n         # output logits\n         bowel = self.logit1(x1)\n         extravasation = self.logit2(x2)\n         kidney = self.logit3(x3)\n         liver = self.logit4(x4)\n         spleen = self.logit5(x5)\n        \n         return bowel, extravasation, kidney, liver, spleen","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:47.969532Z","iopub.execute_input":"2023-09-25T14:23:47.970095Z","iopub.status.idle":"2023-09-25T14:23:47.993297Z","shell.execute_reply.started":"2023-09-25T14:23:47.970062Z","shell.execute_reply":"2023-09-25T14:23:47.992279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the model architecture (adjust as necessary)\nbackbone = 'vit_base_patch16_224.augreg_in21k_ft_in1k'\nmodel_dir_cls = '/kaggle/input/vit-b16-multihead'\ndevice = torch.device('cuda')\nREPLICAS = 1\nimg_size = [224,224]\nprint(f'REPLICAS: {REPLICAS}')\n# Load pre-trained models (add paths to your pre-trained model weights)\nmodel_paths = sorted(glob(f'{model_dir_cls}/*.pth'))[:1]\nprint(model_paths)\nmodels = []\n# model_paths = [\"/kaggle/input/rsna-resnet-50/best_augment_resnet_5.070.pth\"]\nfor model_path in model_paths:\n    try:\n        model = CNNModel(backbone, pretrained=False)\n        model = model.to(device)\n        sd = torch.load(model_path)\n\n        # Checking if the loaded object is a dict or a model instance\n        if isinstance(sd, dict):\n            if 'model_state_dict' in sd.keys():\n                sd = sd['model_state_dict']\n            sd = {k[7:] if k.startswith('module.') else k: sd[k] for k in sd.keys()}\n        elif isinstance(sd, torch.nn.Module):\n            # Handling case where the entire model object was saved\n            # (not recommended due to potential compatibility issues)\n            model = sd\n            sd = None\n        else:\n            raise ValueError(\"Unrecognized format for loaded state dict\")\n\n        if sd is not None:\n            model.load_state_dict(sd, strict=True)\n        \n        model.eval()\n        models.append(model)\n    except Exception as e:\n        print(f\"Could not load model from {model_path}: {e}\")\nlen(models)","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:47.994672Z","iopub.execute_input":"2023-09-25T14:23:47.995095Z","iopub.status.idle":"2023-09-25T14:23:52.950279Z","shell.execute_reply.started":"2023-09-25T14:23:47.995062Z","shell.execute_reply":"2023-09-25T14:23:52.94936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Getting unique patient IDs from test dataset\nimport torch.nn.functional as F\npatient_ids = test_df['patient_id'].unique()\n\n# Initializing array to store predictions\npatient_preds = np.zeros(shape=(len(patient_ids), 2*2 + 3*3), dtype='float32')\nwith torch.no_grad():\n# Iterating over each patient\n    for pidx, patient_id in tqdm(enumerate(patient_ids), total=len(patient_ids), desc=\"Patients \"):\n        # Query the dataframe for a particular patient\n        patient_df = test_df.query(\"patient_id == @patient_id\", engine='python')\n\n        # Initializing model predictions array\n        model_preds = np.zeros(shape=(1, 11), dtype=np.float32)\n\n        print(\"=\"*25)\n        print(f\"   Patient ID: {patient_id}\")\n        print(\"=\"*25)\n\n        # Iterating over each model\n        for _, model in enumerate(models):\n\n            # Getting image paths for a patient\n            patient_paths = patient_df.tensor_path.tolist()\n            #print(patient_paths)\n            # Setting batch size based on number of patient paths and dimension of image\n            dim = np.prod(img_size)**0.5\n            if dim >= 1024:\n                batch_size = REPLICAS * int(4 * 2)\n            elif dim >= 768:\n                batch_size = REPLICAS * int(16 * 2)\n            elif dim >= 640:\n                batch_size = REPLICAS * int(28 * 2)\n            else:\n                batch_size = REPLICAS * int(32 * 2)\n                \n            min_bs = 2**np.floor(np.log2(len(patient_paths)))\n            batch_size = min(min_bs, batch_size)\n            batch_size = int(batch_size)\n            # Building dataset for prediction\n            preds = []\n            #display(patient_df)\n            test_data = AbdominalTestData(patient_df)\n            dtest = DataLoader(test_data, batch_size=batch_size, shuffle=False)\n            # Iterating over each fold\n            # Loading a PyTorch model from a fold path\n\n            # Iterating over batches and getting predictions\n            #print(batch_size)\n            for batch_idx, batch_data in enumerate(tqdm(dtest)):\n                inputs = batch_data.to(device)\n                #print(inputs)\n                pred = model(inputs)\n                bowel =F.sigmoid(pred[0].cpu()).numpy().flatten()\n                extra = F.sigmoid(pred[1].cpu()).numpy().flatten()\n                kidney = F.softmax(pred[2].cpu(),dim =1).numpy().flatten()\n                liver = F.softmax(pred[3].cpu(),dim =1).numpy().flatten()\n                spleen = F.softmax(pred[4].cpu(),dim =1).numpy().flatten()\n\n                preds.append(np.concatenate((bowel,extra, kidney, liver, spleen), axis=0))                           \n            \n            preds = np.array(preds).astype('float32')\n            print(len(patient_paths))\n            print(preds.shape)\n            preds = preds.reshape(len(patient_paths), 11)\n            pred = np.max(preds, axis=0)\n\n            # Store model's prediction\n            model_preds += pred / (len(models))\n\n                # Deleting variables to free up memory\n            del model, pred\n            gc.collect()\n            print('\\n')\n\n            del dtest, patient_paths; gc.collect()\n\n        # Adding processed predictions to patient_preds\n        # (define the post_proc_v2 function to work with your predictions)\n        patient_preds[pidx, :] += post_proc_v2(model_preds)[0]\n\n        del model_preds\n        gc.collect()\n\nprint(\"Prediction Done!\")","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:52.951965Z","iopub.execute_input":"2023-09-25T14:23:52.952727Z","iopub.status.idle":"2023-09-25T14:23:54.509537Z","shell.execute_reply.started":"2023-09-25T14:23:52.952682Z","shell.execute_reply":"2023-09-25T14:23:54.5085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create Submission\ntarget_col  = [\"bowel_healthy\", \"bowel_injury\", \"extravasation_healthy\",\n                   \"extravasation_injury\", \"kidney_healthy\", \"kidney_low\",\n                   \"kidney_high\", \"liver_healthy\", \"liver_low\", \"liver_high\",\n                   \"spleen_healthy\", \"spleen_low\", \"spleen_high\"]\npred_df = pd.DataFrame({'patient_id':patient_ids,})\npred_df[target_col] = patient_preds.astype('float32')\n\n# Align with sample submission\nsub_df = pd.read_csv(f'{BASE_PATH}/sample_submission.csv')\nsub_df = sub_df[['patient_id']]\nsub_df = sub_df.merge(pred_df, on='patient_id', how='left')\n\n# Store submission\n#sub_df.to_csv('submission.csv',index=False)\nsub_df","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:54.511139Z","iopub.execute_input":"2023-09-25T14:23:54.511578Z","iopub.status.idle":"2023-09-25T14:23:54.546816Z","shell.execute_reply.started":"2023-09-25T14:23:54.511544Z","shell.execute_reply":"2023-09-25T14:23:54.54592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"scale_by_2 = ['kidney_low','liver_low','spleen_low','spleen_high']\nscale_by_4 = ['bowel_injury','kidney_high','liver_high']\nscale_by_6 = ['extravasation_injury']\nscale_healthy = ['bowel_healthy', 'extravasation_healthy', 'kidney_healthy', 'liver_healthy', 'spleen_healthy']\nsf_2 = 2\nsf_4 = 4\nsf_6 = 14\nscale_h = 0.99","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:54.548041Z","iopub.execute_input":"2023-09-25T14:23:54.548366Z","iopub.status.idle":"2023-09-25T14:23:54.555467Z","shell.execute_reply.started":"2023-09-25T14:23:54.548336Z","shell.execute_reply":"2023-09-25T14:23:54.554498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Scale each target \nsub_df[scale_by_2] *=sf_2\nsub_df[scale_by_4] *=sf_4\nsub_df[scale_by_6] *=sf_6\nsub_df[scale_healthy] *=scale_h","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:54.556862Z","iopub.execute_input":"2023-09-25T14:23:54.557305Z","iopub.status.idle":"2023-09-25T14:23:54.573578Z","shell.execute_reply.started":"2023-09-25T14:23:54.557267Z","shell.execute_reply":"2023-09-25T14:23:54.572553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Store submission\nsub_df.to_csv('submission.csv',index=False)\nsub_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-09-25T14:23:54.575216Z","iopub.execute_input":"2023-09-25T14:23:54.575676Z","iopub.status.idle":"2023-09-25T14:23:54.597133Z","shell.execute_reply.started":"2023-09-25T14:23:54.575642Z","shell.execute_reply":"2023-09-25T14:23:54.596285Z"},"trusted":true},"execution_count":null,"outputs":[]}]}