{"cells":[{"metadata":{},"cell_type":"markdown","source":"# RSNA Intracranial Hemorrhage Detection\n### Identify acute intracranial hemorrhage and its subtypes\n\n<u>**Intracranial hemorrhage**</u> \n\nIntracranial hemorrhage,bleeding that occurs inside the cranium, is a serious health problem requiring rapid and often intensive medical treatment. For example, intracranial hemorrhages account for approximately 10% of strokes in the U.S., where stroke is the fifth-leading cause of death. Identifying the location and type of any hemorrhage present is a critical step in treating the patient.\n\n<u>**Diagnosis**</u> \n\nDiagnosis requires an urgent procedure. When a patient shows acute neurological symptoms such as severe headache or loss of consciousness, highly trained specialists review medical images of the patient’s cranium to look for the presence, location and type of hemorrhage. The process is complicated and often time consuming.\n\n<u>**Challenge**</u> \n\nBuilding an algorithm to detect acute intracranial hemorrhage and its subtypes."},{"metadata":{},"cell_type":"markdown","source":"# Contents of Notebooks\n1. Introduction\n2. Exploratory data analysis\n3. Visualization\n4. Model\n5. Submission"},{"metadata":{},"cell_type":"markdown","source":"# 1.Introduction\n\n**Hemorrhage types**\n\nHemorrhage in the head (intracranial hemorrhage) is a relatively common condition that has many causes ranging from trauma, stroke, aneurysm, vascular malformations, high blood pressure, illicit drugs and blood clotting disorders. The neurologic consequences also vary extensively depending upon the size, type of hemorrhage and location ranging from headache to death. The role of the Radiologist is to detect the hemorrhage, characterize the hemorrhage subtype, its size and to determine if the hemorrhage might be jeopardizing critical areas of the brain that might require immediate surgery.\n\nWhile all acute (i.e. new) hemorrhages appear dense (i.e. white) on computed tomography (CT), the primary imaging features that help Radiologists determine the subtype of hemorrhage are the location, shape and proximity to other structures (see table).\n\nIntraparenchymal hemorrhage is blood that is located completely within the brain itself; intraventricular or subarachnoid hemorrhage is blood that has leaked into the spaces of the brain that normally contain cerebrospinal fluid (the ventricles or subarachnoid cisterns). Extra-axial hemorrhages are blood that collects in the tissue coverings that surround the brain (e.g. subdural or epidural subtypes). ee figure.) Patients may exhibit more than one type of cerebral hemorrhage, which c may appear on the same image. While small hemorrhages are less morbid than large hemorrhages typically, even a small hemorrhage can lead to death because it is an indicator of another type of serious abnormality (e.g. cerebral aneurysm)."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport pydicom\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport json\nimport cv2\nfrom keras import layers\nfrom keras.applications import DenseNet121\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import Callback, ModelCheckpoint\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential\nfrom keras.optimizers import Adam\nfrom tqdm import tqdm\nprint (\"Complete Loding in the Libraries.\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"#Load in the train and sub data\ntrain = pd.read_csv(\"../input/rsna-intracranial-hemorrhage-detection/stage_1_train.csv\")\nsub = pd.read_csv(\"../input/rsna-intracranial-hemorrhage-detection/stage_1_sample_submission.csv\")\ntrain_images = os.listdir(\"../input/rsna-intracranial-hemorrhage-detection/stage_1_train_images/\")\ntest_images = os.listdir(\"../input/rsna-intracranial-hemorrhage-detection/stage_1_test_images/\")\nprint(\"Train_row:\", train.shape[0])\nprint(\"Train_col:\", train.shape[1])\nprint(\"Sub_row:\", sub.shape[0])\nprint(\"Sub_col:\", sub.shape[1])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 2.Exploratory data analysis"},{"metadata":{"_kg_hide-input":false,"trusted":true},"cell_type":"code","source":"train.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The training data is provided as a set of image Ids and multiple labels, one for each of five sub-types of hemorrhage, plus an additional label for any, which should always be true if any of the sub-type labels is true.\n\nThere is also a target column, Label, indicating the probability of whether that type of hemorrhage exists in the indicated image.\n\nThere will be 6 rows per image Id. The label indicated by a particular row will look like [Image Id]_[Sub-type Name]"},{"metadata":{"trusted":true},"cell_type":"code","source":"train[\"type\"] = train[\"ID\"].str.split(\"_\", n = 3, expand = True)[2]\ntrain[\"PatientID\"] = train[\"ID\"].str.split(\"_\", n = 3, expand = True)[1]\ntrain[\"filename\"] = train[\"ID\"].apply(lambda st: \"ID_\" + st.split('_')[1] + \".png\")\n\nsub[\"filename\"] = sub[\"ID\"].apply(lambda st: \"ID_\" + st.split('_')[1] + \".png\")\nsub[\"type\"] = sub[\"ID\"].apply(lambda st: st.split('_')[2])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Labels**\nLabels show this is imbalanced data."},{"metadata":{"trusted":true},"cell_type":"code","source":"print(train.Label.value_counts())\nsns.set_palette(\"winter_r\", 7, 0.5)\nsns.countplot(x='Label', data=train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.countplot(x=\"Label\", hue=\"type\", data=train)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3. Visualization\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"TRAIN_IMG_PATH = \"../input/rsna-intracranial-hemorrhage-detection/stage_1_train_images/\"\nTEST_IMG_PATH = \"../input/rsna-intracranial-hemorrhage-detection/stage_1_test_images/\"\nBASE_PATH = '/kaggle/input/rsna-intracranial-hemorrhage-detection/'\nTRAIN_DIR = 'stage_1_train_images/'\nTEST_DIR = 'stage_1_test_images/'\n\ndef window_image(img, window_center,window_width, intercept, slope, rescale=True):\n\n    img = (img*slope +intercept)\n    img_min = window_center - window_width//2\n    img_max = window_center + window_width//2\n    img[img<img_min] = img_min\n    img[img>img_max] = img_max\n    \n    if rescale:\n        # Extra rescaling to 0-1, not in the original notebook\n        img = (img - img_min) / (img_max - img_min)\n    \n    return img\n    \ndef get_first_of_dicom_field_as_int(x):\n    #get x[0] as in int is x is a 'pydicom.multival.MultiValue', otherwise get int(x)\n    if type(x) == pydicom.multival.MultiValue:\n        return int(x[0])\n    else:\n        return int(x)\n\ndef get_windowing(data):\n    dicom_fields = [data[('0028','1050')].value, #window center\n                    data[('0028','1051')].value, #window width\n                    data[('0028','1052')].value, #intercept\n                    data[('0028','1053')].value] #slope\n    return [get_first_of_dicom_field_as_int(x) for x in dicom_fields]\n\n    \n    \ndef view_images(images, title = '', aug = None):\n    width = 5\n    height = 2\n    fig, axs = plt.subplots(height, width, figsize=(15,5))\n    \n    for im in range(0, height * width):\n        data = pydicom.read_file(os.path.join(TRAIN_IMG_PATH,'ID_'+images[im]+ '.dcm'))\n        image = data.pixel_array\n        window_center , window_width, intercept, slope = get_windowing(data)\n        image_windowed = window_image(image, window_center, window_width, intercept, slope)\n\n\n        i = im // width\n        j = im % width\n        axs[i,j].imshow(image_windowed, cmap=plt.cm.bone) \n        axs[i,j].axis('off')\n        \n    plt.suptitle(title)\n    plt.show()\n\ncase = 5\ndata = pydicom.dcmread(TRAIN_IMG_PATH+train_images[case])\n\nprint(data)\nwindow_center , window_width, intercept, slope = get_windowing(data)\n\n\n#displaying the image\nimg = pydicom.read_file(TRAIN_IMG_PATH+train_images[case]).pixel_array\n\nimg = window_image(img, window_center, window_width, intercept, slope)\nplt.imshow(img, cmap=plt.cm.bone)\nplt.grid(False)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"view_images(train[(train['type'] == 'epidural') & (train['Label'] == 1)][:10].PatientID.values, title = '1.epidural')","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"view_images(train[(train['type'] == 'intraparenchymal') & (train['Label'] == 1)][:10].PatientID.values, title = '2.intraparenchymal')","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"view_images(train[(train['type'] == 'intraventricular') & (train['Label'] == 1)][:10].PatientID.values, title = '3.intraventricular')","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"view_images(train[(train['type'] == 'subarachnoid') & (train['Label'] == 1)][:10].PatientID.values, title = '4.subarachnoid')","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"view_images(train[(train['type'] == 'subdural') & (train['Label'] == 1)][:10].PatientID.values, title = '5.subdural')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"view_images(train[(train['type'] == 'any') & (train['Label'] == 1)][:10].PatientID.values, title = '6.any')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3.Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"test = pd.DataFrame(sub.filename.unique(), columns=[\"filename\"])\nprint(\"Test_row:\", test.shape[0])\nprint(\"Test_col:\", test.shape[1])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_files = np.random.choice(os.listdir(TRAIN_IMG_PATH), 200000)\nsample_df = train[train.filename.apply(lambda x: x.replace('.png', '.dcm')).isin(sample_files)]\n\npivot_df = sample_df[['Label', 'filename', 'type']].drop_duplicates().pivot(\n    index='filename', columns='type', values='Label').reset_index()\nprint(pivot_df.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def save_and_resize(filenames, load_dir):    \n    save_dir = '/kaggle/tmp/'\n    if not os.path.exists(save_dir):\n        os.makedirs(save_dir)\n\n    for filename in tqdm(filenames):\n        path = load_dir + filename\n        new_path = save_dir + filename.replace('.dcm', '.png')\n        \n        dcm = pydicom.dcmread(path)\n        window_center , window_width, intercept, slope = get_windowing(dcm)\n        img = dcm.pixel_array\n        img = window_image(img, window_center, window_width, intercept, slope)\n        \n        resized = cv2.resize(img, (224, 224))\n        res = cv2.imwrite(new_path, resized)\n        if not res:\n            print('Failed')\n            \nsave_and_resize(filenames=sample_files, load_dir=BASE_PATH + TRAIN_DIR)\nsave_and_resize(filenames=os.listdir(BASE_PATH + TEST_DIR), load_dir=BASE_PATH + TEST_DIR)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"densenet = DenseNet121(\n    weights='../input/densenet-keras/DenseNet-BC-121-32-no-top.h5',\n    include_top=False,\n    input_shape=(224,224,3)\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = build_model()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"checkpoint = ModelCheckpoint(\n    'model.h5', \n    monitor='val_loss', \n    verbose=0, \n    save_best_only=True, \n    save_weights_only=False,\n    mode='auto'\n)\n\ntotal_steps = sample_files.shape[0] / BATCH_SIZE\n\nhistory = model.fit_generator(\n    train_gen,\n    steps_per_epoch=total_steps * 0.85,\n    validation_data=val_gen,\n    validation_steps=total_steps * 0.15,\n    callbacks=[checkpoint],\n    epochs=11\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with open('history.json', 'w') as f:\n    json.dump(history.history, f)\n\nhistory_df = pd.DataFrame(history.history)\nhistory_df[['loss', 'val_loss']].plot()\nhistory_df[['acc', 'val_acc']].plot()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 5.Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"model.load_weights('model.h5')\ny_test = model.predict_generator(\n    test_gen,\n    steps=len(test_gen),\n    verbose=1\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df[['ID', 'Label']].head(10)\n","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":1}