{"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":"import os \nimport time\n\nfrom abc import ABC, abstractmethod, abstractproperty\nfrom collections import defaultdict\nfrom tqdm import tqdm \nfrom PIL import Image\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nfrom sklearn.model_selection import train_test_split, StratifiedGroupKFold\nfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score \n\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.optim import lr_scheduler\nimport torchvision.models as models\nimport torchvision.transforms as transforms\nfrom torchvision.datasets import ImageFolder\nfrom torchvision.io import read_image\nfrom torch.utils.data import DataLoader, Dataset\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-10-23T12:42:08.53155Z","iopub.execute_input":"2023-10-23T12:42:08.532403Z","iopub.status.idle":"2023-10-23T12:42:08.54417Z","shell.execute_reply.started":"2023-10-23T12:42:08.532342Z","shell.execute_reply":"2023-10-23T12:42:08.542808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport torch\nimport pandas as pd\nimport numpy as np\nfrom tqdm.notebook import tqdm\nfrom glob import glob\nimport cv2\nimport pydicom\nimport gc","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:08.546704Z","iopub.execute_input":"2023-10-23T12:42:08.547097Z","iopub.status.idle":"2023-10-23T12:42:08.581471Z","shell.execute_reply.started":"2023-10-23T12:42:08.547056Z","shell.execute_reply":"2023-10-23T12:42:08.580375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 定義一些常量\nBASE_PATH = \"/kaggle/input/rsna-2023-abdominal-trauma-detection\"\nIMAGE_DIR = \"/tmp/dataset/rsna-atd\"\nlocal_weight_path = '/kaggle/input/resnet18/resnet18_model_weights.pth'\n\nSTRIDE = 10","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:08.582838Z","iopub.execute_input":"2023-10-23T12:42:08.583642Z","iopub.status.idle":"2023-10-23T12:42:08.596024Z","shell.execute_reply.started":"2023-10-23T12:42:08.583601Z","shell.execute_reply":"2023-10-23T12:42:08.594949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Config:\n    IMAGE_SIZE = [256, 256]\n    RESIZE_DIM = 256\n    BATCH_SIZE = 64\n    PREFETCH_FACTOR = 2  # 預加載因子，可以根據需要進行調整\n    TARGET_COLS = [\"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\"]\nconfig = Config()","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:08.598665Z","iopub.execute_input":"2023-10-23T12:42:08.599759Z","iopub.status.idle":"2023-10-23T12:42:08.610349Z","shell.execute_reply.started":"2023-10-23T12:42:08.599717Z","shell.execute_reply":"2023-10-23T12:42:08.609015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MultiHeadModel(ABC, nn.Module): \n\n    def __init__(self):\n        super().__init__()    \n        self.main_layers = self.define_main_layers()\n        \n        # Global Average Pooling\n        self.global_avg_pool = nn.AdaptiveAvgPool2d((1, 1))\n        \n        # Break into 5 heads \n        self.fc_bowel  = nn.Linear(self.hidden_dim, 32)\n        self.fc_extra  = nn.Linear(self.hidden_dim, 32)\n        self.fc_liver  = nn.Linear(self.hidden_dim, 32)\n        self.fc_kidney = nn.Linear(self.hidden_dim, 32)\n        self.fc_spleen = nn.Linear(self.hidden_dim, 32)\n        \n        # Prediction heads \n        self.out_bowel  = nn.Linear(32, 1)\n        self.out_extra  = nn.Linear(32, 1)\n        self.out_liver  = nn.Linear(32, 3)\n        self.out_kidney = nn.Linear(32, 3)\n        self.out_spleen = nn.Linear(32, 3)       \n    \n    @abstractmethod\n    def define_main_layers(self) -> nn.Sequential:\n        pass \n    \n    @abstractproperty\n    def hidden_dim(self) -> int:\n        pass\n    \n    def forward(self, x):\n        # Main Layers + GAP\n        x = self.main_layers(x)\n        x = self.global_avg_pool(x)              \n        x = x.view(x.size(0), -1)              \n        \n        # Split into 5 Heads\n        x_bowel  = nn.SiLU()(self.fc_bowel(x)) \n        x_extra  = nn.SiLU()(self.fc_extra(x))\n        x_liver  = nn.SiLU()(self.fc_liver(x))\n        x_kidney = nn.SiLU()(self.fc_kidney(x))\n        x_spleen = nn.SiLU()(self.fc_spleen(x))\n        \n        # Prediction heads\n        out_bowel  = torch.sigmoid(self.out_bowel(x_bowel))\n        out_extra  = torch.sigmoid(self.out_extra(x_extra))\n        out_liver  = nn.Softmax(dim=1)(self.out_liver(x_liver))\n        out_kidney = nn.Softmax(dim=1)(self.out_kidney(x_kidney))\n        out_spleen = nn.Softmax(dim=1)(self.out_spleen(x_spleen))\n        \n        return [out_bowel, out_extra, out_liver, out_kidney, out_spleen]","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:08.61211Z","iopub.execute_input":"2023-10-23T12:42:08.612651Z","iopub.status.idle":"2023-10-23T12:42:08.632521Z","shell.execute_reply.started":"2023-10-23T12:42:08.612615Z","shell.execute_reply":"2023-10-23T12:42:08.631078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ResNet(MultiHeadModel):\n\n    hidden_dim = 512\n    \n    def define_main_layers(self): \n        # Load pre-trained ResNet model + higher level layers\n        #resnet = models.resnet18(pretrained='IMAGENET1K_V1')\n        resnet = models.resnet18(pretrained=False)\n        \n        #load pretraining weight\n        resnet.load_state_dict(torch.load(local_weight_path))\n                             \n        # Remove classification head and GAP layer\n        # resnet.children() returns iter of nn.Module, unpack with * then nn.Sequential\n        main_layers = nn.Sequential(*list(resnet.children())[:-2])\n\n        # Change first layer for 1 color channel\n        # Weights initialized as avg of original weights\n        original_weights = resnet.conv1.weight.clone()\n        new_conv1 = nn.Conv2d(\n                        in_channels  = 1, \n                        out_channels = 64, \n                        kernel_size  = 7,\n                        stride       = 2,\n                        padding      = 3,\n                        bias         = False\n                        )\n        new_conv1.weight.data = original_weights.sum(dim=1, keepdim=True) / 3.0\n        main_layers[0] = new_conv1\n\n        return main_layers","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:08.634393Z","iopub.execute_input":"2023-10-23T12:42:08.634816Z","iopub.status.idle":"2023-10-23T12:42:08.656402Z","shell.execute_reply.started":"2023-10-23T12:42:08.634781Z","shell.execute_reply":"2023-10-23T12:42:08.655191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# INPUT_MODEL_PATH = \"/kaggle/input/resnetkflod/resnet_kflod.pth\"\n# MODEL_PATH = \"/kaggle/working/resnet_kflod.pth\"\n\n\nINPUT_MODEL_PATH = \"/kaggle/input/102380w/model_80w_balance.pth\"\nMODEL_PATH = \"/kaggle/working/model_80w_balance.pth\"","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:08.658385Z","iopub.execute_input":"2023-10-23T12:42:08.658789Z","iopub.status.idle":"2023-10-23T12:42:08.679352Z","shell.execute_reply.started":"2023-10-23T12:42:08.658753Z","shell.execute_reply":"2023-10-23T12:42:08.677338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! cp {INPUT_MODEL_PATH} ./ # 將模型複製到工作目錄\n\nimport torch\n\n# 載入整個模型\nmodel =  torch.load(MODEL_PATH, map_location=torch.device('cpu'))\n\n# 將模型設置為評估模式\nmodel.eval()\n","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:08.684222Z","iopub.execute_input":"2023-10-23T12:42:08.686279Z","iopub.status.idle":"2023-10-23T12:42:10.033816Z","shell.execute_reply.started":"2023-10-23T12:42:08.686202Z","shell.execute_reply":"2023-10-23T12:42:10.0319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 讀取測試數據集的元數據\nmeta_df = pd.read_csv(f\"{BASE_PATH}/test_series_meta.csv\")\n\n# 顯示不重複的病患數量\nnum_rows = meta_df.shape[0]\nunique_patients = meta_df[\"patient_id\"].nunique()\n\nprint(f\"{num_rows=}\")\nprint(f\"{unique_patients=}\")","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:10.036491Z","iopub.execute_input":"2023-10-23T12:42:10.037054Z","iopub.status.idle":"2023-10-23T12:42:10.053794Z","shell.execute_reply.started":"2023-10-23T12:42:10.037012Z","shell.execute_reply":"2023-10-23T12:42:10.052253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 創建測試數據集的路徑\nmeta_df[\"dicom_folder\"] = BASE_PATH + \"/\" + \"test_images\"\\\n                                    + \"/\" + meta_df.patient_id.astype(str)\\\n                                    + \"/\" + meta_df.series_id.astype(str)\n\ntest_folders = meta_df.dicom_folder.tolist()\ntest_paths = []\nfor folder in tqdm(test_folders):\n    #print(folder)\n    test_paths += sorted(glob(os.path.join(folder, \"*dcm\")))[::STRIDE]\n\ntest_df = pd.DataFrame(test_paths, columns=[\"dicom_path\"])\ntest_df[\"patient_id\"] = test_df.dicom_path.map(lambda x: int(x.split(\"/\")[-3]))\ntest_df[\"series_id\"] = test_df.dicom_path.map(lambda x: int(x.split(\"/\")[-2]))\ntest_df[\"instance_number\"] = test_df.dicom_path.map(lambda x: int(x.split(\"/\")[-1].replace(\".dcm\", \"\")))\n\ntest_df[\"image_path\"] = f\"{IMAGE_DIR}/test_images\"\\\n                    + \"/\" + test_df.patient_id.astype(str)\\\n                    + \"/\" + test_df.series_id.astype(str)\\\n                    + \"/\" + test_df.instance_number.astype(str) + \".png\"\n#test_df","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:10.05645Z","iopub.execute_input":"2023-10-23T12:42:10.056941Z","iopub.status.idle":"2023-10-23T12:42:10.105466Z","shell.execute_reply.started":"2023-10-23T12:42:10.056866Z","shell.execute_reply":"2023-10-23T12:42:10.103414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -r {IMAGE_DIR}\nos.makedirs(f\"{IMAGE_DIR}/train_images\", exist_ok=True)\nos.makedirs(f\"{IMAGE_DIR}/test_images\", exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:10.107264Z","iopub.execute_input":"2023-10-23T12:42:10.10765Z","iopub.status.idle":"2023-10-23T12:42:11.264987Z","shell.execute_reply.started":"2023-10-23T12:42:10.107619Z","shell.execute_reply":"2023-10-23T12:42:11.263258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def standardize_pixel_array(dcm):\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        new_array = (pixel_array << bit_shift).astype(dtype) >>  bit_shift\n        pixel_array = pydicom.pixel_data_handlers.util.apply_modality_lut(new_array, dcm)\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    return data\n\n# 縮放並儲存圖像\ndef resize_and_save(file_paths, IMAGE_DIR):\n    for file_path in file_paths:\n        img = read_xray(file_path)\n        h, w = img.shape[:2]\n        img = cv2.resize(img, (config.RESIZE_DIM, config.RESIZE_DIM), cv2.INTER_LINEAR)\n        img = (img * 255).astype(np.uint8)\n        print(file_path)\n        sub_path = file_path.split(\"/\", 4)[-1].split(\".dcm\")[0] + \".png\"\n        print(sub_path)\n        infos = sub_path.split(\"/\")\n        pid = int(infos[-3])\n        sid = int(infos[-2])\n        iid = infos[-1]; iid = iid.replace(\".png\",\"\")\n        new_path = os.path.join(IMAGE_DIR, sub_path)\n        print(new_path)\n        os.makedirs(new_path.rsplit(\"/\", 1)[0], exist_ok=True)\n        cv2.imwrite(new_path, img)\n\n","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:11.26748Z","iopub.execute_input":"2023-10-23T12:42:11.26804Z","iopub.status.idle":"2023-10-23T12:42:11.287061Z","shell.execute_reply.started":"2023-10-23T12:42:11.267989Z","shell.execute_reply":"2023-10-23T12:42:11.285169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 呼叫函式執行圖像處理\nfile_paths = test_df.dicom_path.tolist()\nresize_and_save(file_paths, IMAGE_DIR)","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:11.289409Z","iopub.execute_input":"2023-10-23T12:42:11.290118Z","iopub.status.idle":"2023-10-23T12:42:11.384388Z","shell.execute_reply.started":"2023-10-23T12:42:11.290072Z","shell.execute_reply":"2023-10-23T12:42:11.382947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nfrom torchvision import transforms\nfrom torch.utils.data import Dataset, DataLoader\nfrom PIL import Image\n\n# 解碼圖像\ndef decode_image(image_path):\n    image = Image.open(image_path)\n    image = transforms.Resize(config.IMAGE_SIZE)(image)\n    return image\n\nclass CustomDataset(Dataset):\n    def __init__(self, image_paths, transform=None):\n        self.image_paths = image_paths\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.image_paths)\n\n    def __getitem__(self, idx):\n        image_path = self.image_paths[idx]\n        image = decode_image(image_path)\n        \n        if self.transform:\n            image = self.transform(image)\n        \n        return image\n\n# 創建測試數據集的 DataLoader\ndef build_dataset(image_paths):\n    transform = transforms.Compose([\n        transforms.ToTensor(),\n    ])\n    \n    ds = CustomDataset(image_paths, transform=transform)\n    dataloader = DataLoader(\n        ds,\n        batch_size=config.BATCH_SIZE,\n        shuffle=True,\n        num_workers=1,\n        pin_memory=True,\n    )\n    return dataloader","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:11.386472Z","iopub.execute_input":"2023-10-23T12:42:11.387147Z","iopub.status.idle":"2023-10-23T12:42:11.401309Z","shell.execute_reply.started":"2023-10-23T12:42:11.387103Z","shell.execute_reply":"2023-10-23T12:42:11.39944Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 使用方法\npaths = test_df.image_path.tolist()\nds = build_dataset(paths)\nimages = next(iter(ds))","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:11.404147Z","iopub.execute_input":"2023-10-23T12:42:11.405262Z","iopub.status.idle":"2023-10-23T12:42:11.491503Z","shell.execute_reply.started":"2023-10-23T12:42:11.405204Z","shell.execute_reply":"2023-10-23T12:42:11.490121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **預測結果**","metadata":{}},{"cell_type":"code","source":"# 後處理預測結果\ndef post_proc(pred):\n    proc_pred = np.empty((pred.shape[0], 2*2 + 3*3), dtype=\"float32\")\n    \n    # bowel, extravasation\n    proc_pred[:, 0] = pred[:, 0]\n    proc_pred[:, 1] = 1 - proc_pred[:, 0]\n    proc_pred[:, 2] = pred[:, 1]\n    proc_pred[:, 3] = 1 - proc_pred[:, 2]\n\n    # liver, kidney, spleen\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-10-23T12:42:11.497615Z","iopub.execute_input":"2023-10-23T12:42:11.498941Z","iopub.status.idle":"2023-10-23T12:42:11.509606Z","shell.execute_reply.started":"2023-10-23T12:42:11.498863Z","shell.execute_reply":"2023-10-23T12:42:11.508595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 進行推論並生成提交文件\npatient_ids = test_df[\"patient_id\"].unique()\npatient_preds = np.zeros(\n    shape=(len(patient_ids), 13),  # 修正為 13\n    dtype=\"float32\"\n)\n\nfor pidx, patient_id in tqdm(enumerate(patient_ids), total=len(patient_ids), desc=\"Patients \"):\n    #print(f\"Patient ID: {patient_id}\")\n\n    patient_df = test_df[test_df[\"patient_id\"] == patient_id]\n    patient_paths = patient_df.image_path.tolist()\n\n    # 創建空的 numpy 數組以保存推論結果\n    patient_pred = np.zeros(\n        shape=(len(patient_paths), 11),  # 修正為 11\n        dtype=\"float32\"\n    )\n\n    # 使用數據加載器進行圖像的批次推論\n    for batch_images in build_dataset(patient_paths):\n        with torch.no_grad():\n            batch_pred = model(batch_images)  # 進行批次推論\n        batch_pred = torch.cat(batch_pred, dim=-1).numpy().astype(\"float32\")\n        patient_pred[:len(batch_images), :] = batch_pred\n        #print(patient_pred)\n    # 對每個病患的推論結果進行後處理\n    patient_pred = np.mean(patient_pred.reshape(1, len(patient_paths), 11), axis=0)\n    patient_pred = np.max(patient_pred, axis=0, keepdims=True)\n\n    # 將結果添加到整體病患預測中\n    patient_preds[pidx, :] += post_proc(patient_pred)[0]\n    del patient_df, patient_paths, patient_pred\n    gc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:11.514356Z","iopub.execute_input":"2023-10-23T12:42:11.515073Z","iopub.status.idle":"2023-10-23T12:42:13.126165Z","shell.execute_reply.started":"2023-10-23T12:42:11.515023Z","shell.execute_reply":"2023-10-23T12:42:13.124324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Group by different sample weights\n# scale_by_2 = ['kidney_low','liver_low','spleen_low','bowel_injury']\n# scale_by_4 = ['spleen_high','kidney_high','liver_high']\n# scale_by_6 = ['extravasation_injury']\n# scale_healthy = ['bowel_healthy', 'extravasation_healthy', 'kidney_healthy', 'liver_healthy', 'spleen_healthy']\n\n# # Scale factors based on described metric \n\n# MULTIPLIER = 0.985908\n\n# # MULTIPLIER NEXT = 0.0.995908001\n# # MULTIPLIER BEST = 0.995908\n# # MULTIPLIER DONE = 0.985908, 0.99590805, 0.995908001, 0.9959080000000001, 0.995907999999999, 0.99590799, 0.99590801, 0.9959079, 0.9959081, 0.9959082, 0.9959087, 0.995906, 0.995907, 0.995909, 0.9959085, 0.995913, 0.995905, 0.995915, 0.99999999, 0.98989999, 0.978645131, 0.998856151, 0.999153158, 1.015196, 1.005318, 0.97453, 0.987543, 0.99591\n\n# sf_2 = 2.753135 * MULTIPLIER\n# sf_4 = 6.7531358 * MULTIPLIER\n# sf_6 = 28.78613121 * MULTIPLIER\n# scale_h = 0.995215 * MULTIPLIER","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:13.128432Z","iopub.execute_input":"2023-10-23T12:42:13.129796Z","iopub.status.idle":"2023-10-23T12:42:13.138922Z","shell.execute_reply.started":"2023-10-23T12:42:13.129736Z","shell.execute_reply":"2023-10-23T12:42:13.136747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 創建提交文件\npred_df = pd.DataFrame({\"patient_id\":patient_ids,})\npred_df[config.TARGET_COLS] = patient_preds.astype(\"float32\")\n\n\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# #---------------\n# # Scale each target \n# sub_df[scale_by_2] *=sf_2\n# sub_df[scale_by_4] *=sf_4\n# sub_df[scale_by_6] *=sf_6\n# sub_df[scale_healthy] *=scale_h\n# #---------------\n\nsub_df.to_csv(\"submission.csv\",index=False)\nsub_df","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:13.141154Z","iopub.execute_input":"2023-10-23T12:42:13.142179Z","iopub.status.idle":"2023-10-23T12:42:13.200246Z","shell.execute_reply.started":"2023-10-23T12:42:13.142122Z","shell.execute_reply":"2023-10-23T12:42:13.198619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# pred_df = pd.DataFrame({\"patient_id\":patient_ids,})\n# pred_df[config.TARGET_COLS] = patient_preds.astype(\"float32\")\n# pred_df.to_csv(\"submission.csv\",index=False)\n# pred_df","metadata":{"execution":{"iopub.status.busy":"2023-10-23T12:42:13.204562Z","iopub.execute_input":"2023-10-23T12:42:13.205612Z","iopub.status.idle":"2023-10-23T12:42:13.211688Z","shell.execute_reply.started":"2023-10-23T12:42:13.205552Z","shell.execute_reply":"2023-10-23T12:42:13.210278Z"},"trusted":true},"execution_count":null,"outputs":[]}]}