{"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":"## EDA","metadata":{}},{"cell_type":"code","source":"#load python lobraries\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport pydicom # handle dcm format\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nimport cv2\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport glob","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-05-30T07:27:28.419750Z","iopub.execute_input":"2022-05-30T07:27:28.420057Z","iopub.status.idle":"2022-05-30T07:27:28.428683Z","shell.execute_reply.started":"2022-05-30T07:27:28.420022Z","shell.execute_reply":"2022-05-30T07:27:28.427019Z"},"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)\nimport pydicom # handle dcm format\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nimport cv2\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport glob\nimport os","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:27:30.385150Z","iopub.execute_input":"2022-05-30T07:27:30.385415Z","iopub.status.idle":"2022-05-30T07:27:30.390247Z","shell.execute_reply.started":"2022-05-30T07:27:30.385386Z","shell.execute_reply":"2022-05-30T07:27:30.389256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model building\n","metadata":{}},{"cell_type":"code","source":"import torch\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport pydicom # handle dcm format\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nimport cv2\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport glob\nimport os","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:27:34.504571Z","iopub.execute_input":"2022-05-30T07:27:34.505016Z","iopub.status.idle":"2022-05-30T07:27:34.510133Z","shell.execute_reply.started":"2022-05-30T07:27:34.504979Z","shell.execute_reply":"2022-05-30T07:27:34.509399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install ../input/torchio-library/Deprecated-1.2.13-py2.py3-none-any.whl\n!pip install ../input/torchio-library/SimpleITK-2.1.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl\n!pip install ../input/torchio-library/torchio-0.18.56-py2.py3-none-any.whl","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:25:08.739990Z","iopub.execute_input":"2022-05-30T07:25:08.740241Z","iopub.status.idle":"2022-05-30T07:26:40.469574Z","shell.execute_reply.started":"2022-05-30T07:25:08.740212Z","shell.execute_reply":"2022-05-30T07:26:40.468736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom torch.utils.data import DataLoader, Dataset\n#from models import resnet\n\n## sklearn\nfrom sklearn import model_selection\nfrom sklearn.metrics import roc_auc_score","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:27:37.563790Z","iopub.execute_input":"2022-05-30T07:27:37.564314Z","iopub.status.idle":"2022-05-30T07:27:37.727703Z","shell.execute_reply.started":"2022-05-30T07:27:37.564275Z","shell.execute_reply":"2022-05-30T07:27:37.726974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class TrainDataset(Dataset):\n    def __init__(self, X_train_data , y_train_data , data_dir,  cohort='FLAIR'):\n        self.X_train_data = X_train_data\n        self.y_train_data = y_train_data\n        self.data_dir = data_dir\n        self.cohort = cohort\n    def __getitem__(self, idx):\n        # get sample info\n        #print(self.X_train_data[idx],'idx')\n        sample_id = self.X_train_data[idx] \n        target = self.y_train_data[idx]\n        # get sample path. combination of dir, padded id and cohort\n        sample_dir = os.path.join(self.data_dir, f'{sample_id:05d}', self.cohort)\n        sample_files = os.listdir(sample_dir)\n        #print(sample_dir,'sample_files')\n        # take subset of available images if n_images > 64\n        if len(sample_files) > 64:\n            sample_files = np.random.choice(sample_files, size=64, replace=False)\n            \n        # sort samples\n        sample_files = sorted(sample_files, key=lambda x: int(x[6:-4]))\n        \n        # load images\n        imgs = [self.read_img(os.path.join(sample_dir, path)) for path in sample_files]\n        imgs = np.stack(imgs)\n        \n        # resample images if not enough samples are available\n        if len(sample_files) < 64:\n            indices = sorted(np.random.choice(len(sample_files), size=64, replace=True))\n            imgs = np.stack(imgs[indices])\n        \n        imgs = np.stack(imgs)\n            \n        return torch.tensor(imgs, dtype=torch.float32).unsqueeze(0), torch.tensor(target, dtype=torch.float32)\n        \n    def __len__(self):\n        return len(self.X_train_data)\n    \n    def read_img(self, path):\n        img = self.read_dicom(path)\n        img = cv2.resize(img, (258, 258))\n        return img\n    \n    @staticmethod\n    def read_dicom(path):\n        dicom = pydicom.read_file(path)\n        data = apply_voi_lut(dicom.pixel_array, dicom)\n        if 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        return data","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:27:39.832465Z","iopub.execute_input":"2022-05-30T07:27:39.832989Z","iopub.status.idle":"2022-05-30T07:27:39.845943Z","shell.execute_reply.started":"2022-05-30T07:27:39.832951Z","shell.execute_reply":"2022-05-30T07:27:39.845271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#nifti dataloader\nimport numpy as np\nimport nibabel as nib\nclass NiftiDataset(Dataset):\n    def __init__(self, X_train_data , y_train_data, data_dir,  cohort='FLAIR'):\n        self.X_train_data = X_train_data\n        self.y_train_data = y_train_data\n        self.data_dir = data_dir\n        self.cohort = cohort\n    def __getitem__(self, idx):\n        # get sample info\n        sample_id = self.X_train_data[idx] \n        \n        if type(self.y_train_data) == type(None):\n            target = []\n        else:\n            target = self.y_train_data[idx]\n        # get sample path. combination of dir, padded id and cohort\n        sample_id = int(sample_id)\n        sample_dir = os.path.join(self.data_dir, f'{sample_id:05d}', self.cohort)\n        #final_tensor = get_padded_data(sample_dir , f'{sample_id:05d}')\n        \n        img = nib.load(f'{sample_dir}/{sample_id:05d}_FLAIR.nii.gz')\n        final_tensor = img.get_fdata()\n        final_tensor = final_tensor - np.min(final_tensor)\n        final_tensor = final_tensor / np.max(final_tensor)\n        return torch.tensor(final_tensor, dtype=torch.float32).unsqueeze(0), torch.tensor(target, dtype=torch.float32)\n        \n    def __len__(self):\n        return len(self.X_train_data)\n    ","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:27:43.409006Z","iopub.execute_input":"2022-05-30T07:27:43.409264Z","iopub.status.idle":"2022-05-30T07:27:43.417908Z","shell.execute_reply.started":"2022-05-30T07:27:43.409237Z","shell.execute_reply":"2022-05-30T07:27:43.417216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#load the training lables\nfrom sklearn.model_selection import train_test_split\ntrain_label_df = pd.read_csv('../input/rsna-miccai-brain-tumor-radiogenomic-classification/train_labels.csv')\ntrain_label_df = train_label_df[train_label_df.BraTS21ID.isin(list(map(int, os.listdir('../input/dicom-to-normalized-nifti-with-torchio/processed/train/') )))]\n\nX = train_label_df['BraTS21ID']\ny = train_label_df['MGMT_value']\nX_train, X_test, y_train, y_test = train_test_split(\n    X, y, test_size=0.33, random_state=42, stratify=y)\nX_test = X_test.reset_index(drop= True)\ny_test = y_test.reset_index(drop= True)\nX_train = X_train.reset_index(drop= True)\ny_train = y_train.reset_index(drop= True)","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:27:53.704736Z","iopub.execute_input":"2022-05-30T07:27:53.704998Z","iopub.status.idle":"2022-05-30T07:27:53.721202Z","shell.execute_reply.started":"2022-05-30T07:27:53.704970Z","shell.execute_reply":"2022-05-30T07:27:53.720528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"import sys\nimport os\nimport random\nimport time\n\n#run following steps\nos.system('mkdir MedicalNet')\n\nos.system('cp -r ../input/medical-net-files/data/ MedicalNet')\nos.system('cp -r ../input/medical-net-files/pretrain/ MedicalNet')\nos.system('cp -r ../input/medical-net-files/trails/ MedicalNet')\nos.system('cp -r ../input/medical-net/MedicalNet-master/* MedicalNet')\nos.system('touch MedicalNet__init__.py')\nsys.path.append('MedicalNet')\nimport MedicalNet.model","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:27:56.011469Z","iopub.execute_input":"2022-05-30T07:27:56.012090Z","iopub.status.idle":"2022-05-30T07:28:25.086041Z","shell.execute_reply.started":"2022-05-30T07:27:56.012054Z","shell.execute_reply":"2022-05-30T07:28:25.085210Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    # system\n    seed=42\n    no_cuda=False\n    \n    # model\n    model_name = 'resnet_34_23dataset'\n    use_pretrained = True\n    \nclass TrainerConfig:\n    num_epochs = 20\n    batch_size = 4\n    gradient_accumulation_steps = 1\n\n    # optimizer\n    lr = 3e-2\n    warm_up_ratio = 0.1\n    weight_decay = 0.0\n\n    # log every log_steps to wandb\n    log_steps = 20\n\n    # environment\n    device = 'cuda'\ndef seed_everything(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    \n# MedicalNet expect a class to hold hyperparameters\nclass Struct:\n    def __init__(self, entries):\n        self.__dict__.update(entries)","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:28:30.562269Z","iopub.execute_input":"2022-05-30T07:28:30.562770Z","iopub.status.idle":"2022-05-30T07:28:30.570905Z","shell.execute_reply.started":"2022-05-30T07:28:30.562728Z","shell.execute_reply":"2022-05-30T07:28:30.570251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# system setup\nseed_everything(CFG.seed)\nDEVICE = torch.device(\"cuda\") if torch.cuda.is_available() and not CFG.no_cuda else torch.device(\"cuda\")\nDEVICE = torch.device(\"cuda\")","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:28:33.191281Z","iopub.execute_input":"2022-05-30T07:28:33.191774Z","iopub.status.idle":"2022-05-30T07:28:33.282328Z","shell.execute_reply.started":"2022-05-30T07:28:33.191735Z","shell.execute_reply":"2022-05-30T07:28:33.281655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model specific args\nmodel_pretrained_params = {\n    'resnet_10': {'model_depth': 10, 'resnet_shortcut': 'B'},\n    'resnet_10_23dataset': {'model_depth': 10, 'resnet_shortcut': 'B'},\n    'resnet_18': {'model_depth': 18, 'resnet_shortcut': 'A'},\n    'resnet_18_23dataset': {'model_depth': 18, 'resnet_shortcut': 'A'},\n    'resnet_34': {'model_depth': 34, 'resnet_shortcut': 'A'},\n    'resnet_34_23dataset': {'model_depth': 34, 'resnet_shortcut': 'A'},\n    'resnet_50': {'model_depth': 50, 'resnet_shortcut': 'B'},\n    'resnet_50_23dataset': {'model_depth': 50, 'resnet_shortcut': 'B'},\n    'resnet_101': {'model_depth': 101, 'resnet_shortcut': 'B'},\n    'resnet_152': {'model_depth': 152, 'resnet_shortcut': 'B'},\n    'resnet_200': {'model_depth': 200, 'resnet_shortcut': 'B'},\n}\n# consistent args\nopts = {\n    'model': 'resnet',\n    'input_W': 256,\n    'input_H': 256,\n    'input_D': 64,\n    'no_cuda': CFG.no_cuda,\n    'n_seg_classes': 1,\n    'phase': 'train',\n    'pretrain_path': None,\n    'gpu_id': [1],\n}\n\n# merge modelspecific args and global args\nfor model_name, model_dict in model_pretrained_params.items():\n    model_pretrained_params[model_name] = Struct({**model_dict, **opts})\n    \n    \n# MedicalNet with a global pooling head\nclass MedicalNetWithHead(nn.Module):\n    def __init__(self, model_name, pretrain_path=None):\n        super().__init__()\n        self.model_name = model_name\n        \n        model, parameters = MedicalNet.model.generate_model(model_pretrained_params[model_name])\n        self.medical_net = model\n        self.drop_in = nn.Dropout(p=0.1)\n        \n        # init model with pretrained weights\n        if not pretrain_path and CFG.use_pretrained:\n            self.init_model()\n            \n        # use simple pooling for now\n        self.pool = nn.AdaptiveAvgPool3d(1)\n        \n    def forward(self, x):\n        x = self.medical_net(self.drop_in(x))\n        out = self.pool(x)\n        return out\n            \n    def init_model(self):\n        net_dict = self.medical_net.state_dict()\n        # load pretrain\n        pretrain = torch.load(f'./MedicalNet/pretrain/{self.model_name}.pth', map_location=DEVICE)\n        pretrain_dict = {k: v for k, v in pretrain['state_dict'].items() if k in net_dict.keys()}\n        net_dict.update(pretrain_dict)\n        self.medical_net.load_state_dict(net_dict)\n        print(\"loaded pretrained weights\")","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:28:35.142771Z","iopub.execute_input":"2022-05-30T07:28:35.143106Z","iopub.status.idle":"2022-05-30T07:28:35.162998Z","shell.execute_reply.started":"2022-05-30T07:28:35.143066Z","shell.execute_reply":"2022-05-30T07:28:35.162366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def collate_fn(data):\n    \"\"\"\n       data: is a list of tuples with (example, label, length)\n             where 'example' is a tensor of arbitrary shape\n             and label/length are scalars\n    \"\"\"\n    height_max , width_max , depth_max  = 0,0,0\n    data_return = []\n    lebels_return = []\n    for ind , data_point in enumerate(data):\n        ind , height , width , depth  = data[ind][0].shape\n        height_max = max(height_max ,height )\n        width_max = max(width_max ,width )\n        depth_max = max(depth_max ,depth )\n    for ind,data_tensor in enumerate(data):\n        padded_data = torch.zeros((1,height_max,width_max ,depth_max))\n        padded_data[0,:data[ind][0].shape[1],:data[ind][0].shape[2],:data[ind][0].shape[3]] = data_tensor[0][0]\n        \n        data_return.append(padded_data)\n        if data[ind][1].nelement():\n            lebels_return.append(data[ind][1])\n    return torch.cat(data_return ,0).unsqueeze(1), torch.tensor(lebels_return)","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:28:39.416757Z","iopub.execute_input":"2022-05-30T07:28:39.417009Z","iopub.status.idle":"2022-05-30T07:28:39.427922Z","shell.execute_reply.started":"2022-05-30T07:28:39.416981Z","shell.execute_reply":"2022-05-30T07:28:39.427222Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#!pip install tensorboard\n#!tensorboard --logdir=runs","metadata":{"execution":{"iopub.status.busy":"2022-05-30T06:43:30.931415Z","iopub.execute_input":"2022-05-30T06:43:30.931767Z","iopub.status.idle":"2022-05-30T06:43:31.019309Z","shell.execute_reply.started":"2022-05-30T06:43:30.931726Z","shell.execute_reply":"2022-05-30T06:43:31.018622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from torch.utils.tensorboard import SummaryWriter\n# writer = SummaryWriter()\nclass AverageMeter(object):\n    \"\"\"\n    Computes and stores the average and current value\n    Copied from: https://github.com/pytorch/examples/blob/master/imagenet/main.py\n    \"\"\"\n\n    def __init__(self):\n        self.reset()\n\n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n\n    def update(self, val, n=1):\n        self.val = val\n        self.sum += val * n\n        self.count += n\n        self.avg = self.sum / self.count\n\n\nclass Trainer:\n    def __init__(self, cfg: type(TrainerConfig),\n                 model: torch.nn.Module,\n                 model_path: str,\n                 dataset_train: Dataset = None,\n                 dataset_val: Dataset = None,\n                 #wandb_run: wandb.sdk.wandb_run.Run = None\n                 ):\n        self.cfg = cfg\n        self.model = model\n        self.best_model = None\n        self.model_path = model_path\n        #self.wandb_run = wandb_run\n\n        # datasets\n        self.dataset_train = dataset_train\n        self.dataset_eval = dataset_val\n\n        # dataloaders, train/eval is optional\n        kwargs_dataloader = {'batch_size': self.cfg.batch_size, 'num_workers': 2 , 'collate_fn' : collate_fn}\n        if self.dataset_eval is not None:\n            self.dataloader_train = DataLoader(self.dataset_train, shuffle=True, **kwargs_dataloader  )\n        if self.dataset_eval is not None:\n            self.dataloader_eval = DataLoader(self.dataset_eval, shuffle=False, **kwargs_dataloader)\n\n        # setup loss\n        self.loss_fnc = torch.nn.BCEWithLogitsLoss()\n\n        # if train set is provided, setup training\n        if dataset_train is not None:\n            self.optimizer = torch.optim.SGD(self.model.parameters(), self.cfg.lr, weight_decay=self.cfg.weight_decay, momentum=0.9)\n            #self.optimizer = torch.optim.Adam(self.model.parameters(), lr=0.0001)\n            self.scheduler = torch.optim.lr_scheduler.ExponentialLR(self.optimizer, gamma=0.9)\n            # call optimizer once so we can properly init the lr in step_train()\n            self.optimizer.zero_grad()\n            self.optimizer.step()\n            \n        else:\n            self.optimizer = None\n            self.scheduler = None\n            \n        self.epoch = 0\n\n    def train(self):\n        print(f'Training model for {self.cfg.num_epochs} epochs.')\n        print('Epoch | train_loss | eval_loss | train_auc | val_auc')\n        train_log = pd.DataFrame(columns=['epoch', 'train_loss', 'eval_loss', 'train_auc', 'eval_auc', 'lr'])\n        \n        best_loss = 1e3\n\n        for epoch in range(self.cfg.num_epochs):\n            train_loss, train_auc = self.step_train()\n            eval_loss, eval_auc = self.step_eval(return_predictions=False)\n#             writer.add_scalar('Loss_epoch/train', train_loss, self.epoch)\n#             writer.add_scalar('auc_epoch/train', train_auc,self.epoch)\n#             writer.add_scalar('Loss/test', eval_loss, self.epoch)\n#             writer.add_scalar('auc/test', eval_auc, self.epoch)\n            \n            log_item = {\n                'epoch': epoch,\n                'step': epoch*len(self.dataloader_train),\n                'train_loss': train_loss,\n                'eval_loss': eval_loss,\n                'train_auc': train_auc,\n                'eval_auc': eval_auc,\n                'lr': self.optimizer.param_groups[0]['lr']\n            }\n            #self.wandb_run.log(log_item)\n            train_log = train_log.append(log_item, ignore_index=True)\n            print(f\"{epoch: <6}|{train_loss: >12.3f}|{eval_loss: >11.3f}|{train_auc: >11.3f}|{eval_auc: >8.3f}\")\n      \n            # checkpointing\n            if eval_loss < best_loss:\n                torch.save(self.model, self.model_path)\n                best_loss = eval_loss\n            self.epoch += 1\n        best_epoch = train_log.eval_loss.idxmin()\n        print(\"Training done. Best model at epoch {} with eval_loss {:3.2f} and auc {:3.2f}\".format(\n            train_log.loc[best_epoch, 'epoch'],\n            train_log.loc[best_epoch, 'eval_loss'],\n            train_log.loc[best_epoch, 'eval_auc']\n        ))\n        return train_log\n\n    def step_train(self):\n        self.model.train()\n        \n        # setup logging\n        loss_agg = AverageMeter()\n        targets = []\n        predictions = []\n        steps_per_ep = len(self.dataset_train)//self.cfg.batch_size +1\n        # train one epoch\n        for batch_idx, (x, y) in enumerate(self.dataloader_train):\n            \n            x = x.to(self.cfg.device)\n            y = y.to(self.cfg.device)\n            \n            # forward pass  \n            logits = self.model(x)\n            loss = self.loss_fnc(logits.view(-1), y)\n            writer.add_scalar('Loss_step/train', loss, self.epoch*steps_per_ep + batch_idx)\n            batch_pred = torch.sigmoid(logits.view(-1)).detach().cpu().squeeze().numpy()\n            batch_tar  = y.detach().cpu().squeeze().numpy()\n            #batch_auc = roc_auc_score(batch_tar, batch_pred)\n            #writer.add_scalar('auc_step/train', batch_auc, self.epoch*steps_per_ep + batch_idx)\n            # backward pass\n            loss.backward()\n            if (batch_idx+1) % self.cfg.gradient_accumulation_steps == 0 or (batch_idx+1) == len(self.dataloader_train):\n                self.optimizer.step()\n                self.optimizer.zero_grad()\n                self.scheduler.step()\n\n            # update loss meter\n            loss_agg.update(loss.item(), self.cfg.batch_size)\n\n            # save preds/targets for roc computation\n            predictions.append(batch_pred)\n            targets.append(batch_tar)\n\n            # log every cfg.log_steps steps\n            if batch_idx > 0 and batch_idx % self.cfg.log_steps == 0:\n                log_item = {\n                    'step': self.epoch*len(self.dataloader_train) + batch_idx,\n                    'train_loss': loss_agg.avg,\n                    'train_auc': roc_auc_score(np.hstack(targets), np.hstack(predictions)),\n                    'lr': self.optimizer.param_groups[0]['lr']\n                }\n                #self.wandb_run.log(log_item)\n            \n        # compute auc for whole epoch\n        auc = roc_auc_score(np.hstack(targets), np.hstack(predictions))\n        \n        # tesorboard \n        \n        torch.cuda.empty_cache()\n        return loss_agg.avg, auc\n\n    @torch.no_grad()\n    def step_eval(self, return_predictions=False):\n        self.model.eval()\n        loss_agg = AverageMeter()\n        predictions = []\n        targets = []\n        for batch_idx, (x, y) in enumerate(self.dataloader_eval):\n            x = x.to(self.cfg.device)\n            y = y.to(self.cfg.device)\n            logits = self.model(x)\n            loss = self.loss_fnc(logits.view(-1), y)\n\n            # update loss meter\n            loss_agg.update(loss.item(), self.cfg.batch_size)\n\n            # optionally return predictions\n            # save preds/targets for roc computation\n            predictions.append(torch.sigmoid(logits.view(-1)).detach().cpu().squeeze().numpy())\n            targets.append(y.detach().cpu().squeeze().numpy())\n            \n        # compute auc\n        targets = np.hstack(targets)\n        predictions = np.hstack(predictions)\n        auc = roc_auc_score(targets, predictions)\n        # setup output\n        if return_predictions:\n            out = (loss_agg.avg, auc, predictions)\n        else:\n            out = (loss_agg.avg, auc)\n        return out\n    \n    def predict_results(self):\n        self.model.eval()\n        loss_agg = AverageMeter()\n        predictions = []\n        targets = []\n        for batch_idx, (x, y) in enumerate(self.dataloader_eval):\n            x = x.to(self.cfg.device)\n            logits = self.model(x)\n            # optionally return predictions\n            # save preds/targets for roc computation\n            predictions.append(torch.sigmoid(logits.view(-1)).detach().cpu().squeeze().numpy())\n\n        # get predictions\n        predictions = np.hstack(predictions)\n\n        return predictions\n    ","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:28:41.651217Z","iopub.execute_input":"2022-05-30T07:28:41.651484Z","iopub.status.idle":"2022-05-30T07:28:41.686684Z","shell.execute_reply.started":"2022-05-30T07:28:41.651454Z","shell.execute_reply":"2022-05-30T07:28:41.685815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## inference funtion","metadata":{}},{"cell_type":"code","source":"#!pip install --quiet torchio","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:22:18.704108Z","iopub.execute_input":"2022-05-30T07:22:18.704381Z","iopub.status.idle":"2022-05-30T07:22:29.251114Z","shell.execute_reply.started":"2022-05-30T07:22:18.704353Z","shell.execute_reply":"2022-05-30T07:22:29.250282Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#!pip install --quiet torchio\n\nimport os\nimport shutil\nfrom functools import partial\n# file_path = 'torchio'\n# if os.path.exists(file_path):\n#     shutil.rmtree(file_path)\n# os.makedirs(file_path)\n# os.system(f'cp -r ../input/torchio/torchio-main/* {file_path}')","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:28:47.428694Z","iopub.execute_input":"2022-05-30T07:28:47.429239Z","iopub.status.idle":"2022-05-30T07:28:47.434170Z","shell.execute_reply.started":"2022-05-30T07:28:47.429197Z","shell.execute_reply":"2022-05-30T07:28:47.433311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport torchio as tio\nfrom pathlib import Path\n\n# Parameters to limit the processing power needed.\ndemo  = False # if True limits to 10 patients\nscan_types    = ['FLAIR',\n                 #'T1w','T1wCE','T2w'\n                ] # uses all scan types\nfrom multiprocessing import Pool\n\ndef dicom2nifti(patient,dataset='test'):\n    for scan_type in scan_types:\n        scan_src  = f'{data_dir}/{patient}/{scan_type}/'\n        scan_dest = f'{out_dir}/{dataset}/{patient}/{scan_type}/'\n        Path(scan_dest).mkdir(parents=True, exist_ok=True)\n        image = tio.ScalarImage(scan_src)\n        transforms = [\n            tio.ToCanonical(),\n            tio.Resample((1, 1, 3 )),\n            #tio.ZNormalization(masking_method=tio.ZNormalization.mean),\n            #tio.CropOrPad((128,128,64)),\n            #tio.RescaleIntensity((-1, 1)),\n        ]\n        transform = tio.Compose(transforms)\n        preprocessed = transform(image)\n        preprocessed.save(f'{scan_dest}/{patient}_{scan_type}.nii.gz')","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:28:49.656540Z","iopub.execute_input":"2022-05-30T07:28:49.657355Z","iopub.status.idle":"2022-05-30T07:28:49.664908Z","shell.execute_reply.started":"2022-05-30T07:28:49.657303Z","shell.execute_reply":"2022-05-30T07:28:49.664043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndata_dir   = '/kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification/test'\nout_dir    = './output_files'\ndataset_dir =  '/kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification'\ndataset_to_predict = 'test'\n\ndef create_submission_csv(path_to_test_data,dataset , demo = False):\n    patients = os.listdir(data_dir)\n    if demo:\n        patients = patients[:10]\n    \n    # Remove cases the competion host said to exclude \n    # https://www.kaggle.com/c/rsna-miccai-brain-tumor-radiogenomic-classification/discussion/262046\n    if '00109' in patients: patients.remove('00109')\n    if '00123' in patients: patients.remove('00123')\n    if '00709' in patients: patients.remove('00709')\n\n    print(f'Total patients in test dataset: {len(patients)}')\n    \n#     with Pool() as mp:\n#         mp.map(dicom2nifti, patients)\n    chunk = 10\n    count = 0 \n    for patiant_count in range(0,len(patients), chunk):\n        patients_predict = patients[patiant_count:patiant_count + chunk]\n        #test_eval_data =  list(map(int,list(os.listdir(data_dir))))\n        if os.path.exists(out_dir):\n            shutil.rmtree(out_dir)\n        os.makedirs(out_dir)\n#         with Pool() as mp:\n#             mp.map(dicom2nifti, patients_predict)\n        for patiant in patients_predict:\n            dicom2nifti(patiant)\n        \n        training_data = NiftiDataset(X_train,y_train, data_dir='../input/dicom-to-normalized-nifti-with-torchio/processed/train', cohort='FLAIR')\n        test_eval_dataset = NiftiDataset(patients_predict, None, data_dir=out_dir+'/'+dataset, cohort='FLAIR')\n        model_test_pred= torch.load('../input/final-modal/model_submit.torch')\n        \n        trainer_pred = Trainer(cfg=TrainerConfig,\n                          model=model_test_pred,\n                          model_path=f'model_save.torch',\n                          dataset_train=training_data,\n                          dataset_val=test_eval_dataset,\n                          #wandb_run=wandb_run\n                         )\n        test_data_pred = trainer_pred.predict_results()\n        \n        df = pd.DataFrame({'BraTS21ID': list(map(lambda sample_id: (5 - len(str(sample_id))) * '0'+str(sample_id) ,patients_predict)),\n                           'MGMT_value': test_data_pred , \n                          })\n        #df=df.set_index('BraTS21ID')\n        set_header = True\n        if count != 0:\n            set_header = False\n        df.to_csv('submission.csv', mode='a', index=False, header=set_header)\n        count = count + 1\ncreate_submission_csv(data_dir,dataset_to_predict)","metadata":{"execution":{"iopub.status.busy":"2022-05-30T07:28:56.405647Z","iopub.execute_input":"2022-05-30T07:28:56.406541Z","iopub.status.idle":"2022-05-30T07:33:42.419848Z","shell.execute_reply.started":"2022-05-30T07:28:56.406477Z","shell.execute_reply":"2022-05-30T07:33:42.418858Z"},"trusted":true},"execution_count":null,"outputs":[]}]}