{"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 glob\nimport random\nimport re\nimport time\nimport math\nimport numpy as np\nimport pandas as pd\nimport cv2\n\nimport matplotlib.pyplot as plt\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\n\nfrom random import shuffle\n\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau\nfrom tensorflow.keras.metrics import AUC\n\nimport tensorflow as tf","metadata":{"execution":{"iopub.status.busy":"2021-10-22T05:02:41.159839Z","iopub.execute_input":"2021-10-22T05:02:41.160305Z","iopub.status.idle":"2021-10-22T05:02:46.767966Z","shell.execute_reply.started":"2021-10-22T05:02:41.160212Z","shell.execute_reply":"2021-10-22T05:02:46.767054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_directory = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\n \nmri_types = 'FLAIR'\nIMAGE_SIZE = 124\nNUM_IMAGES = 64\nBATCH_SIZE= 4\n\nnum_folds=5\nSelected_fold=1 \n\ntrain_df = pd.read_csv(\"../input/rsna-miccai-brain-tumor-radiogenomic-classification/train_labels.csv\")\ntrain_df['BraTS21ID5'] = [format(x, '05d') for x in train_df.BraTS21ID]\ntrain_df[\"Fold\"]=\"train\"\nprint(sum(np.array(train_df.MGMT_value)))\nprint(len(np.array(train_df.MGMT_value)) - sum(np.array(train_df.MGMT_value)))","metadata":{"execution":{"iopub.status.busy":"2021-10-22T05:02:59.679232Z","iopub.execute_input":"2021-10-22T05:02:59.67952Z","iopub.status.idle":"2021-10-22T05:02:59.709165Z","shell.execute_reply.started":"2021-10-22T05:02:59.679492Z","shell.execute_reply":"2021-10-22T05:02:59.708188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_dicom_image(path, img_size=IMAGE_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\nimg = pydicom.read_file('../input/rsna-miccai-brain-tumor-radiogenomic-classification/train/00000/FLAIR/Image-108.dcm')\nimg = img.pixel_array\nfig, ax = plt.subplots()\nax.imshow(img, cmap=\"gray\")\nax.set_axis_off()\nplt.show()\n\nsample_img = load_dicom_image('../input/rsna-miccai-brain-tumor-radiogenomic-classification/train/00000/FLAIR/Image-108.dcm')\n\nfig, ax = plt.subplots()\nax.imshow(sample_img, cmap=\"gray\")\nax.set_axis_off()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-10-22T05:03:40.367263Z","iopub.execute_input":"2021-10-22T05:03:40.367707Z","iopub.status.idle":"2021-10-22T05:03:40.744165Z","shell.execute_reply.started":"2021-10-22T05:03:40.367671Z","shell.execute_reply":"2021-10-22T05:03:40.742968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_dicom_images_3d(scan_id, num_imgs=NUM_IMAGES, img_size=IMAGE_SIZE, mri_type=mri_types, 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    files2 = sorted(glob.glob(f\"{data_directory}/{split}/{scan_id}/T2w/*.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    files3 = sorted(glob.glob(f\"{data_directory}/{split}/{scan_id}/T1wCE/*.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    #FLAIR\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    \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        \n    #T2W\n    middle = len(files2)//2\n    num_imgs2 = num_imgs//2\n    p1 = max(0, middle - num_imgs2)\n    p2 = min(len(files2), middle + num_imgs2)\n    img3d2 = np.stack([load_dicom_image(f, rotate=rotate) for f in files2[p1:p2]]).T \n    \n    if img3d2.shape[-1] < num_imgs:\n        n_zero = np.zeros((img_size, img_size, num_imgs - img3d2.shape[-1]))\n        img3d2 = np.concatenate((img3d2,  n_zero), axis = -1)\n        \n    if np.min(img3d2) < np.max(img3d2):\n        img3d2 = img3d2 - np.min(img3d2)\n        img3d2 = img3d2 / np.max(img3d2)\n        \n        \n    #T1wCE\n    middle = len(files3)//2\n    num_imgs2 = num_imgs//2\n    p1 = max(0, middle - num_imgs2)\n    p2 = min(len(files3), middle + num_imgs2)\n    img3d3 = np.stack([load_dicom_image(f, rotate=rotate) for f in files3[p1:p2]]).T \n    \n    if img3d3.shape[-1] < num_imgs:\n        n_zero = np.zeros((img_size, img_size, num_imgs - img3d3.shape[-1]))\n        img3d3 = np.concatenate((img3d3,  n_zero), axis = -1)\n        \n    if np.min(img3d3) < np.max(img3d3):\n        img3d3 = img3d2 - np.min(img3d3)\n        img3d3 = img3d2 / np.max(img3d3)\n        \n        \n            \n    return np.stack((img3d, img3d2, img3d3), 3)\n\na = load_dicom_images_3d(\"00107\")\nprint(a.shape)\n\n","metadata":{"execution":{"iopub.status.busy":"2021-10-22T05:07:58.28917Z","iopub.execute_input":"2021-10-22T05:07:58.290046Z","iopub.status.idle":"2021-10-22T05:07:58.84568Z","shell.execute_reply.started":"2021-10-22T05:07:58.290008Z","shell.execute_reply":"2021-10-22T05:07:58.844682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import KFold,StratifiedKFold\nsfolder = StratifiedKFold(n_splits=5,random_state=13,shuffle=True)\nX = train_df[['BraTS21ID']]\ny = train_df[['MGMT_value']]\n\nfold_no = 1\nfor train, valid in sfolder.split(X,y):\n    if fold_no==Selected_fold:\n        train_df.loc[valid, \"Fold\"] = \"valid\"\n    fold_no += 1","metadata":{"execution":{"iopub.status.busy":"2021-10-22T01:20:38.413425Z","iopub.execute_input":"2021-10-22T01:20:38.413847Z","iopub.status.idle":"2021-10-22T01:20:39.059362Z","shell.execute_reply.started":"2021-10-22T01:20:38.413814Z","shell.execute_reply":"2021-10-22T01:20:39.058626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train=train_df[train_df.Fold==\"train\"]\ndf_valid=train_df[train_df.Fold==\"valid\"]\nprint(\"df_train=\",len(df_train),\"-- df_valid=\",len(df_valid))","metadata":{"execution":{"iopub.status.busy":"2021-10-22T01:34:34.740241Z","iopub.execute_input":"2021-10-22T01:34:34.740494Z","iopub.status.idle":"2021-10-22T01:34:34.749031Z","shell.execute_reply.started":"2021-10-22T01:34:34.740468Z","shell.execute_reply":"2021-10-22T01:34:34.748154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.utils import Sequence\nclass Dataset(Sequence):\n    def __init__(self,df,is_train=True,batch_size=BATCH_SIZE,shuffle=True):\n        self.idx = df[\"BraTS21ID\"].values\n        self.paths = df[\"BraTS21ID5\"].values\n        self.y =  df[\"MGMT_value\"].values\n        self.is_train = is_train\n        self.batch_size = batch_size\n        self.shuffle = shuffle\n    def __len__(self):\n        return math.ceil(len(self.idx)/self.batch_size)\n   \n    def __getitem__(self,ids):\n        id_path= self.paths[ids]\n        batch_paths = self.paths[ids * self.batch_size:(ids + 1) * self.batch_size]\n        \n        if self.y is not None:\n            batch_y = self.y[ids * self.batch_size: (ids + 1) * self.batch_size]\n        \n        if self.is_train:\n            list_x =  [load_dicom_images_3d(x,split=\"train\") for x in batch_paths]\n            batch_X = np.stack(list_x)\n            return batch_X,batch_y\n        else:\n            list_x =  load_dicom_images_3d(id_path,split=\"test\")#str(scan_id).zfill(5)\n            batch_X = np.expand_dims(list_x, axis=0)\n            return batch_X\n    \n    def on_epoch_end(self):\n        if self.shuffle and self.is_train:\n            ids_y = list(zip(self.idx, self.y))\n            shuffle(ids_y)\n            self.idx, self.y = list(zip(*ids_y))","metadata":{"execution":{"iopub.status.busy":"2021-10-22T01:42:34.231135Z","iopub.execute_input":"2021-10-22T01:42:34.231412Z","iopub.status.idle":"2021-10-22T01:42:34.242263Z","shell.execute_reply.started":"2021-10-22T01:42:34.231384Z","shell.execute_reply":"2021-10-22T01:42:34.241548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = Dataset(df_train,batch_size=BATCH_SIZE)\nvalid_dataset = Dataset(df_valid,batch_size=BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2021-10-22T01:41:33.342161Z","iopub.execute_input":"2021-10-22T01:41:33.342421Z","iopub.status.idle":"2021-10-22T01:41:33.347028Z","shell.execute_reply.started":"2021-10-22T01:41:33.342394Z","shell.execute_reply":"2021-10-22T01:41:33.346141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(1):\n    images, label = train_dataset[i]\n    print(\"Dimension of the CT scan is:\", images.shape)\n    ","metadata":{"execution":{"iopub.status.busy":"2021-10-22T01:41:35.870883Z","iopub.execute_input":"2021-10-22T01:41:35.871576Z","iopub.status.idle":"2021-10-22T01:41:42.128512Z","shell.execute_reply.started":"2021-10-22T01:41:35.871541Z","shell.execute_reply":"2021-10-22T01:41:42.127737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model(width=IMAGE_SIZE, height=IMAGE_SIZE, depth=64):\n    \"\"\"Build a 3D convolutional neural network model.\"\"\"\n\n    inputs = keras.Input((width, height, depth, 3))\n     \n    x = layers.Conv3D(filters=32, kernel_size=3, activation=\"relu\")(inputs)\n    x = layers.MaxPool3D(pool_size=2)(x)\n    x = layers.BatchNormalization()(x)\n    \n    x = layers.Conv3D(filters=32, kernel_size=3, activation=\"relu\")(inputs)\n    x = layers.MaxPool3D(pool_size=2)(x)\n    x = layers.BatchNormalization()(x)\n    \n    x = layers.Conv3D(filters=64, kernel_size=3, activation=\"relu\")(inputs)\n    x = layers.MaxPool3D(pool_size=2)(x)\n    x = layers.BatchNormalization()(x)\n    x = layers.Dropout(0.01)(x)\n    \n    x = layers.Conv3D(filters=128, kernel_size=3, activation=\"relu\")(x)\n    x = layers.MaxPool3D(pool_size=2)(x)\n    x = layers.BatchNormalization()(x)\n    x = layers.Dropout(0.02)(x)\n\n    x = layers.Conv3D(filters=256, kernel_size=3, activation=\"relu\")(x)\n    x = layers.MaxPool3D(pool_size=2)(x)\n    x = layers.BatchNormalization()(x)\n    x = layers.Dropout(0.03)(x)\n\n    x = layers.Conv3D(filters=512, kernel_size=3, activation=\"relu\")(x)\n    x = layers.MaxPool3D(pool_size=2)(x)\n    x = layers.BatchNormalization()(x)\n    x = layers.Dropout(0.04)(x)\n\n    x = layers.GlobalAveragePooling3D()(x)\n    x = layers.Dense(units=1024, activation=\"relu\")(x)\n    x = layers.Dropout(0.08)(x)\n\n    outputs = layers.Dense(units=1, activation=\"sigmoid\")(x)\n\n    # Define the model.\n    model = keras.Model(inputs, outputs, name=\"3dcnn\")\n\n    return model\n\n# Build model.\nmodel = get_model(width=IMAGE_SIZE, height=IMAGE_SIZE, depth=64)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-10-22T01:42:51.571448Z","iopub.execute_input":"2021-10-22T01:42:51.571741Z","iopub.status.idle":"2021-10-22T01:42:54.036775Z","shell.execute_reply.started":"2021-10-22T01:42:51.571714Z","shell.execute_reply":"2021-10-22T01:42:54.036046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Compile model.\ninitial_learning_rate = 0.0001\nlr_schedule = keras.optimizers.schedules.ExponentialDecay(\n    initial_learning_rate, decay_steps=100000, decay_rate=0.96, staircase=True\n)\nmodel.compile(\n    loss=\"binary_crossentropy\",\n    optimizer=keras.optimizers.Adam(learning_rate=lr_schedule),\n    metrics=[AUC(name='auc'),\"acc\"],\n)\n# Define callbacks.\nmodel_save = ModelCheckpoint(f'Brain_3d_cls_{mri_types}_Fold_{Selected_fold}.h5', \n                             save_best_only = True, \n                             monitor = 'val_auc', \n                             mode = 'max', verbose = 1)\nearly_stop = EarlyStopping(monitor = 'val_auc', \n                           patience = 10, mode = 'max', verbose = 1,\n                           restore_best_weights = True)\n\n# Train the model, doing validation at the end of each epoch\nepochs = 50\nmodel.fit(\n    train_dataset,\n    validation_data=valid_dataset,\n    epochs=epochs,\n    shuffle=True,\n    verbose=1,\n    callbacks = [model_save, early_stop],\n)","metadata":{"execution":{"iopub.status.busy":"2021-10-21T15:00:51.231117Z","iopub.execute_input":"2021-10-21T15:00:51.231808Z","iopub.status.idle":"2021-10-21T15:10:56.901208Z","shell.execute_reply.started":"2021-10-21T15:00:51.231768Z","shell.execute_reply":"2021-10-21T15:10:56.882561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.read_csv('../input/rsna-miccai-brain-tumor-radiogenomic-classification/sample_submission.csv')\ntest['BraTS21ID5'] = [format(x, '05d') for x in test.BraTS21ID]\ntest\n\n","metadata":{"execution":{"iopub.status.busy":"2021-10-22T05:08:15.051142Z","iopub.execute_input":"2021-10-22T05:08:15.05166Z","iopub.status.idle":"2021-10-22T05:08:15.084479Z","shell.execute_reply.started":"2021-10-22T05:08:15.051627Z","shell.execute_reply":"2021-10-22T05:08:15.083512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_set =  Dataset(test,is_train=False,batch_size=1)\nfor i in range(1):\n    images = test_set[i]\n    print(\"Dimension of the CT scan is:\", images.shape)","metadata":{"execution":{"iopub.status.busy":"2021-10-22T05:08:17.970779Z","iopub.execute_input":"2021-10-22T05:08:17.971574Z","iopub.status.idle":"2021-10-22T05:08:18.32813Z","shell.execute_reply.started":"2021-10-22T05:08:17.971529Z","shell.execute_reply":"2021-10-22T05:08:18.326575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset = Dataset(test,is_train=False,batch_size=1)\npredict = model.predict(test_dataset)\npredict = predict.reshape(-1)\npredict","metadata":{"execution":{"iopub.status.busy":"2021-10-22T01:43:10.24259Z","iopub.execute_input":"2021-10-22T01:43:10.24324Z","iopub.status.idle":"2021-10-22T01:44:50.653727Z","shell.execute_reply.started":"2021-10-22T01:43:10.243205Z","shell.execute_reply":"2021-10-22T01:44:50.652915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame({'BraTS21ID':test['BraTS21ID'],'MGMT_value':predict})\nsubmission","metadata":{"execution":{"iopub.status.busy":"2021-10-22T01:45:32.771746Z","iopub.execute_input":"2021-10-22T01:45:32.772004Z","iopub.status.idle":"2021-10-22T01:45:32.79033Z","shell.execute_reply.started":"2021-10-22T01:45:32.77198Z","shell.execute_reply":"2021-10-22T01:45:32.789631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv('submission.csv',index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}