{"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 os\nimport sys \nimport json\nimport glob\nimport random\nimport collections\nimport time\nimport re\n\nimport numpy as np\nimport pandas as pd\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nimport cv2\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nimport torch\nfrom torch import nn\nfrom torch.utils import data as torch_data\nfrom sklearn import model_selection as sk_model_selection\nfrom torch.nn import functional as torch_functional\nimport torch.nn.functional as F\n\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.metrics import roc_auc_score","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-09-01T07:14:28.735421Z","iopub.execute_input":"2021-09-01T07:14:28.735757Z","iopub.status.idle":"2021-09-01T07:14:28.742169Z","shell.execute_reply.started":"2021-09-01T07:14:28.735727Z","shell.execute_reply":"2021-09-01T07:14:28.741230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if os.path.exists(\"../input/rsna-miccai-brain-tumor-radiogenomic-classification\"):\n    data_directory = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n    pytorch3dpath = \"../input/efficientnetpyttorch3d/EfficientNet-PyTorch-3D\"\nelse:\n    data_directory = '/media/roland/data/kaggle/rsna-miccai-brain-tumor-radiogenomic-classification'\n    pytorch3dpath = \"EfficientNet-PyTorch-3D\"\n    \nmri_types = ['FLAIR','T1w','T1wCE','T2w']\nSIZE = 256\nNUM_IMAGES = 64\n\n# model_path_1 = '../input/nara-testbench-models/'\n# model_path_2 = '../input/nara-only-output/'\n# model_path_list = [model_path_1, model_path_2]\nsys.path.append(pytorch3dpath)\nfrom efficientnet_pytorch_3d import EfficientNet3D","metadata":{"execution":{"iopub.status.busy":"2021-09-01T07:14:31.564596Z","iopub.execute_input":"2021-09-01T07:14:31.564949Z","iopub.status.idle":"2021-09-01T07:14:31.572546Z","shell.execute_reply.started":"2021-09-01T07:14:31.564917Z","shell.execute_reply":"2021-09-01T07:14:31.571718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_dicom_image(path, img_size=SIZE, voi_lut=True, rotate=0):\n    dicom = pydicom.read_file(path)\n    data = dicom.pixel_array\n    if voi_lut:\n        data = apply_voi_lut(dicom.pixel_array, dicom)\n    else:\n        data = dicom.pixel_array\n        \n    if rotate > 0:\n        rot_choices = [0, cv2.ROTATE_90_CLOCKWISE, cv2.ROTATE_90_COUNTERCLOCKWISE, cv2.ROTATE_180]\n        data = cv2.rotate(data, rot_choices[rotate])\n        \n    data = cv2.resize(data, (img_size, img_size))\n    return data\n\n\ndef load_dicom_images_3d(scan_id, num_imgs=NUM_IMAGES, img_size=SIZE, mri_type=\"FLAIR\", split=\"train\", rotate=0):\n\n    files = sorted(glob.glob(f\"{data_directory}/{split}/{scan_id}/{mri_type}/*.dcm\"), \n               key=lambda var:[int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var)])\n\n    middle = len(files)//2\n    num_imgs2 = num_imgs//2\n    p1 = max(0, middle - num_imgs2)\n    p2 = min(len(files), middle + num_imgs2)\n    img3d = np.stack([load_dicom_image(f, rotate=rotate) for f in files[p1:p2]]).T \n    if img3d.shape[-1] < num_imgs:\n        n_zero = np.zeros((img_size, img_size, num_imgs - img3d.shape[-1]))\n        img3d = np.concatenate((img3d,  n_zero), axis = -1)\n        \n    if np.min(img3d) < np.max(img3d):\n        img3d = img3d - np.min(img3d)\n        img3d = img3d / np.max(img3d)\n            \n    return np.expand_dims(img3d,0)\n\ndef set_seed(seed):\n    random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    if torch.cuda.is_available():\n        torch.cuda.manual_seed_all(seed)\n        torch.backends.cudnn.deterministic = True\n\nset_seed(12)","metadata":{"execution":{"iopub.status.busy":"2021-09-01T07:14:53.344348Z","iopub.execute_input":"2021-09-01T07:14:53.344822Z","iopub.status.idle":"2021-09-01T07:14:53.358451Z","shell.execute_reply.started":"2021-09-01T07:14:53.344787Z","shell.execute_reply":"2021-09-01T07:14:53.357594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# modelfiles_1 = [\n#     'FLAIR-e10-loss0.680-auc0.624.pth', \n#     'T1w-e6-loss0.691-auc0.581.pth',\n#     'T1wCE-e1-loss0.693-auc0.500.pth', \n#     'T2w-e5-loss0.694-auc0.417.pth'\n# ]\n\n# modelfiles_2 = [\n#     'FLAIR-e4-loss0.689-auc0.474.pth',\n#     'T1w-e4-loss0.691-auc0.470.pth',\n#     'T1wCE-e3-loss0.690-auc0.500.pth',\n#     'T2w-e6-loss0.686-auc0.611.pth'\n# ]\n\n# modelfiles_list = [modelfiles_1, modelfiles_2]\n\nmodelfiles = [\n    '../input/eeic2021-noaugment/FLAIR-e2-loss0.696-auc0.605.pth',\n    '../input/eeic2021-noaugment/T1w-e7-loss0.685-auc0.555.pth',\n    '../input/eeic2021-noaugment/T1wCE-e6-loss0.683-auc0.633.pth',\n    '../input/eeic2021-noaugment/T2w-e8-loss0.658-auc0.677.pth',\n    '../input/noaugment-only-output/FLAIR-e9-loss0.672-auc0.616.pth',\n    '../input/noaugment-only-output/T1w-e5-loss0.685-auc0.556.pth',\n    '../input/noaugment-only-output/T1wCE-e9-loss0.686-auc0.503.pth',\n    '../input/eeic2021-noaugment/T2w-e8-loss0.658-auc0.677.pth'\n]\n\n\nclass Model_1(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.net = EfficientNet3D.from_name(\"efficientnet-b0\", override_params={'num_classes': 2}, in_channels=1)\n        n_features = self.net._fc.in_features\n        self.net._fc = nn.Linear(in_features=n_features, out_features=1, bias=True)\n    \n    def forward(self, x):\n        out = self.net(x)\n        return out\n\nclass Model_2(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.net = EfficientNet3D.from_name(\"efficientnet-b2\", override_params={'num_classes': 2}, in_channels=1)\n        n_features = self.net._fc.in_features\n        self.net._fc = nn.Linear(in_features=n_features, out_features=1, bias=True)\n    \n    def forward(self, x):\n        out = self.net(x)\n        return out\n\nmodel_list = [Model_1(), Model_2()]\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\nclass Dataset(torch_data.Dataset):\n    def __init__(self, paths, targets=None, mri_type=None, label_smoothing=0.01, split=\"train\", augment=False):\n        self.paths = paths\n        self.targets = targets\n        self.mri_type = mri_type\n        self.label_smoothing = label_smoothing\n        self.split = split\n        self.augment = augment\n          \n    def __len__(self):\n        return len(self.paths)\n    \n    def __getitem__(self, index):\n        scan_id = self.paths[index]\n        if self.targets is None:\n            data = load_dicom_images_3d(str(scan_id).zfill(5), mri_type=self.mri_type[index], split=self.split)\n        else:\n            if self.augment:\n                rotation = np.random.randint(0,4)\n            else:\n                rotation = 0\n\n            data = load_dicom_images_3d(str(scan_id).zfill(5), mri_type=self.mri_type[index], split=\"train\", rotate=rotation)\n\n        if self.targets is None:\n            return {\"X\": torch.tensor(data).float(), \"id\": scan_id}\n        else:\n            y = torch.tensor(abs(self.targets[index]-self.label_smoothing), dtype=torch.float)\n            return {\"X\": torch.tensor(data).float(), \"y\": y}\n\n\ndef predict(modelfile, df, mri_type, split, mst):#mst: ベースラインかonly_outputか\n    print(\"Predict:\", modelfile, mri_type, df.shape)\n    df.loc[:,\"MRI_Type\"] = mri_type\n    data_retriever = Dataset(\n        df.index.values, \n        mri_type=df[\"MRI_Type\"].values,\n        split=split\n    )\n\n    data_loader = torch_data.DataLoader(\n        data_retriever,\n        batch_size=4,\n        shuffle=False,\n        num_workers=8,\n    )\n   \n    model = model_list[mst]\n#     model = model_list[0]\n    model.to(device)\n    \n    checkpoint = torch.load(modelfile)\n    model.load_state_dict(checkpoint[\"model_state_dict\"])\n    model.eval()\n    \n    y_pred = []\n    ids = []\n\n    for e, batch in enumerate(data_loader,1):\n        print(f\"{e}/{len(data_loader)}\", end=\"\\r\")\n        with torch.no_grad():\n            tmp_pred = torch.sigmoid(model(batch[\"X\"].to(device))).cpu().numpy().squeeze()\n            if tmp_pred.size == 1:\n                y_pred.append(tmp_pred)\n            else:\n                y_pred.extend(tmp_pred.tolist())\n            ids.extend(batch[\"id\"].numpy().tolist())\n            \n    preddf = pd.DataFrame({\"BraTS21ID\": ids, \"MGMT_value\": y_pred}) \n    preddf = preddf.set_index(\"BraTS21ID\")\n    return preddf\n    ","metadata":{"execution":{"iopub.status.busy":"2021-09-01T07:24:01.560478Z","iopub.execute_input":"2021-09-01T07:24:01.560844Z","iopub.status.idle":"2021-09-01T07:24:01.874126Z","shell.execute_reply.started":"2021-09-01T07:24:01.560809Z","shell.execute_reply":"2021-09-01T07:24:01.873140Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.read_csv(f\"{data_directory}/sample_submission.csv\", index_col=\"BraTS21ID\")\n\nsubmission[\"MGMT_value\"] = 0\nfor idx, mtype, mst in zip(np.arange(len(modelfiles)), mri_types + mri_types, [0, 0, 0, 0, 0, 0, 0, 0]):\n    pred = predict(modelfiles[idx], submission, mtype, \"test\", mst)\n    submission[\"MGMT_value\"] += pred[\"MGMT_value\"]\n\n\nsubmission[\"MGMT_value\"] /= len(modelfiles)\nsubmission.head()\n\n","metadata":{"execution":{"iopub.status.busy":"2021-09-01T07:24:02.139757Z","iopub.execute_input":"2021-09-01T07:24:02.140089Z","iopub.status.idle":"2021-09-01T07:28:06.274011Z","shell.execute_reply.started":"2021-09-01T07:24:02.140060Z","shell.execute_reply":"2021-09-01T07:28:06.273082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission[\"MGMT_value\"].hist()","metadata":{"execution":{"iopub.status.busy":"2021-09-01T07:29:20.645146Z","iopub.execute_input":"2021-09-01T07:29:20.645490Z","iopub.status.idle":"2021-09-01T07:29:20.835531Z","shell.execute_reply.started":"2021-09-01T07:29:20.645457Z","shell.execute_reply":"2021-09-01T07:29:20.834569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission[\"MGMT_value\"].to_csv(\"submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2021-09-01T07:30:20.225061Z","iopub.execute_input":"2021-09-01T07:30:20.225403Z","iopub.status.idle":"2021-09-01T07:30:20.235030Z","shell.execute_reply.started":"2021-09-01T07:30:20.225372Z","shell.execute_reply":"2021-09-01T07:30:20.234110Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}