{"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 pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport cv2\nimport torch\n\nimport os\nimport glob\nfrom tqdm.notebook import tqdm\nimport SimpleITK as sitk\nimport pydicom\n\nimport sys\nsys.path.append('../input/monai-v060-deep-learning-in-healthcare-imaging/')\nfrom monai.transforms import (\n    AddChannel,\n    Compose,\n    RandRotate90,\n    Resize,\n    ScaleIntensity,\n    EnsureType,\n    Randomizable,\n    LoadImaged,\n    EnsureTyped,\n    RandRotate,\n    RandZoom,\n    RandDeformGrid,\n    RandAffine,\n    Transform\n)\nfrom monai.data import CacheDataset, DataLoader, ImageDataset\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-09-06T09:27:23.536337Z","iopub.execute_input":"2021-09-06T09:27:23.536659Z","iopub.status.idle":"2021-09-06T09:27:29.443102Z","shell.execute_reply.started":"2021-09-06T09:27:23.536631Z","shell.execute_reply":"2021-09-06T09:27:29.442221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1. Config","metadata":{}},{"cell_type":"code","source":"DICOM_IM_FOLDER = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/test/'\nIM_FOLDER = 'BraTS2021_Testing_Data'\nMRI_TYPES = ['T1wCE', 'T1w', 'T2w', 'FLAIR']\nSHORT_MRI_TYPES = ['t1', 't1ce', 't2', 'flair']\n\nSEED = 67\nDIM = (128, 128, 128, 1)\nNUM_CLASSES = 1\nNUM_SEG_CLASSES = 0 # whether to use the segment head\nBATCH_SIZE = 6\nDEVICE = torch.device('cuda:0')\n\nFAST_COMMIT = True\n\nCANDIDATES = [\n    {\n        'backbone_name':'resnet50',\n        'model_path':'../input/brainbaselinemodels/v8/v8/t1_Fold0_resnet50_v8_data_task2_npy_norm_ValidLoss0.662_ValidAUC0.596_Ep19.pth',\n        'mri_type':'t1',\n    },\n    {\n        'backbone_name':'resnet50',\n        'model_path':'../input/brainbaselinemodels/v8/v8/t1ce_Fold0_resnet50_v8_data_task2_npy_norm_ValidLoss0.626_ValidAUC0.697_Ep13.pth',\n        'mri_type':'t1ce',\n    },\n    {\n        'backbone_name':'resnet50',\n        'model_path':'../input/brainbaselinemodels/v8/v8/t2_Fold0_resnet50_v8_data_task2_npy_norm_ValidLoss0.691_ValidAUC0.569_Ep02.pth',\n        'mri_type':'t2',\n    },\n    {\n        'backbone_name':'resnet50',\n        'model_path':'../input/brainbaselinemodels/v8/v8/flair_Fold0_resnet50_v8_data_task2_npy_norm_ValidLoss0.668_ValidAUC0.617_Ep06.pth',\n        'mri_type':'flair',\n    }\n]","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:29.444569Z","iopub.execute_input":"2021-09-06T09:27:29.444913Z","iopub.status.idle":"2021-09-06T09:27:29.451370Z","shell.execute_reply.started":"2021-09-06T09:27:29.444872Z","shell.execute_reply":"2021-09-06T09:27:29.450462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def visualize_3_planes_sitk(image):\n    voxels = sitk.GetArrayFromImage(image)\n    plt.figure(figsize=(9,3))\n    plt.subplot(1,3,1)\n    plt.imshow(voxels[voxels.shape[0]//2])\n    plt.subplot(1,3,2)\n    plt.imshow(voxels[:, voxels.shape[1]//2, :])\n    plt.subplot(1,3,3)\n    plt.imshow(voxels[:,:,voxels.shape[2]//2])\n    \ndef visualize_3_planes(voxels):\n    plt.figure(figsize=(9,3))\n    plt.subplot(1,3,1)\n    plt.imshow(voxels[voxels.shape[0]//2])\n    plt.subplot(1,3,2)\n    plt.imshow(voxels[:, voxels.shape[1]//2, :])\n    plt.subplot(1,3,3)\n    plt.imshow(voxels[:,:,voxels.shape[2]//2])","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:29.453593Z","iopub.execute_input":"2021-09-06T09:27:29.454339Z","iopub.status.idle":"2021-09-06T09:27:29.466936Z","shell.execute_reply.started":"2021-09-06T09:27:29.454301Z","shell.execute_reply":"2021-09-06T09:27:29.466017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. Read Voxels","metadata":{}},{"cell_type":"code","source":"def get_image_plane(data):\n    x1, y1, _, x2, y2, _ = [round(j) for j in data.ImageOrientationPatient]\n    cords = [x1, y1, x2, y2]\n\n    if cords == [1, 0, 0, 0]:\n        return 'Coronal'\n    elif cords == [1, 0, 0, 1]:\n        return 'Axial'\n    elif cords == [0, 1, 0, 0]:\n        return 'Sagittal'\n    else:\n        return 'Unknown'\n    \ndef get_voxel(study_id, scan_type):\n    imgs = []\n    dcm_dir = os.path.join(DICOM_IM_FOLDER, study_id, scan_type, '*.dcm')\n    dcm_paths = sorted(glob.glob(dcm_dir), key=lambda x: int(x.replace('.dcm','').split(\"-\")[-1]))\n    positions = []\n    \n    for dcm_path in dcm_paths:\n        img = pydicom.dcmread(str(dcm_path))\n        imgs.append(img.pixel_array)\n        positions.append(img.ImagePositionPatient)\n        \n    plane = get_image_plane(img)\n    voxel = np.stack(imgs)\n    \n    # reorder planes if needed and rotate voxel\n    if plane == \"Coronal\":\n        if positions[0][1] < positions[-1][1]:\n            voxel = voxel[::-1]\n            print(f\"{study_id} {scan_type} {plane} reordered\")\n        voxel = voxel.transpose((1, 0, 2))\n    elif plane == \"Sagittal\":\n        if positions[0][0] < positions[-1][0]:\n            voxel = voxel[::-1]\n            print(f\"{study_id} {scan_type} {plane} reordered\")\n        voxel = voxel.transpose((1, 2, 0))\n        voxel = np.rot90(voxel, 2, axes=(1, 2))\n    elif plane == \"Axial\":\n        if positions[0][2] > positions[-1][2]:\n            voxel = voxel[::-1]\n            print(f\"{study_id} {scan_type} {plane} reordered\")\n        voxel = np.rot90(voxel, 2)\n    else:\n        raise ValueError(f\"Unknown plane {plane}\")\n    return voxel, plane\n\ndef normalize_contrast(voxel):\n    if voxel.sum() == 0:\n        return voxel\n    voxel = voxel - np.min(voxel)\n    voxel = voxel / np.max(voxel)\n    voxel = (voxel * 255).astype(np.uint8)\n    return voxel\n\ndef crop_voxel(voxel):\n#     try:\n    if voxel.sum() == 0:\n        return voxel\n    keep = (voxel.mean(axis=(0, 1)) > 0)\n    voxel = voxel[:, :, keep]\n    keep = (voxel.mean(axis=(0, 2)) > 0)\n    voxel = voxel[:, keep]\n    keep = (voxel.mean(axis=(1, 2)) > 0)\n    voxel = voxel[keep]\n#     except Exception as ex:\n#         print(ex)\n    return voxel\n\ndef resize_voxel(voxel, sz=128):\n    output = np.zeros((sz, sz, sz), dtype=np.uint8)\n\n    if np.argmax(voxel.shape) == 0:\n        for i, s in enumerate(np.linspace(0, voxel.shape[0] - 1, sz)):\n            output[i] = cv2.resize(voxel[int(s)], (sz, sz))\n    elif np.argmax(voxel.shape) == 1:\n        for i, s in enumerate(np.linspace(0, voxel.shape[1] - 1, sz)):\n            output[:, i] = cv2.resize(voxel[:, int(s)], (sz, sz))\n    elif np.argmax(voxel.shape) == 2:\n        for i, s in enumerate(np.linspace(0, voxel.shape[2] - 1, sz)):\n            output[:, :, i] = cv2.resize(voxel[:, :, int(s)], (sz, sz))\n\n    return output","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:29.470314Z","iopub.execute_input":"2021-09-06T09:27:29.470594Z","iopub.status.idle":"2021-09-06T09:27:29.492208Z","shell.execute_reply.started":"2021-09-06T09:27:29.470561Z","shell.execute_reply":"2021-09-06T09:27:29.491254Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"voxel, plane = get_voxel('00001', 'T1w')\nvoxel = normalize_contrast(voxel)\nvoxel = crop_voxel(voxel)\nvoxel = resize_voxel(voxel)\n","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:29.493546Z","iopub.execute_input":"2021-09-06T09:27:29.494025Z","iopub.status.idle":"2021-09-06T09:27:29.935411Z","shell.execute_reply.started":"2021-09-06T09:27:29.493989Z","shell.execute_reply":"2021-09-06T09:27:29.934563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize_3_planes(voxel)","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:29.936713Z","iopub.execute_input":"2021-09-06T09:27:29.937037Z","iopub.status.idle":"2021-09-06T09:27:30.311125Z","shell.execute_reply.started":"2021-09-06T09:27:29.937003Z","shell.execute_reply":"2021-09-06T09:27:30.310142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"writer = sitk.ImageFileWriter()","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:30.312319Z","iopub.execute_input":"2021-09-06T09:27:30.312691Z","iopub.status.idle":"2021-09-06T09:27:30.320950Z","shell.execute_reply.started":"2021-09-06T09:27:30.312652Z","shell.execute_reply":"2021-09-06T09:27:30.320180Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"patient_ids = []\nimage_names = []\nmri_types = []\nmetas = []\n\nmri_type_mapping = {\n    'T1w':'t1',\n    'T1wCE':'t1ce',\n    'T2w':'t2',\n    'FLAIR':'flair'\n}\n\nif(FAST_COMMIT and len(os.listdir(DICOM_IM_FOLDER)) == 87):\n    iterations = tqdm(['00001','00013', '00015'])\nelse:\n    iterations = tqdm(os.listdir(DICOM_IM_FOLDER))\n\nfor patient_id in iterations:\n    patient_dir = os.path.join(DICOM_IM_FOLDER, patient_id) \n    saved_transform = None\n    for mri_type in MRI_TYPES:\n        type_dir = os.path.join(patient_dir, mri_type)\n\n        try: \n            voxel, plane = get_voxel(patient_id, mri_type)\n            voxel = normalize_contrast(voxel)\n            voxel = crop_voxel(voxel)\n            voxel = resize_voxel(voxel)\n\n            sitk_voxel = sitk.GetImageFromArray(voxel)\n            \n        except Exception as ex:\n            print(ex)\n            print('patient id:', patient_id)\n            voxel = np.zeros(shape=(128,128,128))\n            sitk_voxel = sitk.GetImageFromArray(voxel)\n        \n        outputImageFileName = os.path.join(IM_FOLDER, f'BraTS2021_{patient_id}', \n                                               f'BraTS2021_{patient_id}_{mri_type_mapping[mri_type]}.nii.gz')\n        \n        os.makedirs(os.path.dirname(outputImageFileName), exist_ok=True)\n        writer.SetFileName(outputImageFileName)\n        writer.Execute(sitk_voxel)","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:30.322669Z","iopub.execute_input":"2021-09-06T09:27:30.323037Z","iopub.status.idle":"2021-09-06T09:27:56.512362Z","shell.execute_reply.started":"2021-09-06T09:27:30.323001Z","shell.execute_reply":"2021-09-06T09:27:56.511510Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize_3_planes_sitk(sitk_voxel)","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:56.515199Z","iopub.execute_input":"2021-09-06T09:27:56.515686Z","iopub.status.idle":"2021-09-06T09:27:56.857561Z","shell.execute_reply.started":"2021-09-06T09:27:56.515649Z","shell.execute_reply":"2021-09-06T09:27:56.856599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3. Modeling","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.autograd import Variable\nimport math\nfrom functools import partial\n\n__all__ = [\n    'ResNet', 'resnet10', 'resnet18', 'resnet34', 'resnet50', 'resnet101',\n    'resnet152', 'resnet200'\n]\n\n\ndef conv3x3x3(in_planes, out_planes, stride=1, dilation=1):\n    # 3x3x3 convolution with padding\n    return nn.Conv3d(\n        in_planes,\n        out_planes,\n        kernel_size=3,\n        dilation=dilation,\n        stride=stride,\n        padding=dilation,\n        bias=False)\n\n\ndef downsample_basic_block(x, planes, stride, no_cuda=False):\n    out = F.avg_pool3d(x, kernel_size=1, stride=stride)\n    zero_pads = torch.Tensor(\n        out.size(0), planes - out.size(1), out.size(2), out.size(3),\n        out.size(4)).zero_()\n    if not no_cuda:\n        if isinstance(out.data, torch.cuda.FloatTensor):\n            zero_pads = zero_pads.cuda()\n\n    out = Variable(torch.cat([out.data, zero_pads], dim=1))\n\n    return out\n\n\nclass BasicBlock(nn.Module):\n    expansion = 1\n\n    def __init__(self, inplanes, planes, stride=1, dilation=1, downsample=None):\n        super(BasicBlock, self).__init__()\n        self.conv1 = conv3x3x3(inplanes, planes, stride=stride, dilation=dilation)\n        self.bn1 = nn.BatchNorm3d(planes)\n        self.relu = nn.ReLU(inplace=True)\n        self.conv2 = conv3x3x3(planes, planes, dilation=dilation)\n        self.bn2 = nn.BatchNorm3d(planes)\n        self.downsample = downsample\n        self.stride = stride\n        self.dilation = dilation\n\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n        out = self.conv2(out)\n        out = self.bn2(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass Bottleneck(nn.Module):\n    expansion = 4\n\n    def __init__(self, inplanes, planes, stride=1, dilation=1, downsample=None):\n        super(Bottleneck, self).__init__()\n        self.conv1 = nn.Conv3d(inplanes, planes, kernel_size=1, bias=False)\n        self.bn1 = nn.BatchNorm3d(planes)\n        self.conv2 = nn.Conv3d(\n            planes, planes, kernel_size=3, stride=stride, dilation=dilation, padding=dilation, bias=False)\n        self.bn2 = nn.BatchNorm3d(planes)\n        self.conv3 = nn.Conv3d(planes, planes * 4, kernel_size=1, bias=False)\n        self.bn3 = nn.BatchNorm3d(planes * 4)\n        self.relu = nn.ReLU(inplace=True)\n        self.downsample = downsample\n        self.stride = stride\n        self.dilation = dilation\n\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\nclass GAP3D(nn.Module):\n    def __init__(self, feat_dim):\n        super(GAP3D, self).__init__()\n        self.feat_dim = feat_dim\n\n    def forward(self, x):\n        x = F.adaptive_avg_pool3d(x, (1, 1, 1))\n        x = x.view((-1, self.feat_dim))\n        return x\n\nclass ResNet(nn.Module):\n\n    def __init__(self,\n                 block,\n                 layers,\n                 sample_input_D,\n                 sample_input_H,\n                 sample_input_W,\n                 num_classes,\n                 num_seg_classes,\n                 shortcut_type='B',\n                 no_cuda = False):\n        self.inplanes = 64\n        self.no_cuda = no_cuda\n        self.num_seg_classes = num_seg_classes\n        self.num_classes = num_classes\n\n        super(ResNet, self).__init__()\n        self.conv1 = nn.Conv3d(\n            1,\n            64,\n            kernel_size=7,\n            stride=(2, 2, 2),\n            padding=(3, 3, 3),\n            bias=False)\n            \n        self.bn1 = nn.BatchNorm3d(64)\n        self.relu = nn.ReLU(inplace=True)\n        self.maxpool = nn.MaxPool3d(kernel_size=(3, 3, 3), stride=2, padding=1)\n        self.layer1 = self._make_layer(block, 64, layers[0], shortcut_type)\n        self.layer2 = self._make_layer(\n            block, 128, layers[1], shortcut_type, stride=2)\n        self.layer3 = self._make_layer(\n            block, 256, layers[2], shortcut_type, stride=1, dilation=2)\n        self.layer4 = self._make_layer(\n            block, 512, layers[3], shortcut_type, stride=1, dilation=4)\n\n        # classification head\n        self.feat_dim = 512 * block.expansion\n        self.clf_head = nn.Sequential(\n            GAP3D(self.feat_dim),\n            nn.Linear(self.feat_dim, self.num_classes)\n        )\n\n        if(num_seg_classes > 0):\n            self.conv_seg = nn.Sequential(\n                                            nn.ConvTranspose3d(\n                                            512 * block.expansion,\n                                            32,\n                                            2,\n                                            stride=2\n                                            ),\n                                            nn.BatchNorm3d(32),\n                                            nn.ReLU(inplace=True),\n                                            nn.Conv3d(\n                                            32,\n                                            32,\n                                            kernel_size=3,\n                                            stride=(1, 1, 1),\n                                            padding=(1, 1, 1),\n                                            bias=False), \n                                            nn.BatchNorm3d(32),\n                                            nn.ReLU(inplace=True),\n                                            nn.Conv3d(\n                                            32,\n                                            num_seg_classes,\n                                            kernel_size=1,\n                                            stride=(1, 1, 1),\n                                            bias=False) \n                                            )\n\n            for m in self.modules():\n                if isinstance(m, nn.Conv3d):\n                    m.weight = nn.init.kaiming_normal(m.weight, mode='fan_out')\n                elif isinstance(m, nn.BatchNorm3d):\n                    m.weight.data.fill_(1)\n                    m.bias.data.zero_()\n\n    def _make_layer(self, block, planes, blocks, shortcut_type, stride=1, dilation=1):\n        downsample = None\n        # print(planes, stride, self.inplanes, block.expansion)\n        if stride != 1 or self.inplanes != planes * block.expansion:\n            if shortcut_type == 'A':\n                downsample = partial(\n                    downsample_basic_block,\n                    planes=planes * block.expansion,\n                    stride=stride,\n                    no_cuda=self.no_cuda)\n            else:\n                downsample = nn.Sequential(\n                    nn.Conv3d(\n                        self.inplanes,\n                        planes * block.expansion,\n                        kernel_size=1,\n                        stride=stride,\n                        bias=False), \n                    nn.BatchNorm3d(planes * block.expansion))\n\n        layers = []\n        layers.append(block(self.inplanes, planes, stride=stride, dilation=dilation, downsample=downsample))\n        # print(downsample)\n        self.inplanes = planes * block.expansion\n        for i in range(1, blocks):\n            layers.append(block(self.inplanes, planes, dilation=dilation))\n\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.bn1(x)\n        x = self.relu(x)\n        x = self.maxpool(x)\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n\n        logits = self.clf_head(x)\n\n#         if(self.num_seg_classes > 0):\n#             seg_mask = self.conv_seg(x)\n#             return logits, seg_mask\n        \n        return logits\n\ndef resnet10(**kwargs):\n    \"\"\"Constructs a ResNet-18 model.\n    \"\"\"\n    model = ResNet(BasicBlock, [1, 1, 1, 1], **kwargs)\n    return model\n\n\ndef resnet18(**kwargs):\n    \"\"\"Constructs a ResNet-18 model.\n    \"\"\"\n    model = ResNet(BasicBlock, [2, 2, 2, 2], **kwargs)\n    return model\n\n\ndef resnet34(**kwargs):\n    \"\"\"Constructs a ResNet-34 model.\n    \"\"\"\n    model = ResNet(BasicBlock, [3, 4, 6, 3], **kwargs)\n    return model\n\n\ndef resnet50(**kwargs):\n    \"\"\"Constructs a ResNet-50 model.\n    \"\"\"\n    model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs)\n    return model\n\n\ndef resnet101(**kwargs):\n    \"\"\"Constructs a ResNet-101 model.\n    \"\"\"\n    model = ResNet(Bottleneck, [3, 4, 23, 3], **kwargs)\n    return model\n\n\ndef resnet152(**kwargs):\n    \"\"\"Constructs a ResNet-101 model.\n    \"\"\"\n    model = ResNet(Bottleneck, [3, 8, 36, 3], **kwargs)\n    return model\n\n\ndef resnet200(**kwargs):\n    \"\"\"Constructs a ResNet-101 model.\n    \"\"\"\n    model = ResNet(Bottleneck, [3, 24, 36, 3], **kwargs)\n    return model\n\nimport torch\nfrom torch import nn\n\ndef get_medicalnet_resnet_model(model_name, inp_w, inp_h, inp_d, short_cut_type='B', num_classes=1, num_seg_classes=1, backbone_pretrained=None):\n    model_func = globals()[model_name]\n    model = model_func(\n                sample_input_W=inp_w,\n                sample_input_H=inp_h,\n                sample_input_D=inp_d,\n                shortcut_type=short_cut_type,\n                no_cuda=False,\n                num_classes = num_classes,\n                num_seg_classes=num_seg_classes)\n    \n    if(backbone_pretrained is not None):\n        print('Load pretrained:', backbone_pretrained)\n        net_dict = model.state_dict()\n        pretrain = torch.load(backbone_pretrained, map_location='cpu')\n        pretrain_dict = {k.replace('module.', ''): v for k, v in pretrain['state_dict'].items() if k.replace('module.', '') in net_dict.keys()}\n        net_dict.update(pretrain_dict)\n        model.load_state_dict(net_dict)\n\n    return model\n\ndef get_model(candidate):\n    dim = candidate.get('dim', DIM)\n    if('resnet' in candidate['backbone_name']):\n        model = get_medicalnet_resnet_model(candidate['backbone_name'], dim[1], dim[0], dim[2], num_classes=NUM_CLASSES,\n                                                num_seg_classes=NUM_SEG_CLASSES, backbone_pretrained=candidate.get('backbone_pretrained'))\n    elif('efficientnet' in candidate['backbone_name']):\n        model = monai.networks.nets.efficientnet.EfficientNetBN(model_name=candidate['backbone_name'],spatial_dims=3, in_channels=1,\n                                                pretrained=False, num_classes=NUM_CLASSES)\n    else:\n        raise ValueError('No such backbone name: '+ candidate['backbone_name'])\n    return model\n\ndef predict_fn(dataloader,model,scaler, device='cuda:0'):\n    model.eval()\n  \n    tk0 = tqdm(enumerate(dataloader), total=len(dataloader))\n    all_predictions = []\n    for i, batch in tk0:\n        # input, gt\n        voxels = batch\n        voxels = voxels.to(device)\n\n        # prediction\n        with torch.cuda.amp.autocast(), torch.no_grad():\n            logits = model(voxels)\n            logits = logits.view(-1)\n            \n            logits[torch.isnan(logits)] = 0\n            \n            probs = logits.sigmoid()\n     \n        # append for metric calculation\n        all_predictions.append(probs.detach().cpu().numpy())\n        \n        del batch, voxels, logits, probs\n        torch.cuda.empty_cache()\n\n    all_predictions = np.concatenate(all_predictions)\n    return all_predictions","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:56.859524Z","iopub.execute_input":"2021-09-06T09:27:56.859860Z","iopub.status.idle":"2021-09-06T09:27:56.913078Z","shell.execute_reply.started":"2021-09-06T09:27:56.859827Z","shell.execute_reply":"2021-09-06T09:27:56.912248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.DataFrame(os.listdir(IM_FOLDER), columns=['pfolder'])\ntest_df['BraTS21ID'] = test_df['pfolder'].map(lambda x: int(x.split('_')[-1]))\n\nfor t in SHORT_MRI_TYPES:\n    test_df[f'{t}_data_path'] = test_df.pfolder.map(lambda x: os.path.join(IM_FOLDER, x, x+f'_{t}.nii.gz'))","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:56.914384Z","iopub.execute_input":"2021-09-06T09:27:56.914776Z","iopub.status.idle":"2021-09-06T09:27:56.936073Z","shell.execute_reply.started":"2021-09-06T09:27:56.914741Z","shell.execute_reply":"2021-09-06T09:27:56.935245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:56.937366Z","iopub.execute_input":"2021-09-06T09:27:56.937737Z","iopub.status.idle":"2021-09-06T09:27:56.958520Z","shell.execute_reply.started":"2021-09-06T09:27:56.937701Z","shell.execute_reply":"2021-09-06T09:27:56.957796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_transforms = Compose([AddChannel(), ScaleIntensity()])\nmri_type = SHORT_MRI_TYPES[0]\n\ntest_dataset = ImageDataset(image_files=test_df[f'{mri_type}_data_path'].tolist(),\n                            transform=test_transforms)","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:56.959662Z","iopub.execute_input":"2021-09-06T09:27:56.959983Z","iopub.status.idle":"2021-09-06T09:27:56.965933Z","shell.execute_reply.started":"2021-09-06T09:27:56.959949Z","shell.execute_reply":"2021-09-06T09:27:56.965065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# voxels, labels = next(iter(train_loader))\nvoxels  = test_dataset[0]\nvisualize_3_planes(voxels[0])","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:56.967528Z","iopub.execute_input":"2021-09-06T09:27:56.968147Z","iopub.status.idle":"2021-09-06T09:27:57.338417Z","shell.execute_reply.started":"2021-09-06T09:27:56.968094Z","shell.execute_reply":"2021-09-06T09:27:57.337439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ensembled_prediction = 0\n    \nfor candidate in CANDIDATES:\n    \n    # create data loader\n    mri_type = candidate.get('mri_type')\n    test_dataset = ImageDataset(image_files=test_df[f'{mri_type}_data_path'].tolist(),\n                            transform=test_transforms)\n\n    batch_size = candidate.get('batch_size', BATCH_SIZE)\n    test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False,\n                    num_workers=4, pin_memory=torch.cuda.is_available())\n\n    # Model\n    model = get_model(candidate)\n    print('Load trained model:', candidate['model_path'] )\n    model.load_state_dict(torch.load(candidate['model_path'], map_location='cpu'))\n    model = model.to(DEVICE)\n    print()\n\n    scaler = torch.cuda.amp.GradScaler()\n\n    test_ensembled_prediction += predict_fn(test_loader, model, scaler, device=DEVICE)\n\ntest_ensembled_prediction /= len(CANDIDATES)","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:27:57.339854Z","iopub.execute_input":"2021-09-06T09:27:57.340209Z","iopub.status.idle":"2021-09-06T09:28:18.116139Z","shell.execute_reply.started":"2021-09-06T09:27:57.340174Z","shell.execute_reply":"2021-09-06T09:28:18.115220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df['MGMT_value'] = test_ensembled_prediction","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:28:18.117603Z","iopub.execute_input":"2021-09-06T09:28:18.117948Z","iopub.status.idle":"2021-09-06T09:28:18.125882Z","shell.execute_reply.started":"2021-09-06T09:28:18.117916Z","shell.execute_reply":"2021-09-06T09:28:18.122599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.read_csv('../input/rsna-miccai-brain-tumor-radiogenomic-classification/sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:28:18.127451Z","iopub.execute_input":"2021-09-06T09:28:18.127952Z","iopub.status.idle":"2021-09-06T09:28:18.139479Z","shell.execute_reply.started":"2021-09-06T09:28:18.127916Z","shell.execute_reply":"2021-09-06T09:28:18.138537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = test_df.merge(sub[['BraTS21ID']], on='BraTS21ID', how='right')","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:28:18.140617Z","iopub.execute_input":"2021-09-06T09:28:18.140951Z","iopub.status.idle":"2021-09-06T09:28:18.157813Z","shell.execute_reply.started":"2021-09-06T09:28:18.140918Z","shell.execute_reply":"2021-09-06T09:28:18.156966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:28:18.159271Z","iopub.execute_input":"2021-09-06T09:28:18.159948Z","iopub.status.idle":"2021-09-06T09:28:18.182703Z","shell.execute_reply.started":"2021-09-06T09:28:18.159911Z","shell.execute_reply":"2021-09-06T09:28:18.181613Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df[['BraTS21ID', 'MGMT_value']].head()","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:28:18.184259Z","iopub.execute_input":"2021-09-06T09:28:18.184669Z","iopub.status.idle":"2021-09-06T09:28:18.200506Z","shell.execute_reply.started":"2021-09-06T09:28:18.184618Z","shell.execute_reply":"2021-09-06T09:28:18.199660Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df[['BraTS21ID', 'MGMT_value']].to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:28:18.201776Z","iopub.execute_input":"2021-09-06T09:28:18.202174Z","iopub.status.idle":"2021-09-06T09:28:18.212093Z","shell.execute_reply.started":"2021-09-06T09:28:18.202135Z","shell.execute_reply":"2021-09-06T09:28:18.211097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ls","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:28:18.213702Z","iopub.execute_input":"2021-09-06T09:28:18.214190Z","iopub.status.idle":"2021-09-06T09:28:18.895371Z","shell.execute_reply.started":"2021-09-06T09:28:18.214116Z","shell.execute_reply":"2021-09-06T09:28:18.894464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# clear working dir\n!rm -rf BraTS2021_Testing_Data","metadata":{"execution":{"iopub.status.busy":"2021-09-06T09:28:18.898572Z","iopub.execute_input":"2021-09-06T09:28:18.898847Z","iopub.status.idle":"2021-09-06T09:28:19.599845Z","shell.execute_reply.started":"2021-09-06T09:28:18.898817Z","shell.execute_reply":"2021-09-06T09:28:19.598707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}