{"cells":[{"metadata":{"id":"0LrI7CDlTzsT"},"cell_type":"markdown","source":"RSNA intracranial hemorrhage detection - Hackathon\n===============","execution_count":null},{"metadata":{"id":"CvhuJEcMfkZo"},"cell_type":"markdown","source":"# 01 : Frame the Problem","execution_count":null},{"metadata":{"id":"vecIr9zyfvg_"},"cell_type":"markdown","source":"Objective of this notebook is to build an algorithm to detect acute intracranial hemorrhage and its subtypes.\n![alt text](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F603584%2F56162e47358efd77010336a373beb0d2%2Fsubtypes-of-hemorrhage.png?generation=1568657910458946&alt=media)\n\n**Labels**\n* epidural_hemorrhage,  \n* intraparenchymal_hemorrhage,  \n* intraventricular_hemorrhage,  \n* subarachnoid_hemorrhage,  \n* subdural_hemorrhage,  \n* any,  ","execution_count":null},{"metadata":{"id":"vC8Fr9OrgPvJ"},"cell_type":"markdown","source":"# 02 : Obtaining the Data","execution_count":null},{"metadata":{"id":"7Jxv1M_hTzsU"},"cell_type":"markdown","source":"### Download dataset form kaggle - use this only for colab","execution_count":null},{"metadata":{"id":"piuH59G1p6Xe","trusted":true},"cell_type":"code","source":"# !pip install kaggle\n# !mkdir .kaggle","execution_count":null,"outputs":[]},{"metadata":{"id":"0BoaPOa5TzsV","trusted":true},"cell_type":"code","source":"# import json\n# token = {\"username\":\"YOUR-USER-NAME\",\"key\":\"SOME-VERY-LONG-STRING\"}\n# with open('/content/.kaggle/kaggle.json', 'w') as file:\n#     json.dump(token, file)","execution_count":null,"outputs":[]},{"metadata":{"id":"NmIvVGpvpnt9","trusted":true},"cell_type":"code","source":"# !cp /content/.kaggle/kaggle.json ~/.kaggle/kaggle.json\n# !kaggle config set -n path -v{/content}\n# !chmod 600 /root/.kaggle/kaggle.json","execution_count":null,"outputs":[]},{"metadata":{"id":"u-asa9Afgwz6"},"cell_type":"markdown","source":"### Kaggle kernal data","execution_count":null},{"metadata":{"id":"Ic77CGj55pMP","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\n# import numpy as np # linear algebra\n# import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"id":"BbMYgO1CgTvR"},"cell_type":"markdown","source":"### Import the Libraries","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\", category=DeprecationWarning)\nwarnings.filterwarnings(\"ignore\", category=UserWarning)\nwarnings.filterwarnings(\"ignore\", category=FutureWarning)","execution_count":null,"outputs":[]},{"metadata":{"id":"l6Is1qRVTzsZ","trusted":true},"cell_type":"code","source":"# import the necessary packages\nfrom skimage.transform import resize\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom glob import glob\nfrom tqdm import tqdm\nimport argparse\nimport random\nimport cv2\nimport os\nimport pydicom","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Load the labels data \nlabels data is serialized we have to one hot encode it\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"BASE_PATH = '../input/rsna-intracranial-hemorrhage-detection/'\nTRAIN_IMAGES_FLDR = \"stage_1_train_images\"\nTEST_IMAGES_FLDR = \"stage_1_test_images\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def turn_input_to_dataframe(path):\n    original_df = pd.read_csv(path)\n    original_df['filename'] = original_df['ID'].apply(lambda x: \"ID_\" + x.split('_')[1] + \".dcm\")\n    original_df['type'] = original_df['ID'].apply(lambda x: x.split('_')[2])\n    final_df = original_df[['Label', 'filename', 'type']].drop_duplicates().pivot(index='filename', columns='type', values='Label').reset_index()\n    return final_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data_df = turn_input_to_dataframe(BASE_PATH + 'stage_1_train.csv')\ntest_data_df = turn_input_to_dataframe(BASE_PATH + 'stage_1_sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_data_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def turn_pred_to_dataframe(data_df, pred):\n    pref_df = pd.DataFrame(pred, columns=data_df.columns, index=data_df.index)\n    pref_df = pref_df.stack().reset_index()\n    pref_df.loc[:, \"ID\"] = pref_df.id.str.cat(df.subtype, sep=\"_\")\n    pref_df = pref_df.drop([\"id\", \"subtype\"], axis=1)\n    submission_df = pref_df.rename({0: \"Label\"}, axis=1)\n    return submission_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"turn_pred_to_dataframe(test_data_df)","execution_count":null,"outputs":[]},{"metadata":{"id":"0YhfkyhSh4MH"},"cell_type":"markdown","source":"# 03 : Analyze Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# fix all problamtic images\ndef fix_pxrepr(dcm):\n    if dcm.PixelRepresentation != 0 or dcm.RescaleIntercept<-100: return\n    x = dcm.pixel_array + 1000\n    px_mode = 4096\n    x[x>=px_mode] = x[x>=px_mode] - px_mode\n    dcm.PixelData = x.tobytes()\n    dcm.RescaleIntercept = -1000","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def windowed(dcm, w, l):\n    px = dcm.clone()\n    px_min = l - w//2\n    px_max = l + w//2\n    px[px<px_min] = px_min\n    px[px>px_max] = px_max\n    return (px-px_min) / (px_max-px_min)\n\n#fix_pxrepr(dcm)\n#windowed(dcm, w=80, l=40)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import kornia\ndef gauss_blur2d(x,s):\n    s2 = int(s/4)*2+1\n    x2 = unsqueeze(x, dim=0, n=4-x.dim())\n    res = kornia.filters.gaussian_blur2d(x2, (s2,s2), (s,s), 'replicate')\n    return res.squeeze()\n#blurred = gauss_blur2d(dcm, 100)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def mask_from_blur(x:Tensor, window, sigma=0.3, thresh=0.05, remove_max=True):\n    p = x.windowed(*window)\n    if remove_max: p[p==1] = 0\n    return gauss_blur2d(p, s=sigma*x.shape[-1])>thresh","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def pad_square(x):\n    r,c = x.shape\n    d = (c-r)/2\n    pl,pr,pt,pb = 0,0,0,0\n    if d>0: pt,pd = int(math.floor( d)),int(math.ceil( d))        \n    else:   pl,pr = int(math.floor(-d)),int(math.ceil(-d))\n    return np.pad(x, ((pt,pb),(pl,pr)), 'minimum')\n\ndef crop_mask(x):\n    mask = x.mask_from_blur(dicom_windows.brain)\n    bb = mask2bbox(mask)\n    if bb is None: return\n    lo,hi = bb\n    cropped = x.pixel_array[lo[0]:hi[0],lo[1]:hi[1]]\n    x.pixel_array = pad_square(cropped)","execution_count":null,"outputs":[]},{"metadata":{"id":"FVjb8gR8n41U"},"cell_type":"markdown","source":"### View sample images","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"*code source*:https://www.kaggle.com/omission/eda-view-dicom-images-with-correct-windowing","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def 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        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]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"total_image_count = len(X_df)\n\nfilename = BASE_PATH + TRAIN_IMAGES_FLDR + '/' + X_df['filename'][random.randint(0, total_image_count - 1)]\ndata = pydicom.dcmread(filename)\n\nwindow_center , window_width, intercept, slope = get_windowing(data)\n\n#displaying the image\nimg = pydicom.read_file(filename).pixel_array\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img = window_image(img, window_center, window_width, intercept, slope)\n\nplt.imshow(img, cmap=plt.cm.bone)\nplt.grid(False)\nprint(data)","execution_count":null,"outputs":[]},{"metadata":{"id":"627h6kFbqy3T"},"cell_type":"markdown","source":"# 04 : Feature Engineering","execution_count":null},{"metadata":{"id":"zCbm-LejTzsY"},"cell_type":"markdown","source":"### DataGenerator loading the data on the fly while training","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.python.keras.utils.data_utils import Sequence\n\ndef read_dicom_image_resize(filename, width, height, channel, test=False):\n    IMAGE_FLDR = TEST_IMAGES_FLDR if test else TRAIN_IMAGES_FLDR\n    file_path = BASE_PATH + TRAIN_IMAGES_FLDR + '/' + filename\n    data = pydicom.dcmread(file_path)\n    temp_pixal_array = data.pixel_array\n    window_center, window_width, intercept, slope = get_windowing(data)\n\n    img = window_image(temp_pixal_array, 50, 100, intercept, slope)\n    \n    resized = resize(img, (width, height), anti_aliasing=True)\n    return resized\n\n\nclass DataGenerator(Sequence):\n    'Generates data for Keras'\n    def __init__(self, list_IDs, batch_size=32, dim=(32,32,32), n_channels=1, n_classes=10, shuffle=True, test=False):\n        'Initialization'\n        self.dim = dim\n        self.batch_size = batch_size\n        #self.labels = labels\n        self.list_IDs = list_IDs\n        self.n_channels = n_channels\n        self.n_classes = n_classes\n        self.shuffle = shuffle\n        self.test = test\n        self.on_epoch_end()\n\n    def __len__(self):\n        'Denotes the number of batches per epoch'\n        return int(np.floor(len(self.list_IDs) / self.batch_size))\n\n    def __getitem__(self, index):\n        'Generate one batch of data'\n        # Generate indexes of the batch\n        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]\n        #list_IDs_temp, list_label_temp = [], []\n#         for k in indexes:\n#             #print(\"{} index X {}, y {}\".format(k, self.list_IDs['filename'][k], list(self.labels.iloc[k])))\n#             list_IDs_temp.append(self.list_IDs['filename'][k])\n#             list_label_temp.append(list(self.labels.iloc[k]))\n        list_IDs_temp = [self.list_IDs['filename'][k] for k in indexes]\n        list_label_temp=[[int(self.list_IDs['any'][i]),int(self.list_IDs['epidural'][i]),int(self.list_IDs['intraparenchymal'][i]),int(self.list_IDs['intraventricular'][i]),int(self.list_IDs['subarachnoid'][i]),int(self.list_IDs['subdural'][i])] for i in indexes]\n        # Generate data\n        X, y = self.__data_generation(list_IDs_temp,list_label_temp)\n\n        return X, y\n\n    def on_epoch_end(self):\n        'Updates indexes after each epoch'\n        self.indexes = np.arange(len(self.list_IDs))\n        if self.shuffle == True:\n            np.random.shuffle(self.indexes)\n\n    def __data_generation(self, list_IDs_temp, list_label_temp):\n        'Generates data containing batch_size samples' # X : (n_samples, *dim, n_channels)\n        # Initialization\n        X = []\n        y = []\n        # Generate data\n        for i, filename in enumerate(list_IDs_temp):\n            # Store sample\n            img = read_dicom_image_resize(filename, self.dim[0], self.dim[1], self.dim[2], self.test)\n            X.append(img)\n            \n            \n            \n        X=np.array(X).reshape(-1,self.dim[0],self.dim[1], self.dim[2])\n        # Store class\n        y = np.asarray(list_label_temp)\n\n        return X, y","execution_count":null,"outputs":[]},{"metadata":{"id":"G6OATHkPTzsi"},"cell_type":"markdown","source":"### Divide the data into training and testing(validtion set here) data","execution_count":null},{"metadata":{"id":"aS-0QMtrTzsj","trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n#select 100000 images from the dataset\n\n# partition the data into training and testing splits using 75% of\n# the data for training and the remaining 25% for testing\n\n# (trainX, testX, trainY, testY) = train_test_split(sampleX,\n#     sampleY, test_size=0.30, stratify=sampleY, random_state=42)\n# trainX = X_df[0:100000]\n# trainY = y_df[0:100000]\n# validX = X_df[100000:120000]\n# validY = y_df[100000:120000]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# trainX.reset_index(inplace=True, drop=True)\n# testX.reset_index(inplace=True, drop=True)\n# trainY.reset_index(inplace=True, drop=True)\n# testY.reset_index(inplace=True, drop=True)\n#trainX.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#trainY.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#pd.DataFrame({\"training\": [len(trainX)], \"validation\": [len(validX)]}, index=[\"count\"])#","execution_count":null,"outputs":[]},{"metadata":{"id":"Etn0HzaZra9T"},"cell_type":"markdown","source":"# 05: Model Selection\n","execution_count":null},{"metadata":{"id":"x9_rvcqDTzso"},"cell_type":"markdown","source":"### Define the CNN architecture","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"### Model 1 - from scratch","execution_count":null},{"metadata":{"id":"wJ4lB-xfTzsp","outputId":"8acf6ede-b2e3-4f8e-8e3c-a29e14191ec8","trusted":true},"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Dropout, Activation, Flatten\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D\n\ndef get_model(input_dim):\n    model = Sequential()\n    model.add(Conv2D(filters=32, kernel_size=3, strides=1, padding='same', activation='relu', input_shape=input_dim))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    model.add(Conv2D(filters=32, kernel_size=3, strides=1, padding='same', activation='relu'))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    model.add(Flatten())\n    model.add(Dense(50, activation='relu'))\n    model.add(Dense(6, activation='softmax'))\n    return model\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Focal Loss function\nWhen we have imbalance date per say, more negative classes and less postitive classes, having cross_entropy loss will caluculate negative logarithem of prediction, where a focal loss will take a gamma power of false prediction times the negative logerithem\n ![](https://github.com/umbertogriffo/focal-loss-keras/raw/master/focal_loss.png)\n*code source* : https://github.com/umbertogriffo/focal-loss-keras","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.python.ops import array_ops\n\ndef focal_loss(prediction_tensor, target_tensor, weights=None, alpha=0.25, gamma=2):\n    r\"\"\"Compute focal loss for predictions.\n        Multi-labels Focal loss formula:\n            FL = -alpha * (z-p)^gamma * log(p) -(1-alpha) * p^gamma * log(1-p)\n                 ,which alpha = 0.25, gamma = 2, p = sigmoid(x), z = target_tensor.\n    Args:\n     prediction_tensor: A float tensor of shape [batch_size, num_anchors,\n        num_classes] representing the predicted logits for each class\n     target_tensor: A float tensor of shape [batch_size, num_anchors,\n        num_classes] representing one-hot encoded classification targets\n     weights: A float tensor of shape [batch_size, num_anchors]\n     alpha: A scalar tensor for focal loss alpha hyper-parameter\n     gamma: A scalar tensor for focal loss gamma hyper-parameter\n    Returns:\n        loss: A (scalar) tensor representing the value of the loss function\n    \"\"\"\n    sigmoid_p = tf.nn.sigmoid(prediction_tensor)\n    zeros = array_ops.zeros_like(sigmoid_p, dtype=sigmoid_p.dtype)\n    \n    # For poitive prediction, only need consider front part loss, back part is 0;\n    # target_tensor > zeros <=> z=1, so poitive coefficient = z - p.\n    pos_p_sub = array_ops.where(target_tensor > zeros, target_tensor - sigmoid_p, zeros)\n    \n    # For negative prediction, only need consider back part loss, front part is 0;\n    # target_tensor > zeros <=> z=1, so negative coefficient = 0.\n    neg_p_sub = array_ops.where(target_tensor > zeros, zeros, sigmoid_p)\n    per_entry_cross_ent = - alpha * (pos_p_sub ** gamma) * tf.log(tf.clip_by_value(sigmoid_p, 1e-8, 1.0)) \\\n                          - (1 - alpha) * (neg_p_sub ** gamma) * tf.log(tf.clip_by_value(1.0 - sigmoid_p, 1e-8, 1.0))\n    return tf.reduce_sum(per_entry_cross_ent)","execution_count":null,"outputs":[]},{"metadata":{"id":"UqRKMu1eTzsr"},"cell_type":"markdown","source":"### Compile and train the model","execution_count":null},{"metadata":{"id":"u0SLrCDNTzss","trusted":true},"cell_type":"code","source":"epochs = 2\n#INIT_LR = 1e-3\nbatch_size = 100\nIMAGE_SIZE = 200\n\nloss_function = focal_loss\n# Parameters\nparams = {'dim': (IMAGE_SIZE, IMAGE_SIZE,1),\n          'batch_size': batch_size,\n          'n_classes': 6,\n          'n_channels': 1,\n          'shuffle': True}\n\nvalidSamples=labels_df[100000:120000]\nvalidSamples=validSamples.reset_index(drop=True)\n\ntrainDataGenerator = DataGenerator(labels_df[0:100000], **params)\nvalidDataGenerator = DataGenerator(validSamples, **params)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"get_model((IMAGE_SIZE,IMAGE_SIZE,1)).summary()","execution_count":null,"outputs":[]},{"metadata":{"id":"foHWhomnTzsu","outputId":"c989a994-3916-46f0-b64c-b10cff6a4250","trusted":true},"cell_type":"code","source":"from keras.callbacks import ModelCheckpoint  \nfrom keras_tqdm import TQDMNotebookCallback\n\nmodel = get_model((IMAGE_SIZE,IMAGE_SIZE,1))\n#opt = Adam(lr=INIT_LR, decay=INIT_LR / epochs)\nmodel.compile(loss=loss_function, optimizer=\"adam\", metrics=[\"accuracy\"])\n\ncheckpointer = ModelCheckpoint(filepath='weights.best.from_scratch.hdf5', \n                               verbose=1, save_best_only=True)\n\nhistory = model.fit_generator(\n    generator=trainDataGenerator, \n    validation_data=validDataGenerator,\n    use_multiprocessing=True, workers=-1,\n    epochs=epochs, \n    callbacks=[checkpointer, TQDMNotebookCallback()], verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"id":"5amFQTGg6DjT","outputId":"a0c2474f-48da-423b-ecc6-a6df233642f2","trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Plot training & validation accuracy values\nplt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\nplt.title('Model accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Test'], loc='upper left')\nplt.show()\n\n# Plot training & validation loss values\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('Model loss')\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Test'], loc='upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"JzYjLWFhsJY-"},"cell_type":"markdown","source":"# 05: Model Evaluation","execution_count":null},{"metadata":{"id":"n0lQiCjL2UAk"},"cell_type":"markdown","source":"### Load model weights","execution_count":null},{"metadata":{"id":"vNnNXhFkTzsw","trusted":true},"cell_type":"code","source":"model.load_weights('weights.best.from_scratch.hdf5')","execution_count":null,"outputs":[]},{"metadata":{"id":"OLW8pu1oTzsy"},"cell_type":"markdown","source":"### Accuracy of the model","execution_count":null},{"metadata":{"id":"Rw5c-fCdsWWU","trusted":true},"cell_type":"code","source":"#from sklearn.metrics import confusion_matrix, accuracy_score, recall_score, f1_score, precision_score","execution_count":null,"outputs":[]},{"metadata":{"id":"AOnzkKoMtHps","trusted":true},"cell_type":"code","source":"#y_actual = np.asarray(testY)\n#y_pred = model.predict_generator(testDataGenerator)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# y_pred.argmax(axis=1)","execution_count":null,"outputs":[]},{"metadata":{"id":"cL0lBhJjtumq","outputId":"90377e41-4c56-44a0-973b-404b880282db","trusted":true},"cell_type":"code","source":"# confusion_matrix(y_actual, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"id":"1vU6ACTHuopV","outputId":"b7bab8be-bc0e-4c8d-e349-b60cfb9f9767","trusted":true},"cell_type":"code","source":"# accuracy_score(y_actual, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"id":"Qq1UoQ8NusUn","outputId":"415d7bc6-0bca-44cd-f926-dcc037be4146","trusted":true},"cell_type":"code","source":"# recall_score(y_actual, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"id":"vUTBAshVydme","outputId":"f5871529-229f-4d33-e5d7-a2b2ab449cc7","trusted":true},"cell_type":"code","source":"# precision_score(y_actual, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"id":"vNFfj97buwRW","outputId":"43a74dc8-07a4-42a5-e151-0b1eef3e084f","trusted":true},"cell_type":"code","source":"# f1_score(y_actual, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"id":"tUwAJjn2Tzs5"},"cell_type":"markdown","source":"# 07: Submission results","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"BASE_PATH = '../input/rsna-intracranial-hemorrhage-detection/'\nTRAIN_IMAGES_FLDR = \"stage_1_train_images\"\nTEST_IMAGES_FLDR = \"stage_1_test_images\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_data = pd.read_csv(BASE_PATH + \"stage_1_sample_submission.csv\")\ntest_data['filename'] = test_data['ID'].apply(lambda x: \"ID_\" + x.split('_')[1] + \".dcm\")\ntest_data['type'] = test_data['ID'].apply(lambda x: x.split('_')[2])\ntest_data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_data = test_data[['Label', 'filename', 'type']].drop_duplicates().pivot(\n    index='filename', columns='type', values='Label').reset_index()\ntest_data_filename = test_data['filename']\ntotal_test_images = len(test_data_filename)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df = pd.DataFrame({\"ID\":[], \"Label\":[]})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_test = []\nfor i, filename in tqdm(enumerate(test_data_filename[:1000])):\n    # Store sample\n    ds=pydicom.dcmread(BASE_PATH + TEST_IMAGES_FLDR + '/' + filename)\n    temp=ds.pixel_array\n    window_center , window_width, intercept, slope = get_windowing(ds)\n    img = window_image(temp, 50, 100, intercept, slope)\n    resized = cv2.resize(img, (200, 200))\n    X_test.append(resized)       \nX_test=np.array(X_test).reshape(-1,200,200,1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred = model.predict(X_test)\ny_pred_max = np.zeros_like(y_pred)\ny_pred_max[np.arange(len(y_pred)), y_pred.argmax(1)] = 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i, filename in tqdm(enumerate(test_data_filename[:1000])):\n    prediction = y_pred_max[i]\n    fileID = filename.split(\".\")[0]\n    listOfSeries = [\n        pd.Series([fileID+\"_any\", prediction[0]], index=submission_df.columns),\n        pd.Series([fileID+\"_epidural\", prediction[1]], index=submission_df.columns),\n        pd.Series([fileID+\"_intraparenchymal\", prediction[2]], index=submission_df.columns),\n        pd.Series([fileID+\"_intraventricular\", prediction[3]], index=submission_df.columns),\n        pd.Series([fileID+\"_subarachnoid\", prediction[4]], index=submission_df.columns),\n        pd.Series([fileID+\"_subdural\", prediction[5]], index=submission_df.columns),\n    ]\n    submission_df = submission_df.append(listOfSeries, ignore_index=True)   ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with open(\"stage_1_submission.csv\", \"w\") as f:\n    submission_df.to_csv(f, index=False)","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":4}