{"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":"<a id=\"top\"></a>\n\n<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<h2 class=\"list-group-item list-group-item-action active alert alert-info\" data-toggle=\"list\" role=\"tab\" aria-controls=\"home\"><center>Navigation</center></h2>\n\n* [File structure](#1)\n* [Data Visualization](#2)\n* [Animation](#3)\n    \n    \n* [Modeling](#20)\n    \n    \n* [LIME](#30)","metadata":{}},{"cell_type":"markdown","source":"This work uses some ideas from: \n\nhttps://www.kaggle.com/code/ihelon/brain-tumor-eda-with-animations-and-modeling - navigation & animation technique\n\nhttps://www.kaggle.com/code/cedricsoares/tf-efficientnet-transfer-learning-strat-split/notebook?scriptVersionId=77118556 - model \n\nhttps://www.kaggle.com/competitions/rsna-miccai-brain-tumor-radiogenomic-classification/leaderboard - leaderboard","metadata":{}},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n## <div class=\"alert alert-warning\" style=\"border:0;margin:0\"><center> File structure </center></div>","metadata":{}},{"cell_type":"markdown","source":"The competition data is defined by three cohorts: Training, Validation (Public), and Testing (Private). The “Training” and the “Validation” cohorts are provided to the participants, whereas the “Testing” cohort is kept hidden at all times, during and after the competition.\n\nThese 3 cohorts are structured as follows: Each independent case has a dedicated folder identified by a five-digit number. Within each of these “case” folders, there are four sub-folders, each of them corresponding to each of the structural multi-parametric MRI (mpMRI) scans, 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\nExact folder structure:\n\n```\nTraining/Validation/Testing\n│\n└─── 00000\n│   │\n│   └─── FLAIR\n│   │   │ Image-1.dcm\n│   │   │ Image-2.dcm\n│   │   │ ...\n│   │   \n│   └─── T1w\n│   │   │ Image-1.dcm\n│   │   │ Image-2.dcm\n│   │   │ ...\n│   │   \n│   └─── T1wCE\n│   │   │ Image-1.dcm\n│   │   │ Image-2.dcm\n│   │   │ ...\n│   │   \n│   └─── T2w\n│   │   │ Image-1.dcm\n│   │   │ Image-2.dcm\n│   │   │ .....\n│   \n└─── 00001\n│   │ ...\n│   \n│ ...   \n│   \n└─── 00002\n│   │ ...\n```\n\n## Files\n\n- **train/** - folder containing the training files, with each top-level folder representing a subject. **NOTE:** There are some unexpected issues with the following three cases in the training dataset, participants can exclude the cases during training: `[00109, 00123, 00709]`. We have checked and confirmed that the testing dataset is free from such issues.\n- **train\\_labels.csv** - file containing the target `MGMT_value` for each subject in the training data (e.g. the presence of MGMT promoter methylation)\n- **test/** - the test files, which use the same structure as `train/`; your task is to predict the `MGMT_value` for each subject in the test data. **NOTE**: the total size of the rerun test set (Public and Private) is ~5x the size of the Public test set\n- **sample\\_submission.csv** - a sample submission file in the correct format","metadata":{}},{"cell_type":"markdown","source":"train/ - folder containing the training files, with each top-level folder representing a subject. \n\nNOTE: There are some unexpected issues with the following three cases in the training dataset, participants can exclude the cases during training: [00109, 00123, 00709]. We have checked and confirmed that the testing dataset is free from such issues.","metadata":{}},{"cell_type":"code","source":"# import os\n# path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/train'\n\n# sum(os.path.isdir(os.path.join(path, i)) for i in os.listdir(path))","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:50.386541Z","iopub.execute_input":"2022-05-27T13:31:50.387090Z","iopub.status.idle":"2022-05-27T13:31:50.391153Z","shell.execute_reply.started":"2022-05-27T13:31:50.387057Z","shell.execute_reply":"2022-05-27T13:31:50.390245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# subjects = !ls /kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification/train/* -d\n# len(subjects)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:51.130309Z","iopub.execute_input":"2022-05-27T13:31:51.131122Z","iopub.status.idle":"2022-05-27T13:31:51.134630Z","shell.execute_reply.started":"2022-05-27T13:31:51.131067Z","shell.execute_reply":"2022-05-27T13:31:51.133857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We're given 585 subjects in the training dataset","metadata":{}},{"cell_type":"code","source":"# path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/test'\n\n# sum(os.path.isdir(os.path.join(path, i)) for i in os.listdir(path))","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:51.901082Z","iopub.execute_input":"2022-05-27T13:31:51.901369Z","iopub.status.idle":"2022-05-27T13:31:51.905488Z","shell.execute_reply.started":"2022-05-27T13:31:51.901336Z","shell.execute_reply":"2022-05-27T13:31:51.904612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We're given 87 subjects in the test dataset","metadata":{}},{"cell_type":"code","source":"# import numpy as np\n# import pandas as pd\n# import pydicom\n# import os\n# import glob \n# # The glob module finds all the pathnames matching a specified pattern according to the rules used by the Unix shell, \n# #although results are returned in arbitrary order.\n# import matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:52.267492Z","iopub.execute_input":"2022-05-27T13:31:52.267975Z","iopub.status.idle":"2022-05-27T13:31:52.271155Z","shell.execute_reply.started":"2022-05-27T13:31:52.267943Z","shell.execute_reply":"2022-05-27T13:31:52.270247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/train/*/*/*'\n\n# len(glob.glob(path))","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:52.644609Z","iopub.execute_input":"2022-05-27T13:31:52.645050Z","iopub.status.idle":"2022-05-27T13:31:52.648348Z","shell.execute_reply.started":"2022-05-27T13:31:52.645019Z","shell.execute_reply":"2022-05-27T13:31:52.647398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/test/*/*/*'\n\n# len(glob.glob(path))","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:52.983427Z","iopub.execute_input":"2022-05-27T13:31:52.983758Z","iopub.status.idle":"2022-05-27T13:31:52.987437Z","shell.execute_reply.started":"2022-05-27T13:31:52.983722Z","shell.execute_reply":"2022-05-27T13:31:52.986796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# path_name = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/test/*/*/*'\n# path = glob.glob(path_name)\n# len(path)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:53.279641Z","iopub.execute_input":"2022-05-27T13:31:53.280115Z","iopub.status.idle":"2022-05-27T13:31:53.283394Z","shell.execute_reply.started":"2022-05-27T13:31:53.280070Z","shell.execute_reply":"2022-05-27T13:31:53.282734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# slices = 0\n# for filename in path:\n#     data = load_dicom(filename)\n#     # Exclude the blank images\n#     if data.max() == 0:\n#         slices += 1 \n# print(slices)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:53.575802Z","iopub.execute_input":"2022-05-27T13:31:53.576278Z","iopub.status.idle":"2022-05-27T13:31:53.580038Z","shell.execute_reply.started":"2022-05-27T13:31:53.576228Z","shell.execute_reply":"2022-05-27T13:31:53.578965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# (14404/51473)*100","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:53.872604Z","iopub.execute_input":"2022-05-27T13:31:53.873008Z","iopub.status.idle":"2022-05-27T13:31:53.876343Z","shell.execute_reply.started":"2022-05-27T13:31:53.872978Z","shell.execute_reply":"2022-05-27T13:31:53.875634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# path_name = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/train/*/*/*'\n# path = glob.glob(path_name)\n# len(path)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:54.172892Z","iopub.execute_input":"2022-05-27T13:31:54.173323Z","iopub.status.idle":"2022-05-27T13:31:54.176875Z","shell.execute_reply.started":"2022-05-27T13:31:54.173291Z","shell.execute_reply":"2022-05-27T13:31:54.175965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# slices = 0\n# for filename in path:\n#     data = load_dicom(filename)\n#     # Exclude the blank images\n#     if data.max() == 0:\n#         slices += 1 \n# print(slices)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:54.756469Z","iopub.execute_input":"2022-05-27T13:31:54.756738Z","iopub.status.idle":"2022-05-27T13:31:54.760084Z","shell.execute_reply.started":"2022-05-27T13:31:54.756710Z","shell.execute_reply":"2022-05-27T13:31:54.759335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# (94752/348641)*100","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:55.444163Z","iopub.execute_input":"2022-05-27T13:31:55.444692Z","iopub.status.idle":"2022-05-27T13:31:55.448413Z","shell.execute_reply.started":"2022-05-27T13:31:55.444658Z","shell.execute_reply":"2022-05-27T13:31:55.447491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"It total we have 348 641 scans (train) and 51 473 scans (test)\n\n94 752 (train, 27.17%)\n\n14 404 (test, puste, 27.98%)   ","metadata":{}},{"cell_type":"code","source":"# scans = !ls /kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification/test/*/FLAIR/* -d\n# len(scans)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:56.108196Z","iopub.execute_input":"2022-05-27T13:31:56.108874Z","iopub.status.idle":"2022-05-27T13:31:56.111902Z","shell.execute_reply.started":"2022-05-27T13:31:56.108821Z","shell.execute_reply":"2022-05-27T13:31:56.111123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from tqdm import tqdm\n# count_min = 10e6\n# count_max = 0\n# for s in tqdm(scans):\n#     cnt, = !ls {s}/* | wc -l # this is super-slow.. probably avoiding \"!\" would be a good idea\n#     count_min = min(count_min, int(cnt))\n#     count_max = max(count_max, int(cnt))\n# count_min, count_max","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:56.795932Z","iopub.execute_input":"2022-05-27T13:31:56.796452Z","iopub.status.idle":"2022-05-27T13:31:56.799829Z","shell.execute_reply.started":"2022-05-27T13:31:56.796419Z","shell.execute_reply":"2022-05-27T13:31:56.799193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Each scan consists of number of slices, between 15 and 514","metadata":{}},{"cell_type":"markdown","source":"<a id=\"2\"></a>\n## <div class=\"alert alert-warning\" style=\"border:0;margin:0\"><center> Data visualization </center></div>","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport pydicom\nimport os\nimport glob \n# The glob module finds all the pathnames matching a specified pattern according to the rules used by the Unix shell, \n#although results are returned in arbitrary order.\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:57.720634Z","iopub.execute_input":"2022-05-27T13:31:57.721208Z","iopub.status.idle":"2022-05-27T13:31:57.949126Z","shell.execute_reply.started":"2022-05-27T13:31:57.721160Z","shell.execute_reply":"2022-05-27T13:31:57.948112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_dicom(path):\n    ds = pydicom.dcmread(path)\n    \n    # Convert to float to avoid overflow or underflow losses.\n    image_2d = ds.pixel_array.astype(float)\n\n    # Convert 16-bit pixels to 8-bit\n    if image_2d.max() != 0.0:\n        image_2d_scaled = (np.maximum(image_2d, 0) / image_2d.max()) * 255.0\n    else:\n        image_2d_scaled = image_2d  # blank image\n\n    # Convert to uint\n    image_2d_scaled = np.uint8(image_2d_scaled)\n    \n    return image_2d_scaled\n\ndef get_middle_image(file_directory):\n    list_of_files = os.listdir(file_directory)\n    #  sorts the list of image directories by image number in a path\n    list_of_files.sort(key=lambda x: int(x.split('/')[-1].split('-')[-1].split('.')[0]))  \n    num_of_scans = len(list_of_files)\n    middle_file = list_of_files[num_of_scans//2]\n    return middle_file\n\n\ndef full_ids(data):\n# Add the full paths for each id for different types of sequences to the csv \n# 0 -> 00000; 1010 ->  01010\n    return data.astype(str).str.zfill(5)\n\n\ndef check_MGMT_value(subject_folder):\n    train_labels = pd.read_csv(\"../input/rsna-miccai-brain-tumor-radiogenomic-classification/train_labels.csv\")\n    mgmt_value = train_labels[full_ids(train_labels.BraTS21ID) == subject_folder][\"MGMT_value\"].values[0]\n    return mgmt_value\n\n\ndef diffrent_types_subplot(directory_path, dataset_type, subject_folder, scans_types):\n    plt.figure(figsize=(16, 5))\n    for i, scan_type in enumerate(scans_types, 1):\n        file_directory = os.path.join(directory_path, dataset_type, subject_folder, scan_type)   \n        file_name = get_middle_image(file_directory)\n        plt.subplot(1, 4, i)\n        plt.title(f\"{scan_type}\", fontsize=16)\n \n        plt.xticks([])\n        plt.yticks([])\n        plt.xlabel(file_name, fontsize=14)\n        ds = load_dicom(os.path.join(file_directory, file_name))\n        plt.imshow(ds, cmap=\"gray\") \n    \n    mgmt_value = check_MGMT_value(subject_folder)\n    plt.suptitle(f\"MGMT_value: {mgmt_value}\", fontsize=16);\n    plt.text(0.45, 0.88, f\"Subject: {subject_folder}\", fontsize=15, transform=plt.gcf().transFigure);\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-27T16:51:36.058326Z","iopub.execute_input":"2022-05-27T16:51:36.058710Z","iopub.status.idle":"2022-05-27T16:51:36.075421Z","shell.execute_reply.started":"2022-05-27T16:51:36.058665Z","shell.execute_reply":"2022-05-27T16:51:36.074468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # data visualization\n# directory_path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n# dataset_type = 'train'\n# subject_folder = '00000'\n# scans_types = ['FLAIR','T1w','T1wCE','T2w']\n\n\n# diffrent_types_subplot(directory_path, dataset_type, subject_folder, scans_types)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:58.332978Z","iopub.execute_input":"2022-05-27T13:31:58.333259Z","iopub.status.idle":"2022-05-27T13:31:58.337876Z","shell.execute_reply.started":"2022-05-27T13:31:58.333228Z","shell.execute_reply":"2022-05-27T13:31:58.336827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# subject_folder = '00003'\n\n# diffrent_types_subplot(directory_path, dataset_type, subject_folder, scans_types)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:58.662581Z","iopub.execute_input":"2022-05-27T13:31:58.662944Z","iopub.status.idle":"2022-05-27T13:31:58.667253Z","shell.execute_reply.started":"2022-05-27T13:31:58.662913Z","shell.execute_reply":"2022-05-27T13:31:58.666493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"3\"></a>\n## <div class=\"alert alert-warning\" style=\"border:0;margin:0\"><center> Animation </center></div>","metadata":{}},{"cell_type":"code","source":"from matplotlib import animation, rc\nrc('animation', html='jshtml')\n\n\ndef create_animation(ims):\n    fig = plt.figure(figsize=(6, 6))\n    plt.axis('off')\n    im = plt.imshow(ims[0], cmap=\"gray\");\n\n    def animate_func(i):\n        im.set_array(ims[i])\n        return [im]\n\n    return animation.FuncAnimation(fig, animate_func, frames = len(ims), interval = 100)\n\n\ndef read_scan(path, include_empty=True):\n    t_paths = sorted(glob.glob(os.path.join(path, \"*\")), \n                     key=lambda x: int(x[:-4].split(\"-\")[-1]))\n    slices = []\n    for filename in t_paths:\n        data = load_dicom(filename)\n        # Exclude the blank images\n        if not include_empty and data.max() == 0:\n            continue  # choose next image\n        slices.append(data)\n    return slices","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:59.037080Z","iopub.execute_input":"2022-05-27T13:31:59.037507Z","iopub.status.idle":"2022-05-27T13:31:59.048807Z","shell.execute_reply.started":"2022-05-27T13:31:59.037478Z","shell.execute_reply":"2022-05-27T13:31:59.048057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def whole_scan_subplot(directory_path, dataset_type, subject_folder, scan_type, include_empty):\n    folder_directory = os.path.join(directory_path, dataset_type, subject_folder, scan_type)  \n    print(folder_directory)\n    images = read_scan(folder_directory,include_empty=include_empty)\n\n    print('No of images:', len(images))\n    mgmt_value = check_MGMT_value(subject_folder)\n    print('MGMT: ', mgmt_value)\n\n    fig = plt.figure(figsize=(30,10))\n\n    c = 1\n    for image in images:\n        ax = fig.add_subplot(len(images)//10+1, 10, c)\n        ax.imshow(image, cmap='gray')\n        c+=1\n        plt.axis('off')\n        plt.suptitle(f\"Folder: {dataset_type}/{subject_folder}/{scan_type} \\nMGMT_value: {mgmt_value}\", fontsize=35);\n        fig.tight_layout()","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:59.343595Z","iopub.execute_input":"2022-05-27T13:31:59.344115Z","iopub.status.idle":"2022-05-27T13:31:59.351368Z","shell.execute_reply.started":"2022-05-27T13:31:59.344080Z","shell.execute_reply":"2022-05-27T13:31:59.350488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# directory_path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n# dataset_type = 'train'\n# subject_folder = '00000'\n# scan_type = 'T1w'\n\n# whole_scan_subplot(directory_path, dataset_type, subject_folder, scan_type, include_empty=True)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:31:59.662930Z","iopub.execute_input":"2022-05-27T13:31:59.663188Z","iopub.status.idle":"2022-05-27T13:31:59.667660Z","shell.execute_reply.started":"2022-05-27T13:31:59.663163Z","shell.execute_reply":"2022-05-27T13:31:59.666630Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# images = read_scan(\"../input/rsna-miccai-brain-tumor-radiogenomic-classification/train/00000/T1w\",include_empty=False)\n# print(len(images))\n# anim = create_animation(images)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:00.023566Z","iopub.execute_input":"2022-05-27T13:32:00.024465Z","iopub.status.idle":"2022-05-27T13:32:00.028174Z","shell.execute_reply.started":"2022-05-27T13:32:00.024430Z","shell.execute_reply":"2022-05-27T13:32:00.027396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# anim","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:00.705943Z","iopub.execute_input":"2022-05-27T13:32:00.706375Z","iopub.status.idle":"2022-05-27T13:32:00.710447Z","shell.execute_reply.started":"2022-05-27T13:32:00.706345Z","shell.execute_reply":"2022-05-27T13:32:00.709481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# anim.save('im.mp4')","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:01.595515Z","iopub.execute_input":"2022-05-27T13:32:01.595919Z","iopub.status.idle":"2022-05-27T13:32:01.600002Z","shell.execute_reply.started":"2022-05-27T13:32:01.595880Z","shell.execute_reply":"2022-05-27T13:32:01.599318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"20\"></a>\n## <div class=\"alert alert-danger\" style=\"border:0;margin:0\"><center> Modeling </center></div>","metadata":{}},{"cell_type":"markdown","source":"**3rd place solution: https://www.kaggle.com/code/cedricsoares/tf-efficientnet-transfer-learning-strat-split/notebook?scriptVersionId=77118556**\n\nHis aproach: \n- He used stratified split based on patient ids and class on train dataset to sample a validation dataset\n- He trained four EfficientNet-B3. One for each kind of MRI scans (FLAIR, T1w, T1wCE, T2w)\n- He aggregated results by patient ids to compare differences between the maximum prediction and the average of predictions to average average and the minimum of predictions to keep the prediction linked to the highest difference.","metadata":{}},{"cell_type":"markdown","source":"https://www.tensorflow.org/tutorials/keras/save_and_load#options - how to load model","metadata":{}},{"cell_type":"code","source":"import os                          # Iterate over dataset directories\nimport math                        # For ceil method\nimport cv2                         # Resize for image files\nimport pydicom                     # Read dcm files\nimport matplotlib.pyplot as plt    # Plot images\nimport numpy as np                 # Linear algebra\nimport pandas as pd                # Data processing, CSV file I/O (e.g. pd.read_csv)\nimport tensorflow as tf            # Load model\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom keras_preprocessing.image.dataframe_iterator import DataFrameIterator","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:02.326394Z","iopub.execute_input":"2022-05-27T13:32:02.327347Z","iopub.status.idle":"2022-05-27T13:32:09.713385Z","shell.execute_reply.started":"2022-05-27T13:32:02.327274Z","shell.execute_reply":"2022-05-27T13:32:09.712633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"root_dir = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/'\ndf_train = pd.read_csv(root_dir+'train_labels.csv')","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:09.714867Z","iopub.execute_input":"2022-05-27T13:32:09.715143Z","iopub.status.idle":"2022-05-27T13:32:09.730084Z","shell.execute_reply.started":"2022-05-27T13:32:09.715112Z","shell.execute_reply":"2022-05-27T13:32:09.729108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train['BraTS21ID_full'] = full_ids(df_train['BraTS21ID'])\n\n# Add all the paths to the df for easy access\ndf_train['flair'] = df_train['BraTS21ID_full'].apply(lambda file_id : root_dir+'train/'+file_id+'/FLAIR/')\ndf_train['t1w'] = df_train['BraTS21ID_full'].apply(lambda file_id : root_dir+'train/'+file_id+'/T1w/')\ndf_train['t1wce'] = df_train['BraTS21ID_full'].apply(lambda file_id : root_dir+'train/'+file_id+'/T1wCE/')\ndf_train['t2w'] = df_train['BraTS21ID_full'].apply(lambda file_id : root_dir+'train/'+file_id+'/T2w/')","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:09.731373Z","iopub.execute_input":"2022-05-27T13:32:09.731663Z","iopub.status.idle":"2022-05-27T13:32:09.761791Z","shell.execute_reply.started":"2022-05-27T13:32:09.731628Z","shell.execute_reply":"2022-05-27T13:32:09.761011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.head(5)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:09.763559Z","iopub.execute_input":"2022-05-27T13:32:09.763993Z","iopub.status.idle":"2022-05-27T13:32:09.786014Z","shell.execute_reply.started":"2022-05-27T13:32:09.763960Z","shell.execute_reply":"2022-05-27T13:32:09.785045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test = pd.read_csv(root_dir+'sample_submission.csv')\n\ndf_test['BraTS21ID_full'] = full_ids(df_test['BraTS21ID'])\n\n# Add all the paths to the df for easy access\ndf_test['flair'] = df_test['BraTS21ID_full'].apply(lambda file_id : root_dir+'test/'+file_id+'/FLAIR/')\ndf_test['t1w'] = df_test['BraTS21ID_full'].apply(lambda file_id : root_dir+'test/'+file_id+'/T1w/')\ndf_test['t1wce'] = df_test['BraTS21ID_full'].apply(lambda file_id : root_dir+'test/'+file_id+'/T1wCE/')\ndf_test['t2w'] = df_test['BraTS21ID_full'].apply(lambda file_id : root_dir+'test/'+file_id+'/T2w/')","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:09.787372Z","iopub.execute_input":"2022-05-27T13:32:09.787691Z","iopub.status.idle":"2022-05-27T13:32:09.805893Z","shell.execute_reply.started":"2022-05-27T13:32:09.787651Z","shell.execute_reply":"2022-05-27T13:32:09.804914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:09.807296Z","iopub.execute_input":"2022-05-27T13:32:09.807609Z","iopub.status.idle":"2022-05-27T13:32:09.825393Z","shell.execute_reply.started":"2022-05-27T13:32:09.807570Z","shell.execute_reply":"2022-05-27T13:32:09.824455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 00109 (FLAIR images are blank) 00123 (T1w images are blank) 00709 (FLAIR images are blank)\ndef get_train_val_dataframe(mri_type):\n    all_img_files = []\n    all_img_labels = []\n    all_img_patient_ids = []\n    for row in df_train.iterrows():\n        if row[1]['BraTS21ID_full'] == '00109' and mri_type == 'flair':\n            continue\n        if row[1]['BraTS21ID_full'] == '00123' and mri_type == 't1w':\n            continue\n        if row[1]['BraTS21ID_full'] == '00709' and mri_type == 'flair':\n            continue\n        img_dir = row[1][mri_type]\n        img_files = os.listdir(img_dir)\n        img_nums = sorted([int(ele.replace('Image-', '').replace('.dcm', '')) for ele in img_files])\n        mid_point = int(len(img_nums)/2)\n        start_point = mid_point - max(int(mid_point*0.1), 1)\n        end_point = mid_point + max(int(mid_point*0.1), 1)\n        img_names = [f'Image-{img_nums[i]}.dcm' for i in range(start_point, end_point+1)]\n        img_paths = [img_dir+ele for ele in img_names]\n        img_labels = [row[1]['MGMT_value']]*len(img_paths)\n        img_patient_ids = [row[1]['BraTS21ID']]*len(img_paths)\n        all_img_files.extend(img_paths)\n        all_img_labels.extend(img_labels)\n        all_img_patient_ids.extend(img_patient_ids)\n\n    train_val_df = pd.DataFrame({'patient_ids': all_img_patient_ids,\n                  'labels': all_img_labels,\n                  'file_paths': all_img_files})\n\n    train_val_df['labels'] = train_val_df['labels'].map({1: '1', 0: '0'})\n    \n    #stratifiied 90% split on patient_ids and labels  \n    class_prop= 0.90\n    classes_splits  = {}\n    for i in range(2):\n        train_val_label_class = train_val_df[train_val_df['labels']==f'{i}']\n        train_val_list_ids =  list(train_val_label_class['patient_ids'].unique())\n        train_threshold = math.ceil(class_prop*len(train_val_list_ids))\n        train_ids = train_val_list_ids[:train_threshold]\n        val_ids = train_val_list_ids[train_threshold:]\n        classes_splits[f'train_{i}'] = train_val_label_class[train_val_label_class['patient_ids'].isin(train_ids)]\n        classes_splits[f'val_{i}'] = val_df = train_val_label_class[train_val_label_class['patient_ids'].isin(val_ids)]\n        \n    train_df = pd.concat([classes_splits['train_0'], classes_splits['train_1']], axis=0)\n    val_df = pd.concat([classes_splits['val_0'], classes_splits['val_1']], axis=0)\n  \n    return train_df, val_df","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:09:54.845119Z","iopub.execute_input":"2022-05-27T14:09:54.845408Z","iopub.status.idle":"2022-05-27T14:09:54.860369Z","shell.execute_reply.started":"2022-05-27T14:09:54.845378Z","shell.execute_reply":"2022-05-27T14:09:54.859765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_train_val_dataframe('t2w')","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:11:03.110340Z","iopub.execute_input":"2022-05-27T14:11:03.110676Z","iopub.status.idle":"2022-05-27T14:11:03.900540Z","shell.execute_reply.started":"2022-05-27T14:11:03.110640Z","shell.execute_reply":"2022-05-27T14:11:03.899901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_test_dataframe(mri_type):\n    \n    all_test_img_files = []\n    all_test_img_labels = []\n    all_test_img_patient_ids = []\n    for row in df_test.iterrows():\n        img_dir = row[1][mri_type]\n        img_files = os.listdir(img_dir)\n        img_nums = sorted([int(ele.replace('Image-', '').replace('.dcm', '')) for ele in img_files])\n        mid_point = int(len(img_nums)/2)\n        start_point = mid_point - max(int(mid_point*0.1), 1)\n        end_point = mid_point + max(int(mid_point*0.1), 1)\n        img_names = [f'Image-{img_nums[i]}.dcm' for i in range(start_point, end_point+1)]\n        img_paths = [img_dir+ele for ele in img_names]\n        img_labels = [row[1]['MGMT_value']]*len(img_paths)\n        img_patient_ids = [row[1]['BraTS21ID']]*len(img_paths)\n        all_test_img_files.extend(img_paths)\n        all_test_img_labels.extend(img_labels)\n        all_test_img_patient_ids.extend(img_patient_ids)\n\n    test_df = pd.DataFrame({'patient_ids': all_test_img_patient_ids,\n                  'labels': all_test_img_labels,\n                  'file_paths': all_test_img_files})\n    \n    test_df['labels'] = ['1']*(len(test_df)-1) + ['0'] # workaround for testing data gen\n    \n    return test_df","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:21:10.993243Z","iopub.execute_input":"2022-05-27T14:21:10.993579Z","iopub.status.idle":"2022-05-27T14:21:11.005036Z","shell.execute_reply.started":"2022-05-27T14:21:10.993530Z","shell.execute_reply":"2022-05-27T14:21:11.003775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_test_dataframe(\"t2w\")","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:22:49.106134Z","iopub.execute_input":"2022-05-27T14:22:49.106436Z","iopub.status.idle":"2022-05-27T14:22:49.226221Z","shell.execute_reply.started":"2022-05-27T14:22:49.106402Z","shell.execute_reply":"2022-05-27T14:22:49.225404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DCMDataFrameIterator(DataFrameIterator):\n    def __init__(self, *arg, **kwargs):\n        self.white_list_formats = ('dcm')\n        super(DCMDataFrameIterator, self).__init__(*arg, **kwargs)\n        self.dataframe = kwargs['dataframe']\n        self.x = self.dataframe[kwargs['x_col']]\n        self.y = self.dataframe[kwargs['y_col']]\n        self.color_mode = kwargs['color_mode']\n        self.target_size = kwargs['target_size']\n\n    def _get_batches_of_transformed_samples(self, indices_array):\n        # get batch of images\n        batch_x = np.array([self.read_dcm_as_array(dcm_path, self.target_size, color_mode=self.color_mode)\n                            for dcm_path in self.x.iloc[indices_array]])\n\n        batch_y = np.array(self.y.iloc[indices_array].astype(np.uint8))  # astype because y was passed as str\n\n        # transform images\n        if self.image_data_generator is not None:\n            for i, (x, y) in enumerate(zip(batch_x, batch_y)):\n                transform_params = self.image_data_generator.get_random_transform(x.shape)\n                batch_x[i] = self.image_data_generator.apply_transform(x, transform_params)\n                # you can change y here as well, eg: in semantic segmentation you want to transform masks as well \n                # using the same image_data_generator transformations.\n\n        return batch_x, batch_y\n\n    \n    #####################\n    @staticmethod\n    def read_dcm_as_array(dcm_path, target_size=(300, 300), color_mode='rgb'):\n        image_array = pydicom.dcmread(dcm_path).pixel_array\n        pixels = image_array - np.min(image_array)\n        pixels = pixels / np.max(pixels)\n        image_manual_norm = (pixels * 255).astype(np.uint8)\n        image_array = cv2.resize(image_manual_norm, target_size, interpolation=cv2.INTER_NEAREST)  #this returns a 2d array\n#         image_array = np.expand_dims(image_array, -1)\n        if color_mode == 'rgb':\n            image_array = np.dstack((image_array, np.zeros_like(image_array), np.zeros_like(image_array)))\n        return image_array","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:40.106575Z","iopub.execute_input":"2022-05-27T13:32:40.107358Z","iopub.status.idle":"2022-05-27T13:32:40.121475Z","shell.execute_reply.started":"2022-05-27T13:32:40.107314Z","shell.execute_reply":"2022-05-27T13:32:40.120584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SEED = 369\nBATCH_SIZE = 128\nCLASS_MODE = 'binary'\nCOLOR_MODE = 'rgb'\nTARGET_SIZE = (300, 300)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:40.123290Z","iopub.execute_input":"2022-05-27T13:32:40.123625Z","iopub.status.idle":"2022-05-27T13:32:40.138468Z","shell.execute_reply.started":"2022-05-27T13:32:40.123581Z","shell.execute_reply":"2022-05-27T13:32:40.137793Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_data_generators(train_df,val_df, test_df):\n    train_augmentation_parameters = dict(\n        rescale=1.0/255,\n        zoom_range=0.2,\n        rotation_range=0.2,\n        fill_mode='nearest',\n        height_shift_range= 0.1,\n        width_shift_range=0.1,\n        horizontal_flip=True,\n        brightness_range = [0.8, 1.2]\n    )\n    \n    val_augmentation_parameters = dict(\n        rescale=1.0/255.0\n    )\n\n    test_augmentation_parameters = dict(\n        rescale=1.0/255.0\n    )\n\n    train_consts = {\n        'seed': SEED,\n        'batch_size': BATCH_SIZE,\n        'class_mode': CLASS_MODE,\n        'color_mode': COLOR_MODE,\n        'target_size': TARGET_SIZE,  \n    }\n    \n    val_consts = {\n    'batch_size': BATCH_SIZE,\n    'class_mode': CLASS_MODE,\n    'color_mode': COLOR_MODE,\n    'target_size': TARGET_SIZE,\n    'shuffle': False\n    }\n\n    test_consts = {\n        'batch_size': BATCH_SIZE,\n        'class_mode': CLASS_MODE,\n        'color_mode': COLOR_MODE,\n        'target_size': TARGET_SIZE,\n        'shuffle': False\n    }\n\n    train_augmenter = ImageDataGenerator(**train_augmentation_parameters)\n    val_augmenter = ImageDataGenerator(**val_augmentation_parameters)\n    test_augmenter = ImageDataGenerator(**test_augmentation_parameters)\n\n    train_generator = DCMDataFrameIterator(dataframe=train_df,\n                                 x_col='file_paths',\n                                 y_col='labels',\n                                 image_data_generator=train_augmenter,\n                                 **train_consts)\n    \n    val_generator = DCMDataFrameIterator(dataframe=val_df,\n                                 x_col='file_paths',\n                                 y_col='labels',\n                                 image_data_generator=val_augmenter,\n                                 **val_consts)\n    \n    test_generator = DCMDataFrameIterator(dataframe=test_df,\n                                 x_col='file_paths',\n                                 y_col='labels',\n                                 image_data_generator=test_augmenter,\n                                 **test_consts)\n    \n    return train_generator, val_generator, test_generator","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:40.139886Z","iopub.execute_input":"2022-05-27T13:32:40.140343Z","iopub.status.idle":"2022-05-27T13:32:40.152903Z","shell.execute_reply.started":"2022-05-27T13:32:40.140292Z","shell.execute_reply":"2022-05-27T13:32:40.152065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Recreate the exact same model, including its weights and the optimizer\nbest_model = tf.keras.models.load_model('../input/cedric-soares-best-model/best_model.h5')\n\n# # Show the model architecture\n# best_model.summary()","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:40.153954Z","iopub.execute_input":"2022-05-27T13:32:40.154276Z","iopub.status.idle":"2022-05-27T13:32:44.653665Z","shell.execute_reply.started":"2022-05-27T13:32:40.154249Z","shell.execute_reply":"2022-05-27T13:32:44.652786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# len(best_model.layers)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:44.654870Z","iopub.execute_input":"2022-05-27T13:32:44.655498Z","iopub.status.idle":"2022-05-27T13:32:44.662493Z","shell.execute_reply.started":"2022-05-27T13:32:44.655462Z","shell.execute_reply":"2022-05-27T13:32:44.661527Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# tf.keras.utils.plot_model(best_model)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:32:44.664037Z","iopub.execute_input":"2022-05-27T13:32:44.664435Z","iopub.status.idle":"2022-05-27T13:32:44.688348Z","shell.execute_reply.started":"2022-05-27T13:32:44.664390Z","shell.execute_reply":"2022-05-27T13:32:44.687329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n# train a model for each of the mri types and then ensemble predictions\nall_test_preds = []\n\n# Re-evaluate the model\nfor mt in ['flair', 't1w', 't1wce', 't2w']:\n    print(mt.upper())\n    train_df, val_df = get_train_val_dataframe(mt)\n    test_df = get_test_dataframe(mt)\n    train_g, val_g, test_g = get_data_generators(train_df, val_df, test_df)\n\n    results = best_model.evaluate(test_g, steps=len(test_g), verbose=2)\n    print(f\"Restored model. Test loss, test acc, test AUC: {results}\")\n    test_pred = best_model.predict(test_g, steps=len(test_g))\n    test_df['pred_y'] = test_pred\n    # aggregate the predictions on all image for each person (take the most confident prediction out of all image predictions)\n    mean_pred = test_pred.mean()\n    test_pred_agg = test_df.groupby('patient_ids').apply(\n        lambda x: x['pred_y'].max()\n        if (x['pred_y'].max() - mean_pred) > (mean_pred - x['pred_y'].min()) \n        else x['pred_y'].min())\n    all_test_preds.append(test_pred_agg.values)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T18:25:05.793709Z","iopub.execute_input":"2022-05-27T18:25:05.793993Z","iopub.status.idle":"2022-05-27T18:27:25.029572Z","shell.execute_reply.started":"2022-05-27T18:25:05.793965Z","shell.execute_reply":"2022-05-27T18:27:25.027624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_test_preds = np.array(all_test_preds)\nplt.hist(all_test_preds.mean(0))","metadata":{"execution":{"iopub.status.busy":"2022-05-27T18:35:42.402155Z","iopub.execute_input":"2022-05-27T18:35:42.402506Z","iopub.status.idle":"2022-05-27T18:35:42.640893Z","shell.execute_reply.started":"2022-05-27T18:35:42.402469Z","shell.execute_reply":"2022-05-27T18:35:42.639870Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"subm = pd.read_csv(root_dir+'sample_submission.csv')\nsubm['MGMT_value'] = all_test_preds.mean(0)\nsubm.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:47:20.813071Z","iopub.execute_input":"2022-05-27T13:47:20.813303Z","iopub.status.idle":"2022-05-27T13:47:20.833351Z","shell.execute_reply.started":"2022-05-27T13:47:20.813274Z","shell.execute_reply":"2022-05-27T13:47:20.832723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"subm","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:47:20.834481Z","iopub.execute_input":"2022-05-27T13:47:20.834858Z","iopub.status.idle":"2022-05-27T13:47:20.847630Z","shell.execute_reply.started":"2022-05-27T13:47:20.834828Z","shell.execute_reply":"2022-05-27T13:47:20.846984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def check_MGMT_value_test(subject_folder):\n    mgmt_value = subm[subm.BraTS21ID.astype(str).str.zfill(5) == subject_folder][\"MGMT_value\"].values[0]\n    return mgmt_value\n","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:47:20.848827Z","iopub.execute_input":"2022-05-27T13:47:20.849645Z","iopub.status.idle":"2022-05-27T13:47:20.861282Z","shell.execute_reply.started":"2022-05-27T13:47:20.849592Z","shell.execute_reply":"2022-05-27T13:47:20.860219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"30\"></a>\n## <div class=\"alert alert-warning\" style=\"border:0;margin:0\"><center> LIME </center></div>","metadata":{}},{"cell_type":"markdown","source":"https://towardsdatascience.com/interpreting-image-classification-model-with-lime-1e7064a2f2e5","metadata":{}},{"cell_type":"code","source":"!pip install lime","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:47:20.863015Z","iopub.execute_input":"2022-05-27T13:47:20.863361Z","iopub.status.idle":"2022-05-27T13:47:32.455128Z","shell.execute_reply.started":"2022-05-27T13:47:20.863315Z","shell.execute_reply":"2022-05-27T13:47:32.454325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from lime import lime_image\nfrom skimage.segmentation import mark_boundaries\nfrom tqdm import tqdm\n\nexplainer = lime_image.LimeImageExplainer()","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:47:32.456537Z","iopub.execute_input":"2022-05-27T13:47:32.457152Z","iopub.status.idle":"2022-05-27T13:47:34.208199Z","shell.execute_reply.started":"2022-05-27T13:47:32.457112Z","shell.execute_reply":"2022-05-27T13:47:34.207140Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def diffrent_types_subplot_LIME_steps(directory_path, dataset_type, subject_folder, scans_types):\n    plt.figure(figsize=(16, 22))\n    \n    for i, scan_type in enumerate(scans_types, 1):\n        file_directory = os.path.join(directory_path, dataset_type, subject_folder, scan_type)   \n        file_name = get_middle_image(file_directory)\n        \n        image = load_dicom(os.path.join(file_directory, file_name))\n        plt.subplot(5, len(scans_types), i)\n        plt.title(f\"{scan_type}\", fontsize=16)\n        plt.xticks([])\n        plt.yticks([])\n        plt.xlabel(file_name, fontsize=14)\n        plt.imshow(image, cmap=\"gray\") \n        \n        explanation = explainer.explain_instance(image, best_model.predict, top_labels=2, hide_color=0, num_samples=500)\n        plt.subplot(5, len(scans_types), i + len(scans_types))\n        plt.title(f\"{scan_type}\", fontsize=16)\n        plt.xticks([])\n        plt.yticks([])\n        plt.xlabel(file_name, fontsize=14)\n        plt.imshow(mark_boundaries(image, explanation.segments))\n\n        \n        # print(explanation.__dict__.keys())\n        # print(explanation.top_labels)\n        temp_1, mask_1 = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=True, num_features=5, hide_rest=True)\n        temp_2, mask_2 = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=False, num_features=10, hide_rest=False)\n        plt.subplot(5, len(scans_types), i + len(scans_types)*2)\n        plt.title(f\"{scan_type}\", fontsize=16)\n        plt.xticks([])\n        plt.yticks([])\n        plt.xlabel(file_name, fontsize=14)\n        plt.imshow(mark_boundaries(temp_2, explanation.segments))\n        \n\n        plt.subplot(5, len(scans_types), i + len(scans_types)*3)\n        plt.title(f\"{scan_type}\", fontsize=16)\n        plt.xticks([])\n        plt.yticks([])\n        plt.xlabel(file_name, fontsize=14)\n        plt.imshow(mark_boundaries(temp_2, mask_2))\n        \n        \n        plt.subplot(5, len(scans_types), i + len(scans_types)*3)\n        plt.title(f\"{scan_type}\", fontsize=16)\n        plt.xticks([])\n        plt.yticks([])\n        plt.xlabel(file_name, fontsize=14)\n        plt.imshow(mark_boundaries(temp_2, mask_2))\n\n    \n    mgmt_value = check_MGMT_value(subject_folder)\n    plt.suptitle(f\"MGMT_value: {mgmt_value}\", fontsize=16);\n    plt.text(0.45, 0.95, f\"Subject: {subject_folder}\", fontsize=15, transform=plt.gcf().transFigure);\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-27T16:37:44.252735Z","iopub.execute_input":"2022-05-27T16:37:44.253026Z","iopub.status.idle":"2022-05-27T16:37:44.268496Z","shell.execute_reply.started":"2022-05-27T16:37:44.252996Z","shell.execute_reply":"2022-05-27T16:37:44.267636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"directory_path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\ndataset_type = 'train'\nsubject_folder = '00000'\nscans_types = ['FLAIR','T1w', 'T1wCE','T2w']\n\n\ndiffrent_types_subplot_LIME_steps(directory_path, dataset_type, subject_folder, scans_types)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T16:38:18.756821Z","iopub.execute_input":"2022-05-27T16:38:18.757128Z","iopub.status.idle":"2022-05-27T16:38:22.580159Z","shell.execute_reply.started":"2022-05-27T16:38:18.757092Z","shell.execute_reply":"2022-05-27T16:38:22.577639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# subject_to_check = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/train/*'\n\n# subject_to_check = glob.glob(subject_to_check)\n# subject_to_check = [p[-5:] for p in subject_to_check]\n# subject_to_check.sort()","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:55:46.772429Z","iopub.execute_input":"2022-05-27T13:55:46.775321Z","iopub.status.idle":"2022-05-27T13:55:46.780652Z","shell.execute_reply.started":"2022-05-27T13:55:46.775267Z","shell.execute_reply":"2022-05-27T13:55:46.779575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for subject_folder in tqdm(subject_to_check):\n#     directory_path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n#     dataset_type = 'train'\n#     # subject_folder = '00000'\n#     scans_types = ['FLAIR','T1w','T1wCE','T2w']\n\n\n#     diffrent_types_subplot_LIME_2(directory_path, dataset_type, subject_folder, scans_types)\n#     diffrent_types_subplot(directory_path, dataset_type, subject_folder, scans_types)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T13:55:46.782476Z","iopub.execute_input":"2022-05-27T13:55:46.783249Z","iopub.status.idle":"2022-05-27T13:55:46.794087Z","shell.execute_reply.started":"2022-05-27T13:55:46.783200Z","shell.execute_reply":"2022-05-27T13:55:46.793154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"images — The image that we want LIME to explain.\n\nclassifier_fn — Your image classier prediction function.\n\ntop_labels — The number of labels that you want LIME to show. If it’s 3, then it will only show the top 3 labels with highest probabilities and ignore the rest.\n\nnum_samples — to determine the amount of artificial data points similar to our input that will be generated by LIME.","metadata":{}},{"cell_type":"code","source":"from skimage.segmentation import mark_boundaries\n\ndef diffrent_types_subplot_with_LIME_2(directory_path, dataset_type, subject_folder, scan_type):\n    for scan_type in scans_types:\n        file_directory = os.path.join(directory_path, dataset_type, subject_folder, scan_type)   \n        file_name = get_middle_image(file_directory)\n        path_to_file = os.path.join(file_directory, file_name)\n        image = load_dicom(path_to_file)\n\n        explanation = explainer.explain_instance(image, best_model.predict, top_labels=2, hide_color=0, num_samples=500)\n\n\n        temp_1, mask_1 = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=True, num_features=5, hide_rest=True)\n        temp_2, mask_2 = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=False, num_features=10, hide_rest=False)\n\n        fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))\n        ax1.imshow(mark_boundaries(temp_1, mask_1))\n        ax2.imshow(mark_boundaries(temp_2, mask_2))\n        ax1.axis('off')\n        ax2.axis('off')\n        mgmt_value = check_MGMT_value(subject_folder)\n        plt.suptitle(f\"MGMT_value: {mgmt_value}\\nImage: {dataset_type}/{subject_folder}/{scan_type}/{file_name}\", fontsize=16);\n        plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-27T16:52:10.950044Z","iopub.execute_input":"2022-05-27T16:52:10.950317Z","iopub.status.idle":"2022-05-27T16:52:10.960021Z","shell.execute_reply.started":"2022-05-27T16:52:10.950288Z","shell.execute_reply":"2022-05-27T16:52:10.959077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from skimage.segmentation import mark_boundaries\n\n\ndef diffrent_types_subplot_with_LIME(directory_path, dataset_type, subject_folder, scan_type):\n    plt.figure(figsize=(16, 6))\n    for i, scan_type in enumerate(scans_types, 1):\n        file_directory = os.path.join(directory_path, dataset_type, subject_folder, scan_type)   \n        file_name = get_middle_image(file_directory)\n        path_to_file = os.path.join(file_directory, file_name)\n        image = load_dicom(path_to_file)\n\n        explanation = explainer.explain_instance(image, best_model.predict, top_labels=2, hide_color=0, num_samples=500)\n\n        temp_2, mask_2 = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=False, num_features=10, hide_rest=False)\n\n        plt.subplot(1, len(scans_types), i)\n        plt.title(f\"{scan_type}\", fontsize=16)\n        plt.xticks([])\n        plt.yticks([])\n        plt.xlabel(file_name, fontsize=14)\n        plt.imshow(mark_boundaries(temp_2, mask_2))\n    \n    mgmt_value = check_MGMT_value(subject_folder)\n    plt.suptitle(f\"MGMT_value: {mgmt_value}\", fontsize=16);\n    plt.text(0.45, 0.88, f\"Subject: {subject_folder}\", fontsize=15, transform=plt.gcf().transFigure);\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-27T17:26:05.669649Z","iopub.execute_input":"2022-05-27T17:26:05.669968Z","iopub.status.idle":"2022-05-27T17:26:05.681142Z","shell.execute_reply.started":"2022-05-27T17:26:05.669936Z","shell.execute_reply":"2022-05-27T17:26:05.680142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"directory_path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\ndataset_type = 'train'\nsubject_folder = '00285'\nscans_types = ['FLAIR','T1w','T1wCE','T2w']\n\n\ndiffrent_types_subplot_with_LIME(directory_path, dataset_type, subject_folder, scans_types)\ndiffrent_types_subplot(directory_path, dataset_type, subject_folder, scans_types)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T17:26:08.117749Z","iopub.execute_input":"2022-05-27T17:26:08.118005Z","iopub.status.idle":"2022-05-27T17:27:46.453405Z","shell.execute_reply.started":"2022-05-27T17:26:08.117978Z","shell.execute_reply":"2022-05-27T17:27:46.452600Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# directory_path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n# dataset_type = 'train'\n# subject_folder = '00003'\n# scans_types = ['FLAIR','T1w','T1wCE','T2w']\n\n# diffrent_types_subplot(directory_path, dataset_type, subject_folder, scans_types)\n# diffrent_types_subplot_with_LIME(directory_path, dataset_type, subject_folder, scans_types)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.660464Z","iopub.execute_input":"2022-05-27T14:00:03.661366Z","iopub.status.idle":"2022-05-27T14:00:03.665606Z","shell.execute_reply.started":"2022-05-27T14:00:03.661313Z","shell.execute_reply":"2022-05-27T14:00:03.664615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def whole_scan_subplot_with_LIME(directory_path, dataset_type, subject_folder, scan_type, include_empty):\n    folder_directory = os.path.join(directory_path, dataset_type, subject_folder, scan_type)  \n    print(folder_directory)\n    images = read_scan(folder_directory,include_empty=include_empty)\n\n    print('No of images:', len(images))\n    mgmt_value = check_MGMT_value(subject_folder)\n    print('MGMT: ', mgmt_value)\n\n    fig = plt.figure(figsize=(30,10))\n\n    c = 1\n    masks= []\n    temps = []\n    for image in images:\n        explanation = explainer.explain_instance(image, best_model.predict, top_labels=2, hide_color=0, num_samples=500)\n\n        #temp_1, mask_1 = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=True, num_features=5, hide_rest=True)\n        temp_2, mask_2 = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=False, num_features=10, hide_rest=False)\n        masks.append(mask_2)\n        temps.append(temp_2)\n        \n        ax = fig.add_subplot(len(images)//10+1, 10, c)\n        \n        ax.imshow(mark_boundaries(temp_2, mask_2))\n        c+=1\n        plt.axis('off')\n        plt.suptitle(f\"Folder: {dataset_type}/{subject_folder}/{scan_type} \\nMGMT_value: {mgmt_value}\", fontsize=35);\n        fig.tight_layout()\n    return masks, temps","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.666904Z","iopub.execute_input":"2022-05-27T14:00:03.667119Z","iopub.status.idle":"2022-05-27T14:00:03.682651Z","shell.execute_reply.started":"2022-05-27T14:00:03.667092Z","shell.execute_reply":"2022-05-27T14:00:03.681624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# directory_path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n# dataset_type = 'train'\n# subject_folder = '00000'\n# scan_type = 'T1wCE'\n\n# masks, temps = whole_scan_subplot_with_LIME(directory_path, dataset_type, subject_folder, scan_type, include_empty=False)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.683924Z","iopub.execute_input":"2022-05-27T14:00:03.684631Z","iopub.status.idle":"2022-05-27T14:00:03.700487Z","shell.execute_reply.started":"2022-05-27T14:00:03.684584Z","shell.execute_reply":"2022-05-27T14:00:03.699453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_animation_LIME(masks, temps):\n    fig = plt.figure(figsize=(6, 6))\n    plt.axis('off')\n    im = plt.imshow(mark_boundaries(temps[0], masks[0]));\n\n    def animate_func(i):\n        im.set_array(temps[i])\n        return [im]\n\n    return animation.FuncAnimation(fig, animate_func, frames = len(temps), interval = 100)\n","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.702155Z","iopub.execute_input":"2022-05-27T14:00:03.702863Z","iopub.status.idle":"2022-05-27T14:00:03.714763Z","shell.execute_reply.started":"2022-05-27T14:00:03.702814Z","shell.execute_reply":"2022-05-27T14:00:03.713995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# anim = create_animation_LIME(masks, temps)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.716180Z","iopub.execute_input":"2022-05-27T14:00:03.716612Z","iopub.status.idle":"2022-05-27T14:00:03.727405Z","shell.execute_reply.started":"2022-05-27T14:00:03.716543Z","shell.execute_reply":"2022-05-27T14:00:03.726459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# anim","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.728969Z","iopub.execute_input":"2022-05-27T14:00:03.729569Z","iopub.status.idle":"2022-05-27T14:00:03.741905Z","shell.execute_reply.started":"2022-05-27T14:00:03.729505Z","shell.execute_reply":"2022-05-27T14:00:03.741147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# anim.save('im_lime_T1wCE_1.mp4')","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.743381Z","iopub.execute_input":"2022-05-27T14:00:03.743891Z","iopub.status.idle":"2022-05-27T14:00:03.756645Z","shell.execute_reply.started":"2022-05-27T14:00:03.743728Z","shell.execute_reply":"2022-05-27T14:00:03.755862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now we know why our model classifies our image as a panda! On the left image, we can see that only the super-pixels where the panda is visible are shown. This means that our model classifies our image as a panda because of these parts of super-pixels.","metadata":{}},{"cell_type":"markdown","source":"On the right image, the area of super-pixels colored in green are the ones that increase the probability of our image belongs to a panda class, while the super-pixels colored in red are the ones that decrease the probability.","metadata":{}},{"cell_type":"code","source":"# directory_path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n# dataset_type = 'train'\n# subject_folder = '00003'\n# scan_type = 'T1wCE'\n\n# masks, temps = whole_scan_subplot_with_LIME(directory_path, dataset_type, subject_folder, scan_type, include_empty=False)\n# anim = create_animation_LIME(masks, temps)\n# anim","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.758257Z","iopub.execute_input":"2022-05-27T14:00:03.758708Z","iopub.status.idle":"2022-05-27T14:00:03.770478Z","shell.execute_reply.started":"2022-05-27T14:00:03.758670Z","shell.execute_reply":"2022-05-27T14:00:03.769539Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# anim.save('im_lime_T1wCE_0.mp4')","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.771785Z","iopub.execute_input":"2022-05-27T14:00:03.772169Z","iopub.status.idle":"2022-05-27T14:00:03.789014Z","shell.execute_reply.started":"2022-05-27T14:00:03.772125Z","shell.execute_reply":"2022-05-27T14:00:03.787961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# directory_path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n# dataset_type = 'train'\n# subject_folder = '00000'\n# scan_type = 'T1w'\n\n# masks_T1w_1, temps_T1w_1 = whole_scan_subplot_with_LIME(directory_path, dataset_type, subject_folder, scan_type, include_empty=False)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.790357Z","iopub.execute_input":"2022-05-27T14:00:03.791037Z","iopub.status.idle":"2022-05-27T14:00:03.805100Z","shell.execute_reply.started":"2022-05-27T14:00:03.790995Z","shell.execute_reply":"2022-05-27T14:00:03.804263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# anim_T1w_1 = create_animation_LIME(masks_T1w_1, temps_T1w_1)\n# anim_T1w_1.save('im_lime_T1w_1.mp4')\n# anim_T1w_1","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.806383Z","iopub.execute_input":"2022-05-27T14:00:03.806752Z","iopub.status.idle":"2022-05-27T14:00:03.818504Z","shell.execute_reply.started":"2022-05-27T14:00:03.806720Z","shell.execute_reply":"2022-05-27T14:00:03.817621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# directory_path = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n# dataset_type = 'train'\n# subject_folder = '00003'\n# scan_type = 'T1w'\n\n# masks_T1w_0, temps_T1w_0 = whole_scan_subplot_with_LIME(directory_path, dataset_type, subject_folder, scan_type, include_empty=False)","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.819854Z","iopub.execute_input":"2022-05-27T14:00:03.820603Z","iopub.status.idle":"2022-05-27T14:00:03.830757Z","shell.execute_reply.started":"2022-05-27T14:00:03.820537Z","shell.execute_reply":"2022-05-27T14:00:03.829839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# anim_T1w_0 = create_animation_LIME(masks_T1w_0, temps_T1w_0)\n# anim_T1w_0.save('im_lime_T1w_0.mp4')\n# anim_T1w_0","metadata":{"execution":{"iopub.status.busy":"2022-05-27T14:00:03.831873Z","iopub.execute_input":"2022-05-27T14:00:03.832746Z","iopub.status.idle":"2022-05-27T14:00:03.844426Z","shell.execute_reply.started":"2022-05-27T14:00:03.832702Z","shell.execute_reply":"2022-05-27T14:00:03.843486Z"},"trusted":true},"execution_count":null,"outputs":[]}]}