{"cells":[{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","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\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport scipy as sp\nfrom math import log\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\nimport os\nbasePath = '/kaggle/input/rsna-intracranial-hemorrhage-detection/'\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"trainInfo = pd.read_csv(basePath+'stage_1_train.csv')\nprint(trainInfo.head(10))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"splitData = trainInfo['ID'].str.split('_', expand = True)\ntrainInfo['class'] = splitData[2]\ntrainInfo['fileName'] = splitData[0] + '_' + splitData[1]\ntrainInfo = trainInfo.drop(columns=['ID'],axis=1)\ndel splitData\nprint(trainInfo.head(10))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pivot_trainInfo = trainInfo[['Label', 'fileName', 'class']].drop_duplicates().pivot_table(index = 'fileName',columns=['class'], values='Label')\npivot_trainInfo = pd.DataFrame(pivot_trainInfo.to_records())\nprint(pivot_trainInfo.head(10))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.image as pltimg\nimport pydicom\n\nfig = plt.figure(figsize = (20,10))\nrows = 5\ncolumns = 5\ntrainImages = os.listdir(basePath + 'stage_1_train_images')\nfor i in range(rows*columns):\n    ds = pydicom.dcmread(basePath + 'stage_1_train_images/' + trainImages[i*100+1])\n    fig.add_subplot(rows, columns, i+1)\n    plt.imshow(ds.pixel_array, cmap=plt.cm.bone)\n    fig.add_subplot    \n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"colsToPlot = ['any','epidural','intraparenchymal','intraventricular','subarachnoid','subdural']\nrows = 5\ncolumns = 5\nfor i_col in colsToPlot:\n    fig = plt.figure(figsize = (20,10))\n    trainImages = list(pivot_trainInfo.loc[pivot_trainInfo[i_col]==1,'fileName'])\n    plt.title(i_col + ' Images')\n    for i in range(rows*columns):\n        ds = pydicom.dcmread(basePath + 'stage_1_train_images/' + trainImages[i*100+1] +'.dcm')\n        fig.add_subplot(rows, columns, i+1)\n        plt.imshow(ds.pixel_array, cmap=plt.cm.bone)        \n        fig.add_subplot    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i_col in colsToPlot:\n    plt.figure()\n    ax = sns.countplot(pivot_trainInfo[i_col])\n    ax.set_title(i_col + ' class count')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#dropping of corrupted image from dataset\npivot_trainInfo = pivot_trainInfo.drop(list(pivot_trainInfo['fileName']).index('ID_6431af929'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import keras\nfrom keras.layers import Dense, Activation,Dropout,Conv2D,MaxPooling2D,Flatten,Input,BatchNormalization,AveragePooling2D,LeakyReLU,ZeroPadding2D,Add,GlobalAveragePooling2D\nfrom keras.models import Sequential, Model\nfrom keras.initializers import glorot_uniform\nfrom keras import optimizers\nfrom keras.applications.resnet import ResNet50\nfrom tqdm import tqdm\nfrom sklearn.model_selection import train_test_split\nimport cv2\nimport gc\n\npivot_trainInfo = pivot_trainInfo.sample(frac=1).reset_index(drop=True)\ntrain_df,val_df = train_test_split(pivot_trainInfo,test_size = 0.03, random_state = 42)\nbatch_size = 64","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_train = train_df[['any','epidural','intraparenchymal','intraventricular','subarachnoid','subdural']]\ny_val = val_df[['any','epidural','intraparenchymal','intraventricular','subarachnoid','subdural']]\ntrain_files = list(train_df['fileName'])\ngc.collect()\ndef scaleAndconvertImage(ds,windowLength,windowWidth):\n    image = ds.pixel_array\n    # Set outside-of-scan pixels to 1\n    # The intercept is usually -1024, so air is approximately 0\n    image[image == -2000] = 0\n    # Convert to Hounsfield units (HU)\n    intercept = ds.RescaleIntercept\n    slope = ds.RescaleSlope    \n    image = image * slope + intercept\n    #min_value = windowLength - (windowWidth/2)\n    #max_value = windowLength + (windowWidth/2)     \n    #image[image <= min_value] = 0\n    #image[image > max_value] = 255   \n    #image[(image > min_value) & (image <= max_value)] = \\\n     #   ((image[(image > min_value) & (image <= max_value)] - \n     #     (windowLength - 0.5)) / (windowWidth - 1) + 0.5) * (255 - 0) + 0  \n    U=1.0 \n    eps=(1.0 / 255.0)\n    ue = log((U / eps) - 1.0)\n    W = (2 / windowWidth) * ue\n    b = ((-2 * windowLength) / windowWidth) * ue\n    z = W * image + b\n    image = U / (1 + np.power(np.e, -1.0 * z))    \n    x_max = image.max()\n    x_min = image.min()\n    if x_max != x_min:\n        image = (image - x_min) / (x_max - x_min)\n        return image\n    del x_max,x_min,slope,intercept,ds\n    return np.zeros(image.shape) \n    \n\ndef get_pixels_hu(ds):\n    brain_img = scaleAndconvertImage(ds,40,80)\n    subdural_img = scaleAndconvertImage(ds,80,200)\n    bone_img = scaleAndconvertImage(ds,600,2000)\n    image = np.zeros((brain_img.shape[0], brain_img.shape[1], 3))\n    image[:, :, 0] = brain_img\n    image[:, :, 1] = subdural_img\n    image[:, :, 2] = bone_img   \n    del brain_img,subdural_img,bone_img\n    return image    \n\ndef readDCMFile(fileName):\n    ds = pydicom.read_file(fileName) # read dicom image\n    #img = ds.pixel_array # get image array\n    img = get_pixels_hu(ds)\n    img = cv2.resize(img, (64, 64), interpolation = cv2.INTER_AREA) \n    return img\n\ndef generateImageData(train_files,y_train):\n    numBatches = int(np.ceil(len(train_files)/batch_size))\n    while True:\n        x_batch_data = []\n        y_batch_data = []\n        for i in range(numBatches):\n            batchFiles = train_files[i*batch_size : (i+1)*batch_size]\n            x_batch_data = np.array([readDCMFile(basePath + 'stage_1_train_images/' + i_f +'.dcm') for i_f in batchFiles])\n            y_batch_data = y_train[i*batch_size : (i+1)*batch_size]\n            #x_batch_data = np.reshape(x_batch_data,(x_batch_data.shape[0],x_batch_data.shape[1],x_batch_data.shape[2],1))            \n            yield x_batch_data,y_batch_data\n            x_batch_data = []\n            y_batch_data = []                  \n            \ndef generateTestImageData(test_files):\n    numBatches = int(np.ceil(len(test_files)/batch_size))\n    while True:\n        x_batch_data = []        \n        for i in range(numBatches):\n            batchFiles = test_files[i*batch_size : (i+1)*batch_size]\n            x_batch_data = np.array([readDCMFile(basePath + 'stage_1_test_images/' + i_f +'.dcm') for i_f in batchFiles])\n            #x_batch_data = np.reshape(x_batch_data,(x_batch_data.shape[0],x_batch_data.shape[1],x_batch_data.shape[2],1))\n            yield x_batch_data            \n            x_batch_data = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i_col in colsToPlot:\n    fig = plt.figure(figsize = (20,10))\n    trainImages = list(pivot_trainInfo.loc[pivot_trainInfo[i_col]==1,'fileName'])\n    plt.title(i_col + ' Images')\n    for i in range(rows*columns):\n        img = readDCMFile(basePath + 'stage_1_train_images/' + trainImages[i*100+1] +'.dcm')\n        fig.add_subplot(rows, columns, i+1)\n        plt.imshow(img,cmap=plt.cm.bone)        \n        fig.add_subplot    \n        del img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataGenerator = generateImageData(train_files,train_df[colsToPlot])\nval_files = list(val_df['fileName'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_val = np.array([readDCMFile(basePath + 'stage_1_train_images/' + i_f +'.dcm') for i_f in tqdm(val_files)])\ny_val = val_df[colsToPlot]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# loss function definition courtesy https://www.kaggle.com/akensert/resnet50-keras-baseline-model\nfrom keras import backend as K\ndef logloss(y_true,y_pred):      \n    eps = K.epsilon()\n    \n    class_weights = np.array([2., 1., 1., 1., 1., 1.])\n    \n    y_pred = K.clip(y_pred, eps, 1.0-eps)\n\n    #compute logloss function (vectorised)  \n    out = -( y_true *K.log(y_pred)*class_weights\n            + (1.0 - y_true) * K.log(1.0 - y_pred)*class_weights)\n    return K.mean(out, axis=-1)\n\ndef _normalized_weighted_average(arr, weights=None):\n    \"\"\"\n    A simple Keras implementation that mimics that of \n    numpy.average(), specifically for the this competition\n    \"\"\"\n    \n    if weights is not None:\n        scl = K.sum(weights)\n        weights = K.expand_dims(weights, axis=1)\n        return K.sum(K.dot(arr, weights), axis=1) / scl\n    return K.mean(arr, axis=1)\n\ndef weighted_loss(y_true, y_pred):\n    \"\"\"\n    Will be used as the metric in model.compile()\n    ---------------------------------------------\n    \n    Similar to the custom loss function 'weighted_log_loss()' above\n    but with normalized weights, which should be very similar \n    to the official competition metric:\n        https://www.kaggle.com/kambarakun/lb-probe-weights-n-of-positives-scoring\n    and hence:\n        sklearn.metrics.log_loss with sample weights\n    \"\"\"      \n    \n    eps = K.epsilon()\n    \n    class_weights = K.variable([2., 1., 1., 1., 1., 1.])\n    \n    y_pred = K.clip(y_pred, eps, 1.0-eps)\n\n    loss = -(y_true*K.log(y_pred)\n            + (1.0 - y_true) * K.log(1.0 - y_pred))\n    \n    loss_samples = _normalized_weighted_average(loss,class_weights)\n    \n    return K.mean(loss_samples)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"def inceptionKeras(input_img,numFilters11_1,numFilters11_2,numFilters11_3,numFilters33_1,numFilters55_1,numFilters_pool):\n    tower_11_1 = Conv2D(numFilters11_1, (1,1), padding='same', activation='relu')(input_img)\n    tower_11_2 = Conv2D(numFilters11_2, (1,1), padding='same', activation='relu')(input_img)\n    tower_33_1 = Conv2D(numFilters33_1, (3,3), padding='same', activation='relu')(tower_11_2)\n    tower_11_3 = Conv2D(numFilters11_3, (1,1), padding='same', activation='relu')(input_img)\n    tower_55_1 = Conv2D(numFilters55_1, (5,5), padding='same', activation='relu')(tower_11_3)    \n    tower_33_pool = MaxPooling2D((3,3), strides=(1,1), padding='same')(input_img)\n    tower_33_pool = Conv2D(numFilters_pool, (1,1), padding='same', activation='relu')(tower_33_pool)\n    \n    output = keras.layers.concatenate([tower_11_1, tower_33_1, tower_55_1, tower_33_pool], axis = 3)    \n    output = Activation('relu')(output)\n    return output"},{"metadata":{},"cell_type":"markdown","source":"input_img = Input(shape=(64,64,1))\nlayer_1 = Conv2D(filters = 64,kernel_size = (5,5),strides = 1,padding = 'same',activation='relu')(input_img)\nlayer_2 = Conv2D(filters = 128,kernel_size = (3,3),strides = 1,padding = 'same',activation='relu')(layer_1)\nlayer_2 = MaxPooling2D(pool_size = (3,3),padding = 'same',strides = 2)(layer_2)\nlayer_2 = BatchNormalization(axis=3, momentum=0.99, epsilon=0.001)(layer_2)\nlayer_incp_1 = inceptionKeras(layer_2,8,64,8,96,16,8)\nlayer_incp_2 = inceptionKeras(layer_incp_1,64,96,16,128,32,32)\nlayer_incp_3 = inceptionKeras(layer_incp_2,160,112,24,224,64,64)\nlayer_3 = MaxPooling2D(pool_size = (3,3),padding = 'same',strides = 2)(layer_incp_3)\nlayer_3 = BatchNormalization()(layer_3)\nlayer_incp_4 = inceptionKeras(layer_3,128,128,32,256,64,64)\nlayer_4 = AveragePooling2D(pool_size = (7,7),padding = 'same',strides = 7)(layer_incp_4)\noutput = Flatten()(layer_4)\noutput = Dropout(0.5)(output)\noutput = Dense(512,activation='relu')(output)\nout = Dense(6, activation='sigmoid')(output)"},{"metadata":{"trusted":true},"cell_type":"code","source":"def convolutionBlock(X,f,filters,stage,block,s):\n    conv_name_base = 'res' + str(stage) + block + '_branch'\n    bn_name_base = 'bn' + str(stage) + block + '_branch'\n    \n    X_shortcut = X\n    F1,F2,F3 = filters\n    X = Conv2D(filters = F1, kernel_size = (1,1),strides = s, padding = 'valid',name = conv_name_base + '2a',\n               kernel_initializer=glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3,momentum=0.99, epsilon=0.001,name = bn_name_base+'2a')(X)\n    X = Activation('relu')(X)\n    \n    X = Conv2D(filters = F2, kernel_size = (f,f),strides = 1, padding = 'same',name = conv_name_base + '2b',\n               kernel_initializer=glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3,momentum=0.99, epsilon=0.001,name = bn_name_base+'2b')(X)\n    X = Activation('relu')(X)\n    \n    X = Conv2D(filters = F3, kernel_size = (1,1),strides = 1, padding = 'valid',name = conv_name_base + '2c',\n               kernel_initializer=glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3,momentum=0.99, epsilon=0.001,name = bn_name_base+'2c')(X)\n\n    X_shortcut = Conv2D(filters = F3, kernel_size = (1,1),strides = s, padding = 'valid',name = conv_name_base + '1',\n               kernel_initializer=glorot_uniform(seed=0))(X_shortcut)\n    X_shortcut = BatchNormalization(axis = 3,momentum=0.99, epsilon=0.001,name = bn_name_base+'1')(X_shortcut)\n    \n    X = Add()([X,X_shortcut])\n    X = Activation('relu')(X)\n    \n    return X\n\ndef identityBlock(X,f,filters,stage,block):\n    conv_name_base = 'res' + str(stage) + block + '_branch'\n    bn_name_base = 'bn' + str(stage) + block + '_branch'\n    \n    X_shortcut = X\n    F1,F2,F3 = filters\n    X = Conv2D(filters = F1, kernel_size = (1,1),strides = 1, padding = 'valid',name = conv_name_base + '2a',\n               kernel_initializer=glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3,momentum=0.99, epsilon=0.001,name = bn_name_base+'2a')(X)\n    X = Activation('relu')(X)\n    \n    X = Conv2D(filters = F2, kernel_size = (f,f),strides = 1, padding = 'same',name = conv_name_base + '2b',\n               kernel_initializer=glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3,momentum=0.99, epsilon=0.001,name = bn_name_base+'2b')(X)\n    X = Activation('relu')(X)\n    \n    X = Conv2D(filters = F3, kernel_size = (1,1),strides = 1, padding = 'valid',name = conv_name_base + '2c',\n               kernel_initializer=glorot_uniform(seed=0))(X)\n    X = BatchNormalization(axis = 3,momentum=0.99, epsilon=0.001,name = bn_name_base+'2c')(X)\n    \n    X = Add()([X,X_shortcut])\n    X = Activation('relu')(X)\n    \n    return X","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"input_img = Input((64,64,3))\n#X = Conv2D(filters=3, kernel_size=(1, 1), strides=(1, 1), name=\"initial_conv2d\")(input_img)\n#X = BatchNormalization(axis=3, name='initial_bn')(X)\n#X = Activation('relu', name='initial_relu')(X)\nX = ZeroPadding2D((3, 3))(input_img)\n\n# Stage 1\nX = Conv2D(64, (7, 7), strides=(2, 2), name='conv1', kernel_initializer=glorot_uniform(seed=0))(X)\nX = BatchNormalization(axis=3, name='bn_conv1')(X)\nX = Activation('relu')(X)\nX = MaxPooling2D((3, 3), strides=(2, 2))(X)\n\n# Stage 2\nX = convolutionBlock(X, f=3, filters=[64, 64, 256], stage=2, block='a', s=1)\nX = identityBlock(X, 3, [64, 64, 256], stage=2, block='b')\nX = identityBlock(X, 3, [64, 64, 256], stage=2, block='c')\n\n# Stage 3 (≈4 lines)\nX = convolutionBlock(X, f=3, filters=[128, 128, 512], stage=3, block='a', s=2)\nX = identityBlock(X, 3, [128, 128, 512], stage=3, block='b')\nX = identityBlock(X, 3, [128, 128, 512], stage=3, block='c')\nX = identityBlock(X, 3, [128, 128, 512], stage=3, block='d')\n\n# Stage 4 (≈4 lines)\nX = convolutionBlock(X, f=3, filters=[256, 256, 1024], stage=4, block='a', s=2)\nX = identityBlock(X, 3, [256, 256, 1024], stage=4, block='b')\nX = identityBlock(X, 3, [256, 256, 1024], stage=4, block='c')\nX = identityBlock(X, 3, [256, 256, 1024], stage=4, block='d')\nX = identityBlock(X, 3, [256, 256, 1024], stage=4, block='e')\nX = identityBlock(X, 3, [256, 256, 1024], stage=4, block='f')\n\n# Stage 5 (≈4 lines)\nX = convolutionBlock(X, f=3, filters=[512, 512, 2048], stage=5, block='a', s=2)\nX = identityBlock(X, 3, [512, 512, 2048], stage=5, block='b')\nX = identityBlock(X, 3, [512, 512, 2048], stage=5, block='c')\n\n\n# AVGPOOL (≈1 line). Use \"X = AveragePooling2D(...)(X)\"\nX = AveragePooling2D(pool_size=(2, 2), padding='same')(X)\n# output layer\nX = Flatten()(X)\nout = Dense(6,name='fc' + str(6),activation='sigmoid')(X)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"x_val = np.reshape(x_val,(x_val.shape[0],x_val.shape[1],x_val.shape[2],1))"},{"metadata":{"trusted":true},"cell_type":"code","source":"model_conv = Model(inputs = input_img, outputs = out)\n#model_conv.compile(optimizer='Adam',loss = 'categorical_crossentropy',metrics=['accuracy'])\nmodel_conv.compile(optimizer='Adam',loss = logloss,metrics=[weighted_loss])\nmodel_conv.summary()\nhistory_conv = model_conv.fit_generator(dataGenerator,steps_per_epoch=500, epochs=20,validation_data = (x_val,y_val),verbose = True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"testInfo = pd.read_csv(basePath+'stage_1_sample_submission.csv')\nsplitData = testInfo['ID'].str.split('_', expand = True)\ntestInfo['class'] = splitData[2]\ntestInfo['fileName'] = splitData[0] + '_' + splitData[1]\ntestInfo = testInfo.drop(columns=['ID'],axis=1)\ndel splitData\npivot_testInfo = testInfo[['fileName', 'class','Label']].drop_duplicates().pivot_table(index = 'fileName',columns=['class'], values='Label')\npivot_testInfo = pd.DataFrame(pivot_testInfo.to_records())\ntest_files = list(pivot_testInfo['fileName'])\ntestDataGenerator = generateTestImageData(test_files)\ntemp_pred = model_conv.predict_generator(testDataGenerator,steps = pivot_testInfo.shape[0]/batch_size,verbose = True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"temp_pred.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df = pivot_testInfo\nsubmission_df['any'] = temp_pred[:,0]\nsubmission_df['epidural'] = temp_pred[:,1]\nsubmission_df['intraparenchymal'] = temp_pred[:,2]\nsubmission_df['intraventricular'] = temp_pred[:,3]\nsubmission_df['subarachnoid'] = temp_pred[:,4]\nsubmission_df['subdural'] = temp_pred[:,5]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df = submission_df.melt(id_vars=['fileName'])\nsubmission_df['ID'] = submission_df.fileName + '_' + submission_df.variable\nsubmission_df['Label'] = submission_df['value']\nprint(submission_df.head(20))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df = submission_df.drop(['fileName','variable','value'],axis = 1)\nprint(submission_df.head(20))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df.to_csv('sample_submission.csv', index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.6"}},"nbformat":4,"nbformat_minor":1}