{"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 ../input/rsna-pip-wheels-v3/segmentation_models_pytorch-0.3.0-py3-none-any.whl --no-index --find-links=../input/rsna-pip-wheels-v3 -q","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:42:38.800022Z","iopub.execute_input":"2022-11-07T12:42:38.800381Z","iopub.status.idle":"2022-11-07T12:42:54.765974Z","shell.execute_reply.started":"2022-11-07T12:42:38.800301Z","shell.execute_reply":"2022-11-07T12:42:54.764862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install ../input/rsna-pip-wheels-v3/timm-0.6.11-py3-none-any.whl -q","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:42:54.768747Z","iopub.execute_input":"2022-11-07T12:42:54.769224Z","iopub.status.idle":"2022-11-07T12:43:24.721058Z","shell.execute_reply.started":"2022-11-07T12:42:54.769181Z","shell.execute_reply":"2022-11-07T12:43:24.719883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install ../input/rsna-pip-wheels-v3/python_gdcm-3.0.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -q","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:43:24.723155Z","iopub.execute_input":"2022-11-07T12:43:24.723556Z","iopub.status.idle":"2022-11-07T12:43:55.009179Z","shell.execute_reply.started":"2022-11-07T12:43:24.723505Z","shell.execute_reply":"2022-11-07T12:43:55.0077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install ../input/rsna-pip-wheels-v3/pylibjpeg-1.4.0-py3-none-any.whl","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:43:55.01132Z","iopub.execute_input":"2022-11-07T12:43:55.011901Z","iopub.status.idle":"2022-11-07T12:44:24.752478Z","shell.execute_reply.started":"2022-11-07T12:43:55.011857Z","shell.execute_reply":"2022-11-07T12:44:24.751128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import timm\ntimm.__version__","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:24.757427Z","iopub.execute_input":"2022-11-07T12:44:24.758186Z","iopub.status.idle":"2022-11-07T12:44:27.712618Z","shell.execute_reply.started":"2022-11-07T12:44:24.758147Z","shell.execute_reply":"2022-11-07T12:44:27.711694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport os\nimport sys\nimport importlib\n\nimport torch\nfrom torch.utils.data import DataLoader\nimport multiprocessing as mp\nfrom tqdm import tqdm\nimport glob\nfrom scipy.special import expit\n\nimport albumentations as A\nimport cv2\n\ncv2.setNumThreads(0)\n\nfrom os.path import join\n\nfrom torch.cuda.amp import GradScaler, autocast\n\n!mkdir tmp","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-11-07T12:44:27.714304Z","iopub.execute_input":"2022-11-07T12:44:27.715006Z","iopub.status.idle":"2022-11-07T12:44:29.979481Z","shell.execute_reply.started":"2022-11-07T12:44:27.714968Z","shell.execute_reply":"2022-11-07T12:44:29.978004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sys.path.append('../input/rsna2022-codebase/configs')\nsys.path.append('../input/rsna2022-codebase/data')\nsys.path.append('../input/rsna2022-codebase/models')\nsys.path.append('../input/rsna2022-codebase/postprocess')","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:29.981854Z","iopub.execute_input":"2022-11-07T12:44:29.98272Z","iopub.status.idle":"2022-11-07T12:44:29.989101Z","shell.execute_reply.started":"2022-11-07T12:44:29.982659Z","shell.execute_reply":"2022-11-07T12:44:29.987983Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"KAGGLE_DATA = r'../input/rsna-2022-cervical-spine-fracture-detection'\n\ntrain_df = pd.read_csv(join(KAGGLE_DATA, \"train.csv\"))\ntest_df = pd.read_csv(join(KAGGLE_DATA, \"test.csv\"))\n\nprint('train shape:', train_df.shape)\nprint('test shape:', test_df.shape)","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:29.990931Z","iopub.execute_input":"2022-11-07T12:44:29.992004Z","iopub.status.idle":"2022-11-07T12:44:30.026694Z","shell.execute_reply.started":"2022-11-07T12:44:29.991963Z","shell.execute_reply":"2022-11-07T12:44:30.025543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if len(test_df)==3:\n    # Fix mismatch with test_images folder\n    test_df = pd.DataFrame(columns = ['row_id','StudyInstanceUID','prediction_type'])\n    for i in ['1.2.826.0.1.3680043.22327','1.2.826.0.1.3680043.25399','1.2.826.0.1.3680043.5876']:\n        for j in ['C1','C2','C3','C4','C5','C6','C7','patient_overall']:\n            test_df = test_df.append({'row_id':i+'_'+j,'StudyInstanceUID':i,'prediction_type':j},ignore_index=True)\n\n    IS_PUBLIC = True\nelse:\n    IS_PUBLIC = False","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:30.028302Z","iopub.execute_input":"2022-11-07T12:44:30.02916Z","iopub.status.idle":"2022-11-07T12:44:30.092151Z","shell.execute_reply.started":"2022-11-07T12:44:30.029113Z","shell.execute_reply":"2022-11-07T12:44:30.090952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"means = train_df[[\n    \"C1\",\n    \"C2\",\n    \"C3\",\n    \"C4\",\n    \"C5\",\n    \"C6\",\n    \"C7\",\n    \"patient_overall\"\n]].mean(numeric_only=True)\nmeans","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:30.093483Z","iopub.execute_input":"2022-11-07T12:44:30.094202Z","iopub.status.idle":"2022-11-07T12:44:30.11369Z","shell.execute_reply.started":"2022-11-07T12:44:30.094162Z","shell.execute_reply":"2022-11-07T12:44:30.112288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.head(10)","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:30.115596Z","iopub.execute_input":"2022-11-07T12:44:30.117061Z","iopub.status.idle":"2022-11-07T12:44:30.137151Z","shell.execute_reply.started":"2022-11-07T12:44:30.117019Z","shell.execute_reply":"2022-11-07T12:44:30.136113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images = []\nstudy_ids = []\nframe_ids = []\nfor uid in test_df.StudyInstanceUID.unique():\n    \n    files = [x.split(\"/\")[-1] for x in glob.glob(f\"{KAGGLE_DATA}/test_images/{uid}/*\")]\n    images += [uid+\"/\"+x for x in files]\n    frame_ids += [int(x.split(\".\")[0]) for x in files]\n    study_ids += [uid] * len(files)\n\ndf = pd.DataFrame({\n    \"Image\": images,\n    \"StudyInstanceUID\": study_ids,\n    \"frame\": frame_ids\n}).sort_values([\"StudyInstanceUID\", \"frame\"]).reset_index(drop=True)\n\ndf[['label_frac_c1', 'label_frac_c2', 'label_frac_c3', 'label_frac_c4','label_frac_c5', 'label_frac_c6', 'label_frac_c7']] = 0\ndf[['label_vert_c1', 'label_vert_c2', 'label_vert_c3', 'label_vert_c4','label_vert_c5', 'label_vert_c6', 'label_vert_c7']] = 0","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:30.139911Z","iopub.execute_input":"2022-11-07T12:44:30.14113Z","iopub.status.idle":"2022-11-07T12:44:30.290909Z","shell.execute_reply.started":"2022-11-07T12:44:30.141087Z","shell.execute_reply":"2022-11-07T12:44:30.289927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:30.295053Z","iopub.execute_input":"2022-11-07T12:44:30.295349Z","iopub.status.idle":"2022-11-07T12:44:30.313722Z","shell.execute_reply.started":"2022-11-07T12:44:30.295321Z","shell.execute_reply":"2022-11-07T12:44:30.312636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(df)","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:30.321377Z","iopub.execute_input":"2022-11-07T12:44:30.321699Z","iopub.status.idle":"2022-11-07T12:44:30.332131Z","shell.execute_reply.started":"2022-11-07T12:44:30.32165Z","shell.execute_reply":"2022-11-07T12:44:30.33089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_seg_model(cfg_name, model_name):\n    cfg = importlib.import_module(cfg_name)\n    importlib.reload(cfg)\n    cfg = cfg.cfg\n    #print(cfg)\n    print(cfg.model, cfg.dataset, cfg.backbone, cfg.image_width, cfg.image_height)\n    \n    cfg.mixed_precision = False\n\n    ds = importlib.import_module(cfg.dataset)\n    importlib.reload(ds)\n    CustomDataset = ds.CustomDataset\n    # collate_fn = importlib.import_module(cfg.dataset).collate_fn\n    batch_to_device = ds.batch_to_device\n\n    cfg.post_process_pipeline = importlib.import_module(cfg.post_process_pipeline).post_process_pipeline\n\n    m = importlib.import_module(cfg.model)\n    importlib.reload(m)\n    Net = m.Net\n\n    # test settings\n    cfg.data_folder = f'{KAGGLE_DATA}/test_images/'\n    cfg.test_data_folder = f'{KAGGLE_DATA}/test_images/'\n    cfg.data_dir = KAGGLE_DATA\n    cfg.pretrained = False\n    cfg.device=\"cuda\"\n    cfg.return_logits = True\n\n    cfg.calc_loss = False\n\n    state_dicts = []\n    for filepath in glob.iglob(f'../input/{model_name}/*.pth'):\n\n        state_dicts.append(filepath)\n        break\n    print(state_dicts)\n\n    nets = []\n    for i in range(len(state_dicts)):\n        d = torch.load(state_dicts[i])['model']\n        new_d = {}\n        for k,v in d.items():\n            new_d[k.replace(\"module.\", \"\")] = v\n        sd = new_d\n\n        net = Net(cfg).eval().to(cfg.device)\n        net.load_state_dict(sd)\n\n        nets.append(net)\n    \n    print(\"-------------\")\n    return nets, cfg, CustomDataset, batch_to_device","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:30.33429Z","iopub.execute_input":"2022-11-07T12:44:30.334788Z","iopub.status.idle":"2022-11-07T12:44:30.347414Z","shell.execute_reply.started":"2022-11-07T12:44:30.334748Z","shell.execute_reply":"2022-11-07T12:44:30.346423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_model(cfg_name, model_name):\n    cfg = importlib.import_module(cfg_name)\n    importlib.reload(cfg)\n    cfg = cfg.cfg\n    print(cfg.model, cfg.dataset, cfg.backbone, cfg.image_width, cfg.image_height, cfg.frames_step_size)\n    \n    cfg.mixed_precision = False\n\n    ds = importlib.import_module(cfg.dataset)\n    importlib.reload(ds)\n    CustomDataset = ds.CustomDataset\n    batch_to_device = ds.batch_to_device\n\n    cfg.post_process_pipeline = importlib.import_module(cfg.post_process_pipeline).post_process_pipeline\n\n    m = importlib.import_module(cfg.model)\n    importlib.reload(m)\n    Net = m.Net\n\n    # test settings\n    cfg.data_folder = f'{KAGGLE_DATA}/test_images/'\n    cfg.test_data_folder = f'{KAGGLE_DATA}/test_images/'\n    cfg.data_dir = KAGGLE_DATA\n    cfg.pretrained = False\n    cfg.device=\"cuda\"\n    cfg.box_3d = 'crop_box_3d.csv'\n    cfg.return_logits = True\n    cfg.calc_loss = False\n\n    state_dicts = []\n    for filepath in glob.iglob(f'../input/{model_name}/*.pth'):\n\n        state_dicts.append(filepath)\n        break\n    print(state_dicts)\n\n    nets = []\n    for i in range(len(state_dicts)):\n        d = torch.load(state_dicts[i])['model']\n        new_d = {}\n        for k,v in d.items():\n            new_d[k.replace(\"module.\", \"\")] = v\n        sd = new_d\n\n        net = Net(cfg).eval().to(cfg.device)\n        net.load_state_dict(sd)\n\n        nets.append(net)\n    \n    print(\"-------------\")\n    return nets, cfg, CustomDataset, batch_to_device","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:30.349173Z","iopub.execute_input":"2022-11-07T12:44:30.34958Z","iopub.status.idle":"2022-11-07T12:44:30.363354Z","shell.execute_reply.started":"2022-11-07T12:44:30.349539Z","shell.execute_reply":"2022-11-07T12:44:30.362281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net, cfg, CustomDataset, batch_to_device = load_seg_model('stage1_S1B','rsna2022-stage1-s1b')","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:30.364993Z","iopub.execute_input":"2022-11-07T12:44:30.365383Z","iopub.status.idle":"2022-11-07T12:44:36.73494Z","shell.execute_reply.started":"2022-11-07T12:44:30.365341Z","shell.execute_reply":"2022-11-07T12:44:36.73382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7']] = 0 ","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:36.73659Z","iopub.execute_input":"2022-11-07T12:44:36.737243Z","iopub.status.idle":"2022-11-07T12:44:36.747079Z","shell.execute_reply.started":"2022-11-07T12:44:36.737202Z","shell.execute_reply":"2022-11-07T12:44:36.745947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg.batch_size = 64\ncfg.cache_size = 200\ncfg.cache_disk = \"\"","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:36.748726Z","iopub.execute_input":"2022-11-07T12:44:36.749254Z","iopub.status.idle":"2022-11-07T12:44:36.754869Z","shell.execute_reply.started":"2022-11-07T12:44:36.749218Z","shell.execute_reply":"2022-11-07T12:44:36.753701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchvision.ops import masks_to_boxes\nimport pydicom","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:36.756402Z","iopub.execute_input":"2022-11-07T12:44:36.757452Z","iopub.status.idle":"2022-11-07T12:44:36.764507Z","shell.execute_reply.started":"2022-11-07T12:44:36.757417Z","shell.execute_reply":"2022-11-07T12:44:36.763538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"boxes = []\nwith torch.inference_mode():\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, num_workers = 2)\n    \n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch, 'cuda')\n        out = net[0](batch)\n        pred = (out['logits'].sigmoid().max(1)[0] > 0.5).long()\n        box = torch.zeros((pred.shape[0],4))\n        \n        not_empty = pred.sum((1,2))>10\n        b = masks_to_boxes(pred[not_empty])\n        box[not_empty] = b.cpu()\n        boxes += [box]\nboxes = torch.cat(boxes)","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:36.766021Z","iopub.execute_input":"2022-11-07T12:44:36.767253Z","iopub.status.idle":"2022-11-07T12:44:57.741744Z","shell.execute_reply.started":"2022-11-07T12:44:36.767214Z","shell.execute_reply":"2022-11-07T12:44:57.740463Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"box_preds = df[['StudyInstanceUID']].copy()\nbox_preds[['x1','y1','x2','y2']] = boxes.numpy()","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:57.743655Z","iopub.execute_input":"2022-11-07T12:44:57.74472Z","iopub.status.idle":"2022-11-07T12:44:57.756043Z","shell.execute_reply.started":"2022-11-07T12:44:57.744676Z","shell.execute_reply":"2022-11-07T12:44:57.755071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#need original img shape to scale boxes to fit original image shape\n\ndef get_dicom_meta(path):\n    \"\"\"\n    This supports loading both regular and compressed JPEG images. \n    See the first sell with `pip install` commands for the necessary dependencies\n    \"\"\"\n    img=pydicom.dcmread(path)\n    img.PhotometricInterpretation = 'YBR_FULL'\n    shape = img.pixel_array.shape\n    \n    return shape\n\nmeta = df[['Image','StudyInstanceUID']].drop_duplicates('StudyInstanceUID')\nimg_fns = [f'{KAGGLE_DATA}/test_images/{fn}' for fn in meta['Image'].values]\nshapes = [get_dicom_meta(p) for p in img_fns]\nmeta[['ImageHeight','ImageWidth']] = shapes\n\nscales = meta[['StudyInstanceUID','ImageHeight','ImageWidth']].drop_duplicates().set_index('StudyInstanceUID').to_dict()","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:57.757862Z","iopub.execute_input":"2022-11-07T12:44:57.758288Z","iopub.status.idle":"2022-11-07T12:44:57.796669Z","shell.execute_reply.started":"2022-11-07T12:44:57.758251Z","shell.execute_reply":"2022-11-07T12:44:57.79575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_width = 320\nimage_height = 320\n\nimage_width_orig = 360\nimage_height_orig = 360\n\npad_ = (image_height_orig - image_height) // 2\n\ndef get_box(study_id):\n    df = box_preds[box_preds['StudyInstanceUID']==study_id].copy()\n    raw_boxes = df[['x1','y1','x2','y2']].values\n    df['area'] = (raw_boxes[:,2]-raw_boxes[:,0])*(raw_boxes[:,3]-raw_boxes[:,1])\n    raw_boxes2 = raw_boxes[((raw_boxes[:,2]-raw_boxes[:,0])*(raw_boxes[:,3]-raw_boxes[:,1]))>9]\n    raw_boxes2 = raw_boxes2 + pad_\n    \n    x_scale = scales['ImageWidth'][study_id] / image_width_orig\n    y_scale = scales['ImageHeight'][study_id] / image_height_orig\n    \n    try:\n        x1y1 = np.quantile(raw_boxes2[:,:2],0.05,axis=0)\n        x2y2 = np.quantile(raw_boxes2[:,2:],0.95,axis=0)\n        z1 = np.quantile(np.where(df['area'].values > 0)[0],0.05)\n        z2 = np.quantile(np.where(df['area'].values > 0)[0],0.95)\n\n        box = np.array([x_scale*x1y1[0],x_scale*x2y2[0],y_scale*x1y1[1],y_scale*x2y2[1],z1,z2])\n    except:\n        print(study_id)\n        box = np.array([0,0,0,0,0,0])\n    return box","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:57.798146Z","iopub.execute_input":"2022-11-07T12:44:57.798501Z","iopub.status.idle":"2022-11-07T12:44:57.809614Z","shell.execute_reply.started":"2022-11-07T12:44:57.798467Z","shell.execute_reply":"2022-11-07T12:44:57.80833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"boxes = [get_box(study_id) for study_id in tqdm(meta['StudyInstanceUID'].values)]\nmeta[['x1','x2','y1','y2','z1','z2']] = boxes\nmeta.to_csv('crop_box_3d.csv',index=False)","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:57.811137Z","iopub.execute_input":"2022-11-07T12:44:57.811841Z","iopub.status.idle":"2022-11-07T12:44:57.844088Z","shell.execute_reply.started":"2022-11-07T12:44:57.811807Z","shell.execute_reply":"2022-11-07T12:44:57.843152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"nets = []\nnet, cfg, CustomDataset, batch_to_device = load_model(\"stage2_cfg_ch_11_fix\", \"rsna2022-stage2-cfg-ch-11\")\nnets += net","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:57.845302Z","iopub.execute_input":"2022-11-07T12:44:57.846103Z","iopub.status.idle":"2022-11-07T12:44:58.982494Z","shell.execute_reply.started":"2022-11-07T12:44:57.846057Z","shell.execute_reply":"2022-11-07T12:44:58.981349Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg.batch_size = 64\ncfg.cache_size = 200\ncfg.cache_disk = \"\"\n\nwith torch.inference_mode():\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, num_workers = 2)\n\n    fold_preds0 = [[] for i in range(len(nets))]\n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch, cfg.device)\n        for i, net in enumerate(nets):\n            logits = net(batch)['logits'].float().detach().cpu().numpy()\n\n            fold_preds0[i] += [logits]","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:44:58.985017Z","iopub.execute_input":"2022-11-07T12:44:58.985503Z","iopub.status.idle":"2022-11-07T12:45:33.056297Z","shell.execute_reply.started":"2022-11-07T12:44:58.985473Z","shell.execute_reply":"2022-11-07T12:45:33.054302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fold_preds0 = [np.concatenate(p, axis=0) for p in fold_preds0]","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:45:33.058331Z","iopub.execute_input":"2022-11-07T12:45:33.058955Z","iopub.status.idle":"2022-11-07T12:45:33.06455Z","shell.execute_reply.started":"2022-11-07T12:45:33.058881Z","shell.execute_reply":"2022-11-07T12:45:33.063239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(fold_preds0[0])","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:45:33.066093Z","iopub.execute_input":"2022-11-07T12:45:33.066772Z","iopub.status.idle":"2022-11-07T12:45:33.081956Z","shell.execute_reply.started":"2022-11-07T12:45:33.066734Z","shell.execute_reply":"2022-11-07T12:45:33.08105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"nets = []\nnet, cfg, CustomDataset, batch_to_device = load_model(\"stage2_cfg_ps_wd_29_val\", \"stage2-cfg-ps-wd-29-ff\")\nnets += net\nnet, cfg, CustomDataset, batch_to_device = load_model(\"stage2_cfg_ps_wd_30_val\", \"stage2-cfg-ps-wd-30-ff\")\nnets += net\nnet, cfg, CustomDataset, batch_to_device = load_model(\"stage2_cfg_ps_wd_37_val\", \"stage2-cfg-ps-wd-37-ff\")\nnets += net\nnet, cfg, CustomDataset, batch_to_device = load_model(\"stage2_cfg_ps_wd_40_val\", \"stage2-cfg-ps-wd-40-ff\")\nnets += net","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:45:33.083786Z","iopub.execute_input":"2022-11-07T12:45:33.084804Z","iopub.status.idle":"2022-11-07T12:45:38.397247Z","shell.execute_reply.started":"2022-11-07T12:45:33.084767Z","shell.execute_reply":"2022-11-07T12:45:38.396155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(nets)","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:45:38.398851Z","iopub.execute_input":"2022-11-07T12:45:38.399256Z","iopub.status.idle":"2022-11-07T12:45:38.407953Z","shell.execute_reply.started":"2022-11-07T12:45:38.399218Z","shell.execute_reply":"2022-11-07T12:45:38.406852Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg.batch_size = 64\ncfg.cache_size = 200\ncfg.cache_disk = \"\"\n\nwith torch.inference_mode():\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, num_workers = 2)\n\n    fold_preds = [[] for i in range(len(nets))]\n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch, cfg.device)\n        for i, net in enumerate(nets):\n            logits = net(batch)['logits'].float().detach().cpu().numpy()\n\n            fold_preds[i] += [logits]","metadata":{"execution":{"iopub.status.busy":"2022-11-07T12:45:38.409583Z","iopub.execute_input":"2022-11-07T12:45:38.410571Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"assert (len(nets) == len(fold_preds))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fold_preds = [np.concatenate(p, axis=0) for p in fold_preds]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"assert (len(fold_preds[0]) == len(df))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fold_preds = fold_preds0 + fold_preds0 + fold_preds\nlen(fold_preds)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = expit(np.mean(fold_preds, axis=0))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def post_process_pipeline(cfg, val_data, val_df):\n\n    preds = val_data\n    \n    pred_cols = [\n        \"C1\",\n        \"C2\",\n        \"C3\",\n        \"C4\",\n        \"C5\",\n        \"C6\",\n        \"C7\",\n    ]\n\n    val_df[\n        pred_cols\n    ] = preds\n\n    window_size = 15\n\n    uids = val_df['StudyInstanceUID'].unique()\n\n    for c in  [\n        pred_cols\n    ]:\n        val_df[c] = val_df.groupby(\"StudyInstanceUID\")[c].rolling(window_size).mean().reset_index(0,drop=True)\n\n    \n        \n    preds = (\n        val_df.groupby(\"StudyInstanceUID\")[\n            pred_cols\n        ]\n        .max()\n        .reset_index()\n    )\n    preds[\"patient_overall\"] = 1 - (\n        (1 - preds[\"C1\"])\n        * (1 - preds[\"C2\"])\n        * (1 - preds[\"C3\"])\n        * (1 - preds[\"C4\"])\n        * (1 - preds[\"C5\"])\n        * (1 - preds[\"C6\"])\n        * (1 - preds[\"C7\"])\n    )\n    \n    pred_cols += [\"patient_overall\"]\n\n    for vert in range(8):\n        preds[pred_cols].values[:, vert] = np.clip((preds[pred_cols].values[:, vert] / preds[pred_cols].values[:, vert].mean())* 2* means[vert]/ (1 + means[vert]),\n            0.01,\n            0.99,\n        )\n\n    return preds","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds_pp = post_process_pipeline(cfg, preds, df)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds_pp","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn as nn\n\nfrom torch.utils.data import Dataset, DataLoader\nfrom sklearn.preprocessing import StandardScaler\nimport torch\nimport collections\n\npred_cols = [\n    \"pred_frac_c1\",\n    \"pred_frac_c2\",\n    \"pred_frac_c3\",\n    \"pred_frac_c4\",\n    \"pred_frac_c5\",\n    \"pred_frac_c6\",\n    \"pred_frac_c7\",\n]\nlabel_cols = [\n    \"label_frac_c1\",\n    \"label_frac_c2\",\n    \"label_frac_c3\",\n    \"label_frac_c4\",\n    \"label_frac_c5\",\n    \"label_frac_c6\",\n    \"label_frac_c7\",\n]\n\nclass RSNAStackerDataset(Dataset):\n\n    def __init__(self, df, mode):\n        self.df = df.copy().reset_index(drop=True)\n        self.mode = mode\n\n        self.feature_cols = []\n        self.label_cols = label_cols.copy()\n        \n        df = self.df\n        \n        features = []\n\n        for j, l in enumerate(pred_cols):\n            features.append(df.groupby(\"StudyInstanceUID\")[l].mean().values.reshape(-1,1))\n            features.append(df.groupby(\"StudyInstanceUID\")[l].min().values.reshape(-1,1))\n            features.append(df.groupby(\"StudyInstanceUID\")[l].max().values.reshape(-1,1))\n\n        features.append(df.groupby(\"StudyInstanceUID\").size().values.reshape(-1,1) / 1_000)\n\n        labels = (\n            df.groupby(\"StudyInstanceUID\")[\n                self.label_cols\n            ]\n            .max()\n            .reset_index(drop=True)\n        )\n        labels[\"label_overall\"] = labels[\n            self.label_cols\n        ].max(axis=1)\n        \n        self.X = np.concatenate(features, axis=1)\n        self.y = labels.values\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        \n        X = self.X[idx]\n        y = self.y[idx]\n        \n        return torch.FloatTensor(X), torch.FloatTensor(y)\n\n\n    def __len__(self):\n        return self.df.StudyInstanceUID.nunique()\n\nclass RSNAStackerModel(nn.Module):\n    def __init__(self, n_features):\n        super(RSNAStackerModel, self).__init__()\n        \n        self.sizes = [256, 128, 64]\n        \n        self.features = nn.Sequential(\n            nn.Linear(n_features, self.sizes[0]),\n            nn.PReLU(),\n            nn.Linear(self.sizes[0], self.sizes[1]),\n            nn.PReLU(),\n            nn.Linear(self.sizes[1], self.sizes[2]),\n            nn.PReLU(),\n            nn.BatchNorm1d(self.sizes[-1]),\n            nn.Dropout(0.2)\n        )\n        self.head = nn.Linear(self.sizes[-1], 8)\n\n    def forward(self, x, y):\n        \n        x = self.features(x)\n        x = self.head(x)\n        \n        \n        output = {}\n        \n        output[\"logits\"] = x\n\n        return output\n\ndef run_nn_stacker(exp_name, df, BS=64):\n\n\n    ds = RSNAStackerDataset(df.iloc[:].copy(), mode=\"test\")\n    \n    checkpoints = glob.glob(f\"../input/{exp_name}/*.pth\")\n    \n    preds_all = []\n    for checkpoint in checkpoints:\n        print(f\"running model {checkpoint}\")\n        \n        model = RSNAStackerModel(n_features=ds.X.shape[1]).to(\"cpu\").eval()\n    \n        model_weights = torch.load(checkpoint, map_location=\"cpu\")\n\n        model.load_state_dict(collections.OrderedDict(model_weights), strict=True)\n        \n        del model_weights\n    \n        batch_size = BS\n        dl = DataLoader(ds, shuffle=False, batch_size = batch_size, num_workers = 2)\n\n        with torch.no_grad():\n            preds = []\n            for batch in tqdm(dl):\n\n                data = [x.to(\"cpu\") for x in batch]\n                inputs, target = data\n                out = model(inputs, target)\n                preds.append(out[\"logits\"].float().sigmoid().detach().cpu().numpy())\n\n        preds_all.append(np.concatenate(preds, axis=0))\n        \n        del model\n        del dl\n        \n    del ds\n    \n    \n    preds = np.mean(preds_all, axis=0)\n    \n    return preds\n\ndf[pred_cols] = preds\n\ndf[label_cols] = 0\n\nnn_stacker_preds = run_nn_stacker(\"../input/final-nn-v0-ff\", df, BS=64)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"nn_stacker_preds.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = preds_pp.copy()\n\npred_cols = [\n    \"C1\",\n    \"C2\",\n    \"C3\",\n    \"C4\",\n    \"C5\",\n    \"C6\",\n    \"C7\",\n    \"patient_overall\"\n]\n\npreds[pred_cols] = 0.7*nn_stacker_preds + 0.3*preds[pred_cols]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"row_ids = []\nfractured = []\nfor idx,row in preds.iterrows():\n    for c in pred_cols:\n        row_ids.append(row.StudyInstanceUID+\"_\"+c)\n        fractured.append(row[c])\n        \nsub_df = pd.DataFrame({\n    \"row_id\": row_ids,\n    \"fractured\": fractured\n})","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df.to_csv('submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}