{"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 pandas as pd\nimport seaborn as sns\nimport json\nimport ast\nimport glob\nfrom tqdm import tqdm\nimport gc\n\nimport  matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n\nimport pydicom\nimport cv2\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:00:39.340660Z","iopub.execute_input":"2021-10-13T05:00:39.340986Z","iopub.status.idle":"2021-10-13T05:00:40.273908Z","shell.execute_reply.started":"2021-10-13T05:00:39.340906Z","shell.execute_reply":"2021-10-13T05:00:40.273134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Seed for reproducability\nimport numpy as np\nimport random\nseed = 1234\nnp.random.seed(seed)","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:00:40.645011Z","iopub.execute_input":"2021-10-13T05:00:40.645732Z","iopub.status.idle":"2021-10-13T05:00:40.651072Z","shell.execute_reply.started":"2021-10-13T05:00:40.645696Z","shell.execute_reply":"2021-10-13T05:00:40.649176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom sklearn.metrics import roc_auc_score\n\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.utils import to_categorical","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:00:41.580078Z","iopub.execute_input":"2021-10-13T05:00:41.581153Z","iopub.status.idle":"2021-10-13T05:00:45.867964Z","shell.execute_reply.started":"2021-10-13T05:00:41.581083Z","shell.execute_reply":"2021-10-13T05:00:45.867236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_dir = \"../input/rsna-miccai-brain-tumor-radiogenomic-classification\"\nmri_types = [\"FLAIR\",\"T1w\",\"T2w\",\"T1wCE\"]","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:00:45.871307Z","iopub.execute_input":"2021-10-13T05:00:45.871514Z","iopub.status.idle":"2021-10-13T05:00:45.877560Z","shell.execute_reply.started":"2021-10-13T05:00:45.871491Z","shell.execute_reply":"2021-10-13T05:00:45.876840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv('../input/rsna-miccai-brain-tumor-radiogenomic-classification/train_labels.csv')\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:00:45.880262Z","iopub.execute_input":"2021-10-13T05:00:45.880458Z","iopub.status.idle":"2021-10-13T05:00:45.910540Z","shell.execute_reply.started":"2021-10-13T05:00:45.880436Z","shell.execute_reply":"2021-10-13T05:00:45.909950Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.read_csv('../input/rsna-miccai-brain-tumor-radiogenomic-classification/sample_submission.csv')\n\nprint(f\"train data: Rows={train_df.shape[0]}, Columns={train_df.shape[1]}\")","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:00:45.912011Z","iopub.execute_input":"2021-10-13T05:00:45.912295Z","iopub.status.idle":"2021-10-13T05:00:45.922060Z","shell.execute_reply.started":"2021-10-13T05:00:45.912250Z","shell.execute_reply":"2021-10-13T05:00:45.921089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_dicom(path, size = 224):\n    dicom = pydicom.read_file(path)\n    data = dicom.pixel_array\n    if np.max(data) != 0:\n        data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    return cv2.resize(data, (size, size))","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:00:48.090384Z","iopub.execute_input":"2021-10-13T05:00:48.090943Z","iopub.status.idle":"2021-10-13T05:00:48.096384Z","shell.execute_reply.started":"2021-10-13T05:00:48.090906Z","shell.execute_reply":"2021-10-13T05:00:48.095365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_all_image_paths(brats21id, image_type, folder='train'): \n    assert(image_type in mri_types)\n    \n    patient_path = os.path.join(\n        \"../input/rsna-miccai-brain-tumor-radiogenomic-classification/%s/\" % folder, \n        str(brats21id).zfill(5),\n    )\n\n    paths = sorted(\n        glob.glob(os.path.join(patient_path, image_type, \"*\")), \n        key=lambda x: int(x[:-4].split(\"-\")[-1]),\n    )\n    \n    num_images = len(paths)\n    \n    start = int(num_images * 0.25)\n    end = int(num_images * 0.75)\n\n    interval = 3\n    \n    if num_images < 10: \n        interval = 1\n    \n    return np.array(paths[start:end:interval])\n\ndef get_all_images(brats21id, image_type, folder='train', size=225):\n    return [load_dicom(path, size) for path in get_all_image_paths(brats21id, image_type, folder)]","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:00:48.500143Z","iopub.execute_input":"2021-10-13T05:00:48.500933Z","iopub.status.idle":"2021-10-13T05:00:48.512898Z","shell.execute_reply.started":"2021-10-13T05:00:48.500888Z","shell.execute_reply":"2021-10-13T05:00:48.511966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_all_data_for_train(image_type, image_size=32):\n    global train_df\n    \n    X = []\n    y = []\n    train_ids = []\n\n    for i in tqdm(train_df.index):\n        x = train_df.loc[i]\n        images = get_all_images(int(x['BraTS21ID']), image_type, 'train', image_size)\n        label = x['MGMT_value']\n\n        X += images\n        y += [label] * len(images)\n        train_ids += [int(x['BraTS21ID'])] * len(images)\n        assert(len(X) == len(y))\n    return np.array(X), np.array(y), np.array(train_ids)","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:00:48.864804Z","iopub.execute_input":"2021-10-13T05:00:48.865067Z","iopub.status.idle":"2021-10-13T05:00:48.871713Z","shell.execute_reply.started":"2021-10-13T05:00:48.865031Z","shell.execute_reply":"2021-10-13T05:00:48.870896Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_all_data_for_test(image_type, image_size=32):\n    global test_df\n    \n    X = []\n    test_ids = []\n\n    for i in tqdm(test_df.index):\n        x = test_df.loc[i]\n        images = get_all_images(int(x['BraTS21ID']), image_type, 'test', image_size)\n        X += images\n        test_ids += [int(x['BraTS21ID'])] * len(images)\n\n    return np.array(X), np.array(test_ids)","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:00:49.359625Z","iopub.execute_input":"2021-10-13T05:00:49.359882Z","iopub.status.idle":"2021-10-13T05:00:49.366070Z","shell.execute_reply.started":"2021-10-13T05:00:49.359854Z","shell.execute_reply":"2021-10-13T05:00:49.365166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X, y, trainidt = get_all_data_for_train('FLAIR', image_size=224)\nX_test, testidt = get_all_data_for_test('FLAIR', image_size=224)","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:00:49.859681Z","iopub.execute_input":"2021-10-13T05:00:49.859935Z","iopub.status.idle":"2021-10-13T05:02:56.950483Z","shell.execute_reply.started":"2021-10-13T05:00:49.859907Z","shell.execute_reply":"2021-10-13T05:02:56.949679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X.shape, y.shape, trainidt.shape","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:02:56.952298Z","iopub.execute_input":"2021-10-13T05:02:56.952586Z","iopub.status.idle":"2021-10-13T05:02:56.958350Z","shell.execute_reply.started":"2021-10-13T05:02:56.952551Z","shell.execute_reply":"2021-10-13T05:02:56.957639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train, X_valid, y_train, y_valid, trainidt_train, trainidt_valid = train_test_split(X, y, trainidt, test_size=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:02:56.959562Z","iopub.execute_input":"2021-10-13T05:02:56.959960Z","iopub.status.idle":"2021-10-13T05:02:57.142719Z","shell.execute_reply.started":"2021-10-13T05:02:56.959921Z","shell.execute_reply":"2021-10-13T05:02:57.141986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train = tf.expand_dims(X_train, axis=-1)\nX_valid = tf.expand_dims(X_valid, axis=-1)","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:02:57.145311Z","iopub.execute_input":"2021-10-13T05:02:57.145577Z","iopub.status.idle":"2021-10-13T05:02:59.540681Z","shell.execute_reply.started":"2021-10-13T05:02:57.145543Z","shell.execute_reply":"2021-10-13T05:02:59.539918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_train = to_categorical(y_train)\ny_valid = to_categorical(y_valid)","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:02:59.542186Z","iopub.execute_input":"2021-10-13T05:02:59.542420Z","iopub.status.idle":"2021-10-13T05:02:59.548241Z","shell.execute_reply.started":"2021-10-13T05:02:59.542388Z","shell.execute_reply":"2021-10-13T05:02:59.547491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model03():\n    np.random.seed(0)\n    random.seed(12)\n    tf.random.set_seed(12)\n\n    inpt = keras.Input(shape=X_train.shape[1:])\n\n    h = keras.layers.experimental.preprocessing.Rescaling(1.0 / 255)(inpt)\n\n    h = keras.layers.Conv2D(32, kernel_size=(3, 3), activation=\"relu\", name=\"Conv_1\")(h)\n    h = keras.layers.MaxPool2D(pool_size=(2, 2))(h)\n\n    h = keras.layers.Conv2D(64, kernel_size=(3, 3), activation=\"relu\", name=\"Conv_3\",)(h)\n    h = keras.layers.MaxPool2D(pool_size=(2, 2))(h)\n    \n    h = keras.layers.Conv2D(128, kernel_size=(3, 3), activation=\"relu\", name=\"Conv_5\")(h)\n    h = keras.layers.MaxPool2D(pool_size=(2, 2))(h)\n    \n\n    \n    h = keras.layers.Flatten()(h)\n    h = keras.layers.Dropout(0.1)(h)\n    h = keras.layers.Dense(512, activation=\"relu\",kernel_initializer = tf.keras.initializers.HeNormal())(h)\n    h = keras.layers.Dropout(0.1)(h)\n    \n    output = keras.layers.Dense(2, activation=\"softmax\",kernel_initializer = tf.keras.initializers.HeNormal())(h)\n    model = keras.Model(inpt, output)\n\n    # https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/schedules/ExponentialDecay\n    \n    initial_learning_rate =  0.0001\n    lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(\n        initial_learning_rate,\n        decay_steps=100000,\n        decay_rate=0.96, \n        staircase=True\n    )\n  \n    roc_auc = tf.keras.metrics.AUC(name='roc_auc', curve='ROC')\n    accuracy  = tf.keras.metrics.Accuracy(name = \"accuracy\")\n    model.compile(\n        loss=\"categorical_crossentropy\", \n        optimizer=keras.optimizers.Adam(learning_rate=0.0001),\n        metrics=[roc_auc,accuracy],\n    )\n    return model","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:47:05.902279Z","iopub.execute_input":"2021-10-13T05:47:05.902853Z","iopub.status.idle":"2021-10-13T05:47:05.915273Z","shell.execute_reply.started":"2021-10-13T05:47:05.902816Z","shell.execute_reply":"2021-10-13T05:47:05.914564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint_filepath = \"best_model.h5\"\n\nmodel_checkpoint_cb = tf.keras.callbacks.ModelCheckpoint(\n    filepath=checkpoint_filepath,\n    save_weights_only=False,\n    monitor=\"val_roc_auc\",\n    mode=\"max\",\n    save_best_only=True,\n    save_freq=\"epoch\",\n    verbose=1,\n)\nearly_stopping_cb = tf.keras.callbacks.EarlyStopping(monitor=\"val_accuracy\", mode='max', patience=3)","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:47:06.261672Z","iopub.execute_input":"2021-10-13T05:47:06.262222Z","iopub.status.idle":"2021-10-13T05:47:06.267264Z","shell.execute_reply.started":"2021-10-13T05:47:06.262188Z","shell.execute_reply":"2021-10-13T05:47:06.266545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# roc_auc = tf.keras.metrics.AUC(name='roc_auc', curve='ROC')\n# accuracy  = tf.keras.metrics.Accuracy(name = \"accuracy\")\n# model.compile(optimizer=\"adam\", loss=\"binary_crossentropy\", metrics=[accuracy,roc_auc])","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:47:06.651049Z","iopub.execute_input":"2021-10-13T05:47:06.651590Z","iopub.status.idle":"2021-10-13T05:47:06.655005Z","shell.execute_reply.started":"2021-10-13T05:47:06.651557Z","shell.execute_reply":"2021-10-13T05:47:06.654199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model = get_model02() # LB score 0.676\nmodel = get_model03() # LB score 0.5\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:47:07.010959Z","iopub.execute_input":"2021-10-13T05:47:07.011196Z","iopub.status.idle":"2021-10-13T05:47:07.101215Z","shell.execute_reply.started":"2021-10-13T05:47:07.011171Z","shell.execute_reply":"2021-10-13T05:47:07.100031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(x=X_train, y = y_train, epochs=100, \n                    callbacks=[model_checkpoint_cb],\n                    validation_data=(X_valid, y_valid))","metadata":{"execution":{"iopub.status.busy":"2021-10-13T05:47:07.371586Z","iopub.execute_input":"2021-10-13T05:47:07.371829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_best = tf.keras.models.load_model(filepath=checkpoint_filepath)","metadata":{"execution":{"iopub.status.busy":"2021-10-11T07:16:54.357405Z","iopub.execute_input":"2021-10-11T07:16:54.357613Z","iopub.status.idle":"2021-10-11T07:16:55.636371Z","shell.execute_reply.started":"2021-10-11T07:16:54.357589Z","shell.execute_reply":"2021-10-11T07:16:55.635622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model_best.predict(X_valid)\n\npred = np.argmax(y_pred, axis=1)\n\nresult = pd.DataFrame(trainidt_valid)\nresult[1] = pred\n\nresult.columns = [\"BraTS21ID\", \"MGMT_value\"]\nresult2 = result.groupby(\"BraTS21ID\", as_index=False).mean()\n\nresult2 = result2.merge(train_df, on=\"BraTS21ID\")\nauc = roc_auc_score(\n    result2.MGMT_value_y,\n    result2.MGMT_value_x,\n)\nprint(f\"Validation AUC={auc}\")","metadata":{"execution":{"iopub.status.busy":"2021-10-11T07:16:55.637927Z","iopub.execute_input":"2021-10-11T07:16:55.638171Z","iopub.status.idle":"2021-10-11T07:16:56.528697Z","shell.execute_reply.started":"2021-10-11T07:16:55.638139Z","shell.execute_reply":"2021-10-11T07:16:56.528001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model_best.predict(X_test)\n\npred = np.argmax(y_pred, axis=1) #\n\nresult = pd.DataFrame(testidt)\nresult[1] = pred\npred","metadata":{"execution":{"iopub.status.busy":"2021-10-11T07:16:59.632601Z","iopub.execute_input":"2021-10-11T07:16:59.632849Z","iopub.status.idle":"2021-10-11T07:17:00.38916Z","shell.execute_reply.started":"2021-10-11T07:16:59.632822Z","shell.execute_reply":"2021-10-11T07:17:00.388469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission = pd.read_csv('../input/rsna-miccai-brain-tumor-radiogenomic-classification/sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2021-10-11T07:17:01.756315Z","iopub.execute_input":"2021-10-11T07:17:01.756574Z","iopub.status.idle":"2021-10-11T07:17:01.7688Z","shell.execute_reply.started":"2021-10-11T07:17:01.756547Z","shell.execute_reply":"2021-10-11T07:17:01.767998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result.columns=['BraTS21ID','MGMT_value']\n\nresult2 = result.groupby('BraTS21ID',as_index=False).mean()\nresult2['BraTS21ID'] = sample_submission['BraTS21ID']\n\n# Rounding... 0.907866 -> 0.9\nresult2['MGMT_value'] = result2['MGMT_value'].apply(lambda x:round(x*10)/10)\n# result2['MGMT_value'] = result2['MGMT_value'] # No rounding\nresult2.to_csv('submission.csv',index=False)\nresult2","metadata":{"execution":{"iopub.status.busy":"2021-10-11T07:17:03.137244Z","iopub.execute_input":"2021-10-11T07:17:03.137863Z","iopub.status.idle":"2021-10-11T07:17:03.160191Z","shell.execute_reply.started":"2021-10-11T07:17:03.137825Z","shell.execute_reply":"2021-10-11T07:17:03.159534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}