{"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":"# RSNA-MICCAI Brain Tumor Radiogenomic Classificationn - **An approach with PyTorch EfficientNet 3D**\n\n## **Problem Description**:\n\nThere are structural multi-parametric MRI (mpMRI) scans for different subjects, in DICOM format. The exact mpMRI scans included are:\n\n* Fluid Attenuated Inversion Recovery (FLAIR)\n* T1-weighted pre-contrast (T1w)\n* T1-weighted post-contrast (T1Gd)\n* T2-weighted (T2)\n\n`train_labels.csv` - file contains the target **MGMT_value** for each subject in the training data **(e.g. the presence of MGMT promoter methylation)**.\n\nSo, it's a binary classification problem.\n\n## **An EfficientNet3D solution**:\n\n* For each patient, we consider 4 sequences (FLAIR, T1w, T1Gd, T2), and for each of those sequences we take 64 slices from the middle. We resize the slices in shape (256, 256).\n\n* Construct an efficientnet-3d in pytorch with input shape (256, 256, 256) or (4, 256, 256, 64).\n\n* Perform binary classification.\n\n## **An EfficientNet2D solution**:\n\n* For each patient, we consider 4 sequences (FLAIR, T1w, T1Gd, T2), and for each of those sequences take a slice randomly. Idea from [https://github.com/zabir-nabil/Fibro-CoSANet](https://github.com/zabir-nabil/Fibro-CoSANet)\n\n* Construct a 4-channel image out of these 4 sequences.\n\n* Design a 4 channel pytorch model.\n\n* Add augmentation. Check out the augmentation notebook: https://www.kaggle.com/furcifer/mri-data-augmentation-pipeline\n\n* Add few heuristics to avoid black/empty scans.\n\n* Design modified efficient-net (4 channels) as model.\n\n* Perform binary classification.\n\n\n## **Check out my other kernels**\n\n### ⚡ **Training kernel:** https://www.kaggle.com/furcifer/torch-efficientnet3d-for-mri-no-train/\n\n### ⚡ **Inference kernel:** https://www.kaggle.com/furcifer/torch-effnet3d-for-mri-no-inference/\n\n### ⚡ **Training kernel (EfficientNet2D):** https://www.kaggle.com/furcifer/no-baseline-pytorch-cnn-for-mri/\n","metadata":{}},{"cell_type":"code","source":"from IPython.display import Image\nImage(\"../input/diagram/diagram.png\")","metadata":{"execution":{"iopub.status.busy":"2021-07-25T10:05:15.863213Z","iopub.execute_input":"2021-07-25T10:05:15.863567Z","iopub.status.idle":"2021-07-25T10:05:15.889481Z","shell.execute_reply.started":"2021-07-25T10:05:15.863536Z","shell.execute_reply":"2021-07-25T10:05:15.885477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Importing libraries**","metadata":{}},{"cell_type":"code","source":"import os\nimport glob\nfrom tqdm import tqdm_notebook as tqdm\nimport math\nimport random\nimport numpy as np\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nimport torch.nn.functional as F\nfrom torchvision import transforms, utils\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport matplotlib\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nimport cv2\nfrom sklearn.metrics import roc_auc_score\nimport imgaug as ia\nimport imgaug.augmenters as iaa\n\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"execution":{"iopub.status.busy":"2021-07-25T09:47:00.880019Z","iopub.execute_input":"2021-07-25T09:47:00.880389Z","iopub.status.idle":"2021-07-25T09:47:00.887526Z","shell.execute_reply.started":"2021-07-25T09:47:00.880351Z","shell.execute_reply":"2021-07-25T09:47:00.886482Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Importing EfficientNet-(2D + 3D)**","metadata":{}},{"cell_type":"code","source":"import sys\nsys.path.append('../input/efficientnetpyttorch3d/EfficientNet-PyTorch-3D')\nsys.path.append('../input/efficientnet-pytorch')\nsys.path.append('../input/efficientnet/EfficientNet-PyTorch-master/')","metadata":{"execution":{"iopub.status.busy":"2021-07-25T09:47:04.748798Z","iopub.execute_input":"2021-07-25T09:47:04.749165Z","iopub.status.idle":"2021-07-25T09:47:04.755984Z","shell.execute_reply.started":"2021-07-25T09:47:04.749134Z","shell.execute_reply":"2021-07-25T09:47:04.754954Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"MODEL = \"4C\" # [\"4C\", \"3D\", \"4C+3D\"]","metadata":{"execution":{"iopub.status.busy":"2021-07-25T09:47:06.757144Z","iopub.execute_input":"2021-07-25T09:47:06.757467Z","iopub.status.idle":"2021-07-25T09:47:06.761252Z","shell.execute_reply.started":"2021-07-25T09:47:06.757439Z","shell.execute_reply":"2021-07-25T09:47:06.760149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Inspecting Labels**","metadata":{}},{"cell_type":"code","source":"path = '/kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification'\ntrain_data = pd.read_csv(os.path.join(path, 'train_labels.csv'))\nprint('Num of train samples:', len(train_data))\ntrain_data.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-25T09:47:09.346071Z","iopub.execute_input":"2021-07-25T09:47:09.346415Z","iopub.status.idle":"2021-07-25T09:47:09.37606Z","shell.execute_reply.started":"2021-07-25T09:47:09.346386Z","shell.execute_reply":"2021-07-25T09:47:09.375142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Augmentation**","metadata":{}},{"cell_type":"code","source":"sometimes = lambda aug: iaa.Sometimes(0.1, aug)\n\nseq = iaa.Sequential(\n    [\n        # apply the following augmenters to most images\n        iaa.Fliplr(0.5), # horizontally flip 50% of all images\n        iaa.Flipud(0.5), # vertically flip 20% of all images\n        # crop images by -5% to 10% of their height/width\n        sometimes(iaa.CropAndPad(\n            percent=(-0.05, 0.05),\n            pad_mode=ia.ALL,\n            pad_cval=(0, 255)\n        )),\n        sometimes(iaa.Affine(\n            scale={\"x\": (0.8, 1.2), \"y\": (0.8, 1.2)}, # scale images to 80-120% of their size, individually per axis\n            translate_percent={\"x\": (-0.2, 0.2), \"y\": (-0.2, 0.2)}, # translate by -20 to +20 percent (per axis)\n            rotate=(-45, 45), # rotate by -45 to +45 degrees\n            shear=(-16, 16), # shear by -16 to +16 degrees\n            order=[0, 1], # use nearest neighbour or bilinear interpolation (fast)\n            cval=(0, 255), # if mode is constant, use a cval between 0 and 255\n            mode=ia.ALL # use any of scikit-image's warping modes (see 2nd image from the top for examples)\n        )),\n        # execute 0 to 5 of the following (less important) augmenters per image\n        # don't execute all of them, as that would often be way too strong\n        iaa.SomeOf((0, 5),\n            [\n                sometimes(iaa.Superpixels(p_replace=(0, 1.0), n_segments=(20, 200))), # convert images into their superpixel representation\n                iaa.OneOf([\n                    iaa.GaussianBlur((0, 3.0)), # blur images with a sigma between 0 and 3.0\n                    iaa.AverageBlur(k=(2, 7)), # blur image using local means with kernel sizes between 2 and 7\n                    iaa.MedianBlur(k=(3, 11)), # blur image using local medians with kernel sizes between 2 and 7\n                ]),\n                iaa.Sharpen(alpha=(0, 1.0), lightness=(0.75, 1.5)), # sharpen images\n                iaa.Emboss(alpha=(0, 1.0), strength=(0, 2.0)), # emboss images\n                # search either for all edges or for directed edges,\n                # blend the result with the original image using a blobby mask\n                iaa.SimplexNoiseAlpha(iaa.OneOf([\n                    iaa.EdgeDetect(alpha=(0.5, 1.0)),\n                    iaa.DirectedEdgeDetect(alpha=(0.5, 1.0), direction=(0.0, 1.0)),\n                ])),\n                iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.05*255), per_channel=0.5), # add gaussian noise to images\n                iaa.OneOf([\n                    iaa.Dropout((0.01, 0.1), per_channel=0.5), # randomly remove up to 10% of the pixels\n                    iaa.CoarseDropout((0.03, 0.15), size_percent=(0.02, 0.05), per_channel=0.2),\n                ]),\n                iaa.Invert(0.05, per_channel=True), # invert color channels\n                iaa.Add((-10, 10), per_channel=0.5), # change brightness of images (by -10 to 10 of original value)\n                \n                # either change the brightness of the whole image (sometimes\n                # per channel) or change the brightness of subareas\n                iaa.OneOf([\n                    iaa.Multiply((0.5, 1.5), per_channel=0.5),\n                    iaa.FrequencyNoiseAlpha(\n                        exponent=(-4, 0),\n                        first=iaa.Multiply((0.5, 1.5), per_channel=True),\n                        second=iaa.LinearContrast((0.5, 2.0))\n                    )\n                ]),\n                iaa.LinearContrast((0.5, 2.0), per_channel=0.5), # improve or worsen the contrast\n                sometimes(iaa.ElasticTransformation(alpha=(0.5, 3.5), sigma=0.25)), # move pixels locally around (with random strengths)\n                sometimes(iaa.PiecewiseAffine(scale=(0.01, 0.05))), # sometimes move parts of the image around\n                sometimes(iaa.PerspectiveTransform(scale=(0.01, 0.1)))\n            ],\n            random_order=True\n        )\n    ],\n    random_order=True\n)","metadata":{"execution":{"iopub.status.busy":"2021-07-25T09:47:13.444444Z","iopub.execute_input":"2021-07-25T09:47:13.444781Z","iopub.status.idle":"2021-07-25T09:47:13.466896Z","shell.execute_reply.started":"2021-07-25T09:47:13.444749Z","shell.execute_reply":"2021-07-25T09:47:13.465965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **MRI Slice Loading/Processing**","metadata":{}},{"cell_type":"code","source":"def dicom2array(paths, voi_lut=True, fix_monochrome=True, remove_black_boundary=True, aug = False):\n    \n    for path in paths:\n        dicom = pydicom.read_file(path)\n        # VOI LUT (if available by DICOM device) is used to\n        # transform raw DICOM data to \"human-friendly\" view\n        if voi_lut:\n            data = apply_voi_lut(dicom.pixel_array, dicom)\n        else:\n            data = dicom.pixel_array\n        if data.max() > 0.0: # avoiding black images (if possible)\n            break\n    # depending on this value, X-ray may look inverted - fix that:\n    if fix_monochrome and dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n    data = data - np.min(data)\n    data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    if remove_black_boundary: # we get slightly more details\n        (x, y) = np.where(data > 0)\n        if len(x) > 0 and len(y) > 0:\n            x_mn = np.min(x)\n            x_mx = np.max(x)\n            y_mn = np.min(y)\n            y_mx = np.max(y)\n            if (x_mx - x_mn) > 10 and (y_mx - y_mn) > 10:\n                data = data[:,np.min(y):np.max(y)]\n    data = cv2.resize(data, (512, 512))\n    if aug and random.randint(0,1) == 1: # augmenting only 50% of the time\n        data = seq(images=data)\n    return data\n\n\ndef load_3d_dicom_images(scan_id, split = \"train\", channel_expand = True):\n    \"\"\"\n    we will use some heuristics to choose the slices to avoid any numpy zero matrix (if possible)\n    \"\"\"\n    flair = sorted(glob.glob(f\"{path}/{split}/{scan_id}/FLAIR/*.dcm\"))\n    t1w = sorted(glob.glob(f\"{path}/{split}/{scan_id}/T1w/*.dcm\"))\n    t1wce = sorted(glob.glob(f\"{path}/{split}/{scan_id}/T1wCE/*.dcm\"))\n    t2w = sorted(glob.glob(f\"{path}/{split}/{scan_id}/T2w/*.dcm\"))\n    \n    \n    flair_img = np.array([dicom2array(a) for a in flair[len(flair)//2 - 32:len(flair)//2 + 32]]).T\n    \n    if len(flair_img) == 0:\n        flair_img = np.zeros((256, 256, 64))\n    elif flair_img.shape[-1] < 64:\n        n_zero = 64 - flair_img.shape[-1]\n        flair_img = np.concatenate((flair_img, np.zeros((256, 256, n_zero))), axis = -1)\n    #print(flair_img.shape)\n        \n    \n    \n    t1w_img = np.array([dicom2array(a) for a in t1w[len(t1w)//2 - 32:len(t1w)//2 + 32]]).T\n    \n    if len(t1w_img) == 0:\n        t1w_img = np.zeros((256, 256, 64))\n    elif t1w_img.shape[-1] < 64:\n        n_zero = 64 - t1w_img.shape[-1]\n        t1w_img = np.concatenate((t1w_img, np.zeros((256, 256, n_zero))), axis = -1)\n    #print(t1w_img.shape)\n    \n    \n    t1wce_img = np.array([dicom2array(a) for a in t1wce[len(t1wce)//2 - 32:len(t1wce)//2 + 32]]).T\n    \n    if len(t1wce_img) == 0:\n        t1wce_img = np.zeros((256, 256, 64))\n    elif t1wce_img.shape[-1] < 64:\n        n_zero = 64 - t1wce_img.shape[-1]\n        t1wce_img = np.concatenate((t1wce_img, np.zeros((256, 256, n_zero))), axis = -1)\n    #print(t1wce_img.shape)\n    \n    \n    t2w_img = np.array([dicom2array(a) for a in t2w[len(t2w)//2 - 32:len(t2w)//2 + 32]]).T\n    \n    if len(t2w_img) == 0:\n        t2w_img = np.zeros((256, 256, 64))\n    elif t2w_img.shape[-1] < 64:\n        n_zero = 64 - t2w_img.shape[-1]\n        t2w_img = np.concatenate((t2w_img, np.zeros((256, 256, n_zero))), axis = -1)\n    #print(t2w_img.shape)\n    \n    return np.concatenate((flair_img, t1w_img, t1wce_img, t2w_img), axis = -1) if not channel_expand else np.moveaxis(np.array((flair_img, t1w_img, t1wce_img, t2w_img)), 0, -1)\n\n\ndef load_rand_dicom_images(scan_id, split = \"train\", aug = False):\n    \"\"\"\n    send 4 random slices of each modality\n    \"\"\"\n    if split != \"train\" and split != \"test\":\n        split = \"train\"\n    flair = sorted(glob.glob(f\"{path}/{split}/{scan_id}/FLAIR/*.dcm\"))\n    flair_img = dicom2array(random.sample(flair, max(len(flair)//2, 1)), aug = aug)\n    t1w = sorted(glob.glob(f\"{path}/{split}/{scan_id}/T1w/*.dcm\"))\n    t1w_img = dicom2array(random.sample(t1w, max(len(t1w)//2, 1)), aug = aug)\n    t1wce = sorted(glob.glob(f\"{path}/{split}/{scan_id}/T1wCE/*.dcm\"))\n    t1wce_img = dicom2array(random.sample(t1wce, max(len(t1wce)//2, 1)), aug = aug)\n    t2w = sorted(glob.glob(f\"{path}/{split}/{scan_id}/T2w/*.dcm\"))\n    t2w_img = dicom2array(random.sample(t2w, max(len(t2w)//2, 1)), aug = aug)\n    \n    return np.array((flair_img, t1w_img, t1wce_img, t2w_img)).T","metadata":{"execution":{"iopub.status.busy":"2021-07-25T09:47:17.411462Z","iopub.execute_input":"2021-07-25T09:47:17.411798Z","iopub.status.idle":"2021-07-25T09:47:17.438144Z","shell.execute_reply.started":"2021-07-25T09:47:17.411768Z","shell.execute_reply":"2021-07-25T09:47:17.437155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Data Loader**","metadata":{}},{"cell_type":"code","source":"# let's write a simple pytorch dataloader\n\nclass BrainTumor4C(Dataset): # 4 channel data-loader\n    def __init__(self, path = '/kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification', split = \"train\", validation_split = 0.2):\n        # labels\n        train_data = pd.read_csv(os.path.join(path, 'train_labels.csv'))\n        self.labels = {}\n        brats = list(train_data[\"BraTS21ID\"])\n        mgmt = list(train_data[\"MGMT_value\"])\n        for b, m in zip(brats, mgmt):\n            self.labels[str(b).zfill(5)] = m\n            \n        if split == \"valid\":\n            self.split = split\n            self.ids = [a.split(\"/\")[-1] for a in sorted(glob.glob(path + f\"/train/\" + \"/*\"))]\n            self.ids = self.ids[:int(len(self.ids)* validation_split)] # first 20% as validation\n        elif split == \"train\":\n            self.split = split\n            self.ids = [a.split(\"/\")[-1] for a in sorted(glob.glob(path + f\"/{split}/\" + \"/*\"))]\n            self.ids = self.ids[int(len(self.ids)* validation_split):] # last 80% as train\n        else:\n            self.split = split\n            self.ids = [a.split(\"/\")[-1] for a in sorted(glob.glob(path + f\"/{split}/\" + \"/*\"))]\n            \n    \n    def __len__(self):\n        return len(self.ids)\n    \n    def __getitem__(self, idx):\n        imgs = load_rand_dicom_images(self.ids[idx], self.split, aug = False)\n        \n        transform = transforms.Compose([transforms.ToTensor()]) # transforms.Normalize((0.5, 0.5, 0.5, 0.5), (0.5, 0.5, 0.5, 0.5))\n        imgs = transform(imgs)\n        \n        imgs = imgs - imgs.min()\n        imgs = (imgs + 1e-5) / (imgs.max() - imgs.min() + 1e-5)\n        \n        if self.split != \"test\":\n            label = self.labels[self.ids[idx]]\n            return torch.tensor(imgs, dtype = torch.float32), torch.tensor(label, dtype = torch.long)\n        else:\n            return torch.tensor(imgs, dtype = torch.float32), self.ids[idx]","metadata":{"execution":{"iopub.status.busy":"2021-07-25T10:46:42.578404Z","iopub.execute_input":"2021-07-25T10:46:42.578732Z","iopub.status.idle":"2021-07-25T10:46:42.590662Z","shell.execute_reply.started":"2021-07-25T10:46:42.578703Z","shell.execute_reply":"2021-07-25T10:46:42.589901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# testing the dataloader\ntest_dataset = BrainTumor4C(split = \"test\")\ntest_bs = 8\ntest_loader = DataLoader(test_dataset, batch_size = test_bs, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2021-07-25T09:47:33.219686Z","iopub.execute_input":"2021-07-25T09:47:33.220035Z","iopub.status.idle":"2021-07-25T09:47:33.239353Z","shell.execute_reply.started":"2021-07-25T09:47:33.220004Z","shell.execute_reply":"2021-07-25T09:47:33.238572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for img, idx in test_loader:\n    print(img.shape)\n    print(img.max())\n    print(img.mean())\n    print(img.min())\n    print(idx)\n    break","metadata":{"execution":{"iopub.status.busy":"2021-07-25T09:47:33.815097Z","iopub.execute_input":"2021-07-25T09:47:33.815401Z","iopub.status.idle":"2021-07-25T09:47:36.380607Z","shell.execute_reply.started":"2021-07-25T09:47:33.815375Z","shell.execute_reply":"2021-07-25T09:47:36.379788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Model: EfficientNet-3D B0 / EfficientNet B1**","metadata":{}},{"cell_type":"code","source":"if MODEL == \"3D\":\n    PATH = \"../input/rsna-efficientnet3db0/best_roc_0.29_loss_1826.83.pt\"\n    model = EfficientNet3D.from_name(\"efficientnet-b0\", override_params={'num_classes': 2}, in_channels=4)\n    model.load_state_dict(torch.load(PATH))\n    model.eval()","metadata":{"execution":{"iopub.status.busy":"2021-07-25T09:47:40.859477Z","iopub.execute_input":"2021-07-25T09:47:40.859822Z","iopub.status.idle":"2021-07-25T09:47:40.865313Z","shell.execute_reply.started":"2021-07-25T09:47:40.859791Z","shell.execute_reply":"2021-07-25T09:47:40.864072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if MODEL == \"4C\":\n    from efficientnet_pytorch import EfficientNet\n    from efficientnet_pytorch.utils import Conv2dStaticSamePadding\n\n    PATH = \"../input/effb14c/best_roc_0.35_loss_39.45.pt\"\n    model = EfficientNet.from_name('efficientnet-b1')\n\n    # augment model with 4 channels\n\n    model._conv_stem = Conv2dStaticSamePadding(4, 32, kernel_size = (3,3), stride = (2,2), \n                                                                 bias = False, image_size = 512)\n    model._fc = torch.nn.Linear(in_features=1280, out_features=2, bias=True)\n    \n    model.load_state_dict(torch.load(PATH))\n    model.eval()","metadata":{"execution":{"iopub.status.busy":"2021-07-25T10:46:56.298402Z","iopub.execute_input":"2021-07-25T10:46:56.298759Z","iopub.status.idle":"2021-07-25T10:46:56.548098Z","shell.execute_reply.started":"2021-07-25T10:46:56.298725Z","shell.execute_reply":"2021-07-25T10:46:56.547238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# test\ngpu = torch.device(f\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nmodel.to(gpu)\nn_bootstrap = 9\n\nif MODEL == \"4C\":\n    labels = {}\n\n    model.eval()\n    for i_b in range(n_bootstrap):\n        for i, data in tqdm(enumerate(test_loader, 0)):\n\n            x, idx = data\n\n            x = x.to(gpu)\n\n            # forward\n            outputs = model(x)\n\n            label = torch.argmax(outputs, dim = -1)\n\n            # print(idx)\n            # print(label)\n\n            label = label.tolist()\n            for i_, idx_ in enumerate(list(idx)):\n                labels[idx_] = labels.get(idx_, []) + [label[i_]]\n                \n            # break","metadata":{"execution":{"iopub.status.busy":"2021-07-25T10:48:48.629415Z","iopub.execute_input":"2021-07-25T10:48:48.629820Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import collections\nlabels_od = collections.OrderedDict(sorted(labels.items()))\nprint(labels_od)","metadata":{"execution":{"iopub.status.busy":"2021-07-25T09:59:46.089506Z","iopub.execute_input":"2021-07-25T09:59:46.089848Z","iopub.status.idle":"2021-07-25T09:59:46.096794Z","shell.execute_reply.started":"2021-07-25T09:59:46.089816Z","shell.execute_reply":"2021-07-25T09:59:46.095801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f_idxs = []\nf_labels = []\nfor idx in labels_od.keys():\n    f_idxs.append(int(idx))\n    f_labels.append(np.array(labels_od[idx], dtype = np.float32).mean())    ","metadata":{"execution":{"iopub.status.busy":"2021-07-25T10:48:12.500714Z","iopub.execute_input":"2021-07-25T10:48:12.501080Z","iopub.status.idle":"2021-07-25T10:48:12.507945Z","shell.execute_reply.started":"2021-07-25T10:48:12.501048Z","shell.execute_reply":"2021-07-25T10:48:12.506843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f_idxs)\nprint(f_labels)","metadata":{"execution":{"iopub.status.busy":"2021-07-25T10:48:14.412447Z","iopub.execute_input":"2021-07-25T10:48:14.412771Z","iopub.status.idle":"2021-07-25T10:48:14.418041Z","shell.execute_reply.started":"2021-07-25T10:48:14.412739Z","shell.execute_reply":"2021-07-25T10:48:14.416730Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.read_csv(\"../input/rsna-miccai-brain-tumor-radiogenomic-classification/sample_submission.csv\")\n\nfor i, row in submission.iterrows():\n    idx = int(row['BraTS21ID'])\n    try:\n        new_label = f_labels[f_idxs.index(idx)]\n        submission.loc[i, 'MGMT_value'] = float(new_label)\n    except:\n        pass","metadata":{"execution":{"iopub.status.busy":"2021-07-25T10:02:42.885213Z","iopub.execute_input":"2021-07-25T10:02:42.885538Z","iopub.status.idle":"2021-07-25T10:02:42.926284Z","shell.execute_reply.started":"2021-07-25T10:02:42.885511Z","shell.execute_reply":"2021-07-25T10:02:42.925412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv(\"submission.csv\", index=False)\nsubmission","metadata":{"execution":{"iopub.status.busy":"2021-07-25T10:02:44.066602Z","iopub.execute_input":"2021-07-25T10:02:44.066943Z","iopub.status.idle":"2021-07-25T10:02:44.085296Z","shell.execute_reply.started":"2021-07-25T10:02:44.066909Z","shell.execute_reply":"2021-07-25T10:02:44.084372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}