{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## 3rd Place Solution Inference\n\nFor training see instructions in [this repo](https://github.com/darraghdog/RSNA22) which is linked in this notebook's attached dataset [github-rsna22](https://www.kaggle.com/datasets/darraghdog/github-rsna22/versions/6).\n\nThis notebook scores public `0.2287` and private `0.2453`.\nInference runs in approximately 4 hours (1.5 hours for bounding box extraction, and 2.5 hours for inference).","metadata":{}},{"cell_type":"markdown","source":"![](https://github.com/darraghdog/RSNA22/raw/main/figs/study.gif)","metadata":{"execution":{"iopub.status.busy":"2022-10-31T08:31:04.742634Z","iopub.execute_input":"2022-10-31T08:31:04.743701Z","iopub.status.idle":"2022-10-31T08:31:05.909636Z","shell.execute_reply.started":"2022-10-31T08:31:04.743652Z","shell.execute_reply":"2022-10-31T08:31:05.908284Z"}}},{"cell_type":"code","source":"!pip install -r ../input/github-rsna22/requirements.txt --no-index --find-links=file:///kaggle/input/rsna2022-pip-wheels/ -q","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-04-04T01:58:21.939553Z","iopub.execute_input":"2023-04-04T01:58:21.940271Z","iopub.status.idle":"2023-04-04T01:58:54.705884Z","shell.execute_reply.started":"2023-04-04T01:58:21.940226Z","shell.execute_reply":"2023-04-04T01:58:54.704601Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp -r ../input/github-rsna22/* ./","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:58:54.70888Z","iopub.execute_input":"2023-04-04T01:58:54.709951Z","iopub.status.idle":"2023-04-04T01:58:55.794307Z","shell.execute_reply.started":"2023-04-04T01:58:54.709902Z","shell.execute_reply":"2023-04-04T01:58:55.792954Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport scipy as sp\nimport os\nimport json\nimport sys\nimport importlib\nimport multiprocessing as mp\nimport gc\nfrom tqdm.auto import tqdm\nimport glob\nimport torch\nfrom copy import copy\nfrom torch.cuda.amp import GradScaler, autocast\nfrom torch.utils.data import DataLoader\nimport timm\nimport pylibjpeg\nimport pydicom\nfrom PIL import Image\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:58:55.796291Z","iopub.execute_input":"2023-04-04T01:58:55.797194Z","iopub.status.idle":"2023-04-04T01:58:59.257253Z","shell.execute_reply.started":"2023-04-04T01:58:55.797145Z","shell.execute_reply":"2023-04-04T01:58:59.256023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.backends.cudnn.benchmark = True\n\nsys.path.append('./configs')\nsys.path.append('./data')\nsys.path.append('./models')\nsys.path.append('./postprocess')","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:58:59.260279Z","iopub.execute_input":"2023-04-04T01:58:59.261439Z","iopub.status.idle":"2023-04-04T01:58:59.26733Z","shell.execute_reply.started":"2023-04-04T01:58:59.261398Z","shell.execute_reply":"2023-04-04T01:58:59.266059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"COMP_FOLDER = '../input/rsna-2022-cervical-spine-fracture-detection/'\nDATA_FOLDER = COMP_FOLDER + 'test_images/'\nMETA_DF = COMP_FOLDER + 'test.csv'\n\ntrain_df = pd.read_csv(COMP_FOLDER + 'train.csv')\ntest_df = pd.read_csv(COMP_FOLDER + 'test.csv')\nsample_submission = pd.read_csv(COMP_FOLDER + 'sample_submission.csv')\n\nkeycols = 'StudyInstanceUID slice_number'.split()\ndf = pd.DataFrame([i.replace('.dcm', '').split('/')[-2:] \n                       for i in glob.glob(DATA_FOLDER+'/*/*.dcm')], columns = keycols)\ndf['slice_number'] = df['slice_number'].astype(int)\ndf = df.sort_values(keycols).reset_index(drop = True)\n\nPUBLIC_RUN = len(test_df) == 3\nN_CORES = mp.cpu_count()\nMIXED_PRECISION = False\nPIN_MEMORY = True\nDL_PREFETCH_FACTOR = 1\nNUM_SLICES_PER_UID_BBOX = 600\n\nRAM_CHECK = False\nOOF_CHECK = False\nFOLD = 3\nMAX_FOLDS = 99\n\nassert (RAM_CHECK + OOF_CHECK) <= 1\n\nDEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'\n\nif PUBLIC_RUN is False:\n    RAM_CHECK = False\n    OOF_CHECK = False\n\nif RAM_CHECK is True:\n    test_df = train_df[:250].reset_index(drop=True)  # Number to be checked\n    DATA_FOLDER = DATA_FOLDER.replace('test','train')\n    META_DF = META_DF.replace('test','train')\n    print(test_df.head())\n    \n    keycols = 'StudyInstanceUID slice_number'.split()\n    df = pd.DataFrame([i.replace('.dcm', '').split('/')[-2:] \n                       for i in glob.glob(DATA_FOLDER+'/*/*.dcm')], columns = keycols)\n    df['slice_number'] = df['slice_number'].astype(int)\n    df = df.sort_values(keycols).reset_index(drop = True)\n    \n    df = df[df.StudyInstanceUID.isin(test_df.StudyInstanceUID)].reset_index(drop = True)\n    \nif OOF_CHECK is True:\n    test_df = pd.read_csv('../input/rsna2022-train-dataset/train_folded_v01.csv').query(f'fold == {FOLD}').reset_index(drop = True)\n    DATA_FOLDER = DATA_FOLDER.replace('test','train')\n    META_DF = META_DF.replace('test','train')\n    print(test_df.head())\n    \n    keycols = 'StudyInstanceUID slice_number'.split()\n    df = pd.DataFrame([i.replace('.dcm', '').split('/')[-2:] \n                       for i in glob.glob(DATA_FOLDER+'/*/*.dcm')], columns = keycols)\n    df['slice_number'] = df['slice_number'].astype(int)\n    df = df.sort_values(keycols).reset_index(drop = True)\n    \n    df = df[df.StudyInstanceUID.isin(test_df.StudyInstanceUID)].reset_index(drop = True)\n\ndf['fold'] = -1\nprint(train_df.shape)\nprint(test_df.shape)\nprint(df.shape)\ngc.collect()\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:58:59.26919Z","iopub.execute_input":"2023-04-04T01:58:59.269663Z","iopub.status.idle":"2023-04-04T01:58:59.752641Z","shell.execute_reply.started":"2023-04-04T01:58:59.269622Z","shell.execute_reply":"2023-04-04T01:58:59.751526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n# change it to nn.BCELoss(reduction='none') if you have sigmoid activation in last layer\nloss_fn = torch.nn.BCELoss(reduction=\"none\") \ncompetition_weights = {\n    '-' : torch.tensor([7, 1, 1, 1, 1, 1, 1, 1], dtype=torch.float, device=device),\n    '+' : torch.tensor([14, 2, 2, 2, 2, 2, 2, 2], dtype=torch.float, device=device),\n}","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:58:59.755002Z","iopub.execute_input":"2023-04-04T01:58:59.755966Z","iopub.status.idle":"2023-04-04T01:59:02.560815Z","shell.execute_reply.started":"2023-04-04T01:58:59.755925Z","shell.execute_reply":"2023-04-04T01:59:02.559781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_cfg(CFG):\n    cfg = importlib.import_module('default_config')\n    importlib.reload(cfg)\n    cfg = importlib.import_module(CFG)\n    importlib.reload(cfg)\n    cfg = copy(cfg.cfg)\n    cfg.post_process_pipeline = importlib.import_module(cfg.post_process_pipeline).post_process_pipeline\n\n    cfg.data_dir = COMP_FOLDER\n    cfg.test_data_folder = DATA_FOLDER\n    cfg.mixed_precision = MIXED_PRECISION\n    cfg.pretrained = False\n    cfg.pretrained_weights = False\n    cfg.batch_size = cfg.batch_size\n    cfg.offline_inference = True\n\n    print(CFG, cfg.model, cfg.dataset, cfg.backbone, cfg.pretrained_weights, cfg.post_process_pipeline)\n    \n    return cfg\n\ndef get_dl(cfg):\n    ds = importlib.import_module(cfg.dataset)\n    importlib.reload(ds)\n\n    CustomDataset = ds.CustomDataset\n    batch_to_device = ds.batch_to_device\n\n    test_ds = CustomDataset(df, cfg, cfg.val_aug, mode=\"test\")\n    test_dl = DataLoader(test_ds, shuffle=False, batch_size=cfg.batch_size, collate_fn=ds.val_collate_fn, num_workers=N_CORES, pin_memory=PIN_MEMORY, prefetch_factor = DL_PREFETCH_FACTOR)\n\n    return test_dl, batch_to_device\n\ndef get_bb_dl(cfg):\n    ds = importlib.import_module(cfg.dataset)\n    importlib.reload(ds)\n\n    CustomDataset = ds.CustomDataset\n    batch_to_device = ds.batch_to_device\n\n    test_ds = CustomDataset(bbdf, cfg, cfg.val_aug, mode=\"test\")\n    test_dl = DataLoader(test_ds, shuffle=False, batch_size=cfg.batch_size, collate_fn=ds.val_collate_fn, num_workers=N_CORES, pin_memory=PIN_MEMORY, prefetch_factor = DL_PREFETCH_FACTOR)\n\n    return test_dl, batch_to_device\n\ndef get_state_dict(sd_fp):\n    sd = torch.load(sd_fp, map_location=\"cpu\")\n    sd = {k.replace(\"module.\", \"\"):v for k,v in sd.items()}\n    return sd\n\ndef get_nets(cfg,state_dicts,test_ds):\n    model = importlib.import_module(cfg.model)\n    importlib.reload(model)\n    Net = model.Net\n\n    nets = []\n\n    for i,state_dict in enumerate(state_dicts):\n        net = Net(cfg).eval().to(DEVICE)\n        print(\"loading dict\")\n        sd = get_state_dict(state_dict)\n        if \"model\" in sd.keys():\n            sd = sd[\"model\"]\n        net.load_state_dict(sd, strict=True)\n        nets += [net.half()]\n        del sd\n        gc.collect()\n    return nets\n\ndef competiton_loss_row_norm(y_hat, y):\n    loss = loss_fn(y_hat, y)\n    weights = y * competition_weights['+'] + (1 - y) * competition_weights['-']\n    loss = (loss * weights).sum(axis=1)\n    w_sum = weights.sum(axis=1)\n    loss = torch.div(loss, w_sum)\n    return loss.mean().item()\n\ndef window_range(g, thresh = 0.1, window = 5, min_periods=3, center=True):\n    bbseqprobas = g.has_bbox.rolling(window, min_periods=min_periods, center=center).mean()\n    if bbseqprobas.max() <= thresh:\n        sn_from, sn_to = g.slice_numbers.iloc[[0,-1]]\n        return [sn_from, sn_to]\n    bb_range = np.where(bbseqprobas > thresh)[0]\n    sn_from = g.slice_numbers.iloc[bb_range[0]]\n    sn_to = g.slice_numbers.iloc[bb_range[-1]]\n    return [sn_from, sn_to]","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:59:02.56351Z","iopub.execute_input":"2023-04-04T01:59:02.563807Z","iopub.status.idle":"2023-04-04T01:59:02.580942Z","shell.execute_reply.started":"2023-04-04T01:59:02.56378Z","shell.execute_reply":"2023-04-04T01:59:02.579669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bbdf = df\nbbdf['count'] = bbdf.groupby('StudyInstanceUID')['fold'].transform('count').values\nbbdf['cumcount'] = 1+ bbdf.groupby('StudyInstanceUID')['fold'].transform('cumcount').values\nbbdf['key'] = (bbdf['cumcount']  / (bbdf['count'] / NUM_SLICES_PER_UID_BBOX)).round().astype(int)\nbbdf = bbdf.drop_duplicates('StudyInstanceUID key'.split()).drop('count cumcount key'.split(), 1)","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:59:02.582523Z","iopub.execute_input":"2023-04-04T01:59:02.583666Z","iopub.status.idle":"2023-04-04T01:59:02.606508Z","shell.execute_reply.started":"2023-04-04T01:59:02.583625Z","shell.execute_reply":"2023-04-04T01:59:02.604248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"name = 'cfg_loc_dh_01B'\n\ncfg = get_cfg(name)\ncfg.meta_df = META_DF\ncfg.data_folder = DATA_FOLDER\ncfg.verify_sample = False\ncfg.load_jpg = False\ncfg.batch_size = 8\ncfg.drop_scans = []\ntest_dl, batch_to_device = get_bb_dl(cfg)\n\n\nstate_dict_fps = sorted(glob.glob('../input/weights-cfg-loc-dh-01b/check*'))[:MAX_FOLDS]\nprint('\\n'.join(state_dict_fps))\nif OOF_CHECK:\n    nets = get_nets(cfg,state_dict_fps[:1], test_dl.dataset)\nelse:\n    nets = get_nets(cfg,state_dict_fps, test_dl.dataset)","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:59:02.608358Z","iopub.execute_input":"2023-04-04T01:59:02.608755Z","iopub.status.idle":"2023-04-04T01:59:16.073202Z","shell.execute_reply.started":"2023-04-04T01:59:02.608716Z","shell.execute_reply":"2023-04-04T01:59:16.072101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_data = {}\npreds = []\nuids = []\nslices = []\n#ids = []\nwith torch.inference_mode():\n    for tt, batch in tqdm(enumerate(test_dl), total = len(test_dl)):\n        batch = batch_to_device(batch,DEVICE)\n        batch['image'] = batch['image'].half()\n        outs = [net(batch) for net in nets]\n        preds += [torch.stack([out['preds'] for out in outs], dim=0).cpu().mean(0)]\n        uids +=  [outs[0]['StudyUID'].cpu()]\n        slices += [outs[0]['slice_numbers'].cpu()]\n        if tt % 5 == 0:\n            gc.collect()\n            torch.cuda.empty_cache()\n        #ids += batch['StudyUID'].cpu()\npreds = torch.cat(preds, dim=0)\nuids = torch.cat(uids, dim=0)\nslices = torch.cat(slices, dim=0)\npredbbdf = pd.DataFrame(preds.float().clip(0, 1).numpy(), columns = 'x0 y0 x1 y1 has_bbox'.split())\npredbbdf['uid'] = uids.numpy()\npredbbdf['slice_numbers'] = slices.numpy()[:,1]\npredbbdf['StudyInstanceUID'] = test_dl.dataset.df.loc[test_dl.dataset.ids]['StudyInstanceUID'].values\n\n# Hack for studies with no bounding box > 0.5.... - just put in a dummy box and let it go thru the pipeline\npredbbdf['max_has_bbox'] = predbbdf.groupby('StudyInstanceUID')['has_bbox'].transform(max)\npredbbdf.loc[predbbdf.max_has_bbox<0.5, 'x0 y0'.split()] = 0.2\npredbbdf.loc[predbbdf.max_has_bbox<0.5, 'x1 y1'.split()] = 0.8\npredbbdf.loc[predbbdf.max_has_bbox<0.5, 'has_bbox'.split()] = 0.51\npredbbdf = predbbdf.drop('max_has_bbox', 1)\n\nbbpreddf = pd.concat([ \\\n    predbbdf.query('has_bbox > 0.5').groupby('StudyInstanceUID')['x0 y0'.split()].apply(min),\n    predbbdf.query('has_bbox > 0.5').groupby('StudyInstanceUID')['x1 y1'.split()].apply(max)], 1)\n\nwrls = predbbdf.groupby('StudyInstanceUID').apply(window_range)\nwrdf = pd.DataFrame(wrls.tolist(), index = wrls.index, columns = 'slnum_from slnum_to'.split())\nbbpreddf['slnum_from slnum_to'.split()] = wrdf.loc[bbpreddf.index]\nbbpreddf['slnum_max'] = predbbdf.groupby('StudyInstanceUID')['slice_numbers'].max().loc[bbpreddf.index]\n\nbbpreddf.iloc[:,:2] = np.floor((bbpreddf.iloc[:,:2] * 512)).astype(int).clip(0, 512)\nbbpreddf.iloc[:,2:4] = np.ceil((bbpreddf.iloc[:,2:4] * 512)).astype(int).clip(0, 512)\nbbpreddf.to_csv('train_bbox_pred_v01.csv')\n\n((bbpreddf.slnum_to - bbpreddf.slnum_from) / bbpreddf.slnum_max).hist(bins = 50 )","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:59:16.07787Z","iopub.execute_input":"2023-04-04T01:59:16.078419Z","iopub.status.idle":"2023-04-04T01:59:43.497862Z","shell.execute_reply.started":"2023-04-04T01:59:16.078388Z","shell.execute_reply":"2023-04-04T01:59:43.496805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del test_dl, nets, preds, uids, slices, predbbdf, bbpreddf\ngc.collect()\ntorch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:59:43.499333Z","iopub.execute_input":"2023-04-04T01:59:43.501763Z","iopub.status.idle":"2023-04-04T01:59:43.817989Z","shell.execute_reply.started":"2023-04-04T01:59:43.501718Z","shell.execute_reply":"2023-04-04T01:59:43.815183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!head train_bbox_pred_v01.csv","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:59:43.820004Z","iopub.execute_input":"2023-04-04T01:59:43.820723Z","iopub.status.idle":"2023-04-04T01:59:44.867824Z","shell.execute_reply.started":"2023-04-04T01:59:43.820681Z","shell.execute_reply":"2023-04-04T01:59:44.866588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"name = 'cfg_dh_fracseq_04F_crop_gx1'\n\ncfg = get_cfg(name)\ncfg.meta_df = META_DF\ncfg.data_folder = DATA_FOLDER\ncfg.verify_sample = False\ncfg.load_jpg = False\ncfg.cnn_chunk_size = 32\ncfg.bbox_df = 'train_bbox_pred_v01.csv'\ncfg.batch_size=1\ncfg.norm_on_cuda=True\ntest_dl, batch_to_device = get_dl(cfg)\ntest_dl.dataset.norm_mean = test_dl.dataset.norm_mean.to(DEVICE)\ntest_dl.dataset.norm_std = test_dl.dataset.norm_std.to(DEVICE)\ntest_dl.dataset.metadf = pd.DataFrame({'StudyInstanceUID': \\\n                                       test_dl.dataset.df.index.unique()}).set_index('StudyInstanceUID')\ntest_dl.dataset.metadf[['patient_overall'] + cfg.target] = 0.\n\nstate_dict_fps = sorted(glob.glob('../input/cfg-dh-fracseq-04f-crop-gx1/*check*'))\nif OOF_CHECK:\n    state_dict_fps = [i for i in state_dict_fps if f'fold{FOLD}_' in i]\nstate_dict_fps = state_dict_fps[:MAX_FOLDS]\n\nprint('\\n'.join(state_dict_fps))\nif OOF_CHECK:\n    nets = get_nets(cfg,state_dict_fps[:1], test_dl.dataset)\nelse:\n    nets = get_nets(cfg,state_dict_fps, test_dl.dataset)","metadata":{"execution":{"iopub.status.busy":"2023-04-04T01:59:44.869712Z","iopub.execute_input":"2023-04-04T01:59:44.870344Z","iopub.status.idle":"2023-04-04T02:00:12.217769Z","shell.execute_reply.started":"2023-04-04T01:59:44.870308Z","shell.execute_reply":"2023-04-04T02:00:12.216598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"name = 'cfg_dh_fracseq_04G_crop_gx1'\n\ncfg = get_cfg(name)\ncfg.meta_df = META_DF\ncfg.data_folder = DATA_FOLDER\ncfg.verify_sample = False\ncfg.load_jpg = False\ncfg.cnn_chunk_size = 16\ncfg.bbox_df = 'train_bbox_pred_v01.csv'\ncfg.batch_size=1\ncfg.norm_on_cuda=True\ntest_dl, batch_to_device = get_dl(cfg)\ntest_dl.dataset.norm_mean = test_dl.dataset.norm_mean.to(DEVICE)#.half()\ntest_dl.dataset.norm_std = test_dl.dataset.norm_std.to(DEVICE)#.half()\ntest_dl.dataset.metadf = pd.DataFrame({'StudyInstanceUID': \\\n                                       test_dl.dataset.df.index.unique()}).set_index('StudyInstanceUID')\ntest_dl.dataset.metadf[['patient_overall'] + cfg.target] = 0.\n\n\nstate_dict_fps = sorted(glob.glob('../input/cfg-dh-fracseq-04g-crop-gx1/*check*'))\nif OOF_CHECK:\n    state_dict_fps = [i for i in state_dict_fps if f'fold{FOLD}_' in i]\nstate_dict_fps = state_dict_fps[:MAX_FOLDS]\n\nprint('\\n'.join(state_dict_fps))\nif OOF_CHECK:\n    nets += get_nets(cfg,state_dict_fps[:1], test_dl.dataset)\nelse:\n    nets += get_nets(cfg,state_dict_fps, test_dl.dataset)","metadata":{"execution":{"iopub.status.busy":"2023-04-04T02:00:12.219321Z","iopub.execute_input":"2023-04-04T02:00:12.22007Z","iopub.status.idle":"2023-04-04T02:00:29.244166Z","shell.execute_reply.started":"2023-04-04T02:00:12.220007Z","shell.execute_reply":"2023-04-04T02:00:29.243097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(nets))\nprint('Cnn chunk sizes : '+' '.join(map(str, [i.cfg.cnn_chunk_size for i in nets])))","metadata":{"execution":{"iopub.status.busy":"2023-04-04T02:00:29.245803Z","iopub.execute_input":"2023-04-04T02:00:29.246169Z","iopub.status.idle":"2023-04-04T02:00:29.251994Z","shell.execute_reply.started":"2023-04-04T02:00:29.246131Z","shell.execute_reply":"2023-04-04T02:00:29.250893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vaacoshl_data = {}\npreds = []\n#ids = []\nwith torch.inference_mode():\n    for tt, batch in tqdm(enumerate(test_dl), total = len(test_dl)):\n        batch = batch_to_device(batch,DEVICE)\n        batch['image'] = test_dl.dataset.norm4d( batch['image'] )\n        #batch['image'] = batch['image'].half()\n        outs = [net(batch) for net in nets]\n        preds += [torch.sigmoid(torch.stack([out['logits'] for out in outs], dim=0)).cpu().mean(0)]\n        if tt % 10 == 0:\n            gc.collect()\n            torch.cuda.empty_cache()\nids = test_dl.dataset.ids\npreds = torch.cat(preds, dim=0).float()\ndel test_dl, nets\ngc.collect()\ntorch.cuda.empty_cache()\n","metadata":{"execution":{"iopub.status.busy":"2023-04-04T02:00:29.253626Z","iopub.execute_input":"2023-04-04T02:00:29.2543Z","iopub.status.idle":"2023-04-04T02:01:17.82773Z","shell.execute_reply.started":"2023-04-04T02:00:29.254262Z","shell.execute_reply":"2023-04-04T02:01:17.826595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preddf = pd.DataFrame(preds.numpy(), columns = ['patient_overall'] + cfg.target)\npreddf['StudyInstanceUID'] = ids\npreddf = preddf.set_index('StudyInstanceUID')\npreddf.head()","metadata":{"execution":{"iopub.status.busy":"2023-04-04T02:01:17.829958Z","iopub.execute_input":"2023-04-04T02:01:17.830393Z","iopub.status.idle":"2023-04-04T02:01:17.854781Z","shell.execute_reply.started":"2023-04-04T02:01:17.830352Z","shell.execute_reply":"2023-04-04T02:01:17.853064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"subdf = preddf.reset_index().melt(id_vars=[\"StudyInstanceUID\"], var_name=\"row_id\", value_name=\"fractured\")\nsubdf['row_id'] = subdf[['StudyInstanceUID', 'row_id']] .agg('_'.join, axis=1)\nsubdf = subdf.drop('StudyInstanceUID', 1)\nsubdf.head()","metadata":{"execution":{"iopub.status.busy":"2023-04-04T02:01:17.856256Z","iopub.execute_input":"2023-04-04T02:01:17.85672Z","iopub.status.idle":"2023-04-04T02:01:17.875953Z","shell.execute_reply.started":"2023-04-04T02:01:17.856682Z","shell.execute_reply":"2023-04-04T02:01:17.874748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"subdf.to_csv('submission.csv', index = False)","metadata":{"execution":{"iopub.status.busy":"2023-04-04T02:01:17.87758Z","iopub.execute_input":"2023-04-04T02:01:17.87806Z","iopub.status.idle":"2023-04-04T02:01:17.889681Z","shell.execute_reply.started":"2023-04-04T02:01:17.877977Z","shell.execute_reply":"2023-04-04T02:01:17.888641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Clean up local directory\n!rm -rf ./*.txt\n!rm -rf ./*.py*","metadata":{"execution":{"iopub.status.busy":"2023-04-04T02:01:17.891221Z","iopub.execute_input":"2023-04-04T02:01:17.891834Z","iopub.status.idle":"2023-04-04T02:01:19.879879Z","shell.execute_reply.started":"2023-04-04T02:01:17.891794Z","shell.execute_reply":"2023-04-04T02:01:19.878482Z"},"trusted":true},"execution_count":null,"outputs":[]}]}