{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","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 os\nimport gc\nimport random\nimport pydicom\nimport cv2\n\nimport matplotlib.pyplot as plt\n\nfrom sklearn.model_selection import train_test_split\n\nimport tensorflow as tf\nimport keras\nfrom keras.models import Model\nfrom keras.utils import to_categorical\nfrom keras.applications.resnet50 import ResNet50\nfrom keras.preprocessing import image\nfrom keras.layers import Input, Conv2D, MaxPooling2D, Dense, Flatten, BatchNormalization, GlobalAveragePooling2D\nfrom keras.optimizers import SGD, Adam, RMSprop\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau\nfrom keras import backend as K\n\nprint(os.listdir('../input/'))\nprint(os.listdir('../input/rsna-intracranial-hemorrhage-detection/'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Constants\nSEED = 42\nNUM_CLASSES = 6\nNO_PATIENTS_SELECTED = 10000 #50000\nIMG_DIM = 512\nNO_CHANNEL = 3\nBATCH_SIZE = 64\n\nPATH='../input/rsna-intracranial-hemorrhage-detection/'\n\nRESNET_WEIGHT_FULLPATH = '../input/resnet50weightsfile/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'\nTRAIN_CSV_FULLPATH = PATH + 'stage_1_train.csv'\nTEST_CSV_FULLPATH = PATH + 'stage_1_sample_submission.csv'\nTRAIN_IMG_PATH = PATH + 'stage_1_train_images/'\nTEST_IMG_PATH = PATH + 'stage_1_test_images/'\n\n\nrandom.seed(SEED) ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"df_train = pd.read_csv(TRAIN_CSV_FULLPATH)\n\n# Removing corrupted image\ndf_train = df_train[df_train.ID != 'ID_6431af929_epidural']\ndf_train = df_train[df_train.ID != 'ID_6431af929_intraparenchymal']\ndf_train = df_train[df_train.ID != 'ID_6431af929_intraventricular']\ndf_train = df_train[df_train.ID != 'ID_6431af929_subarachnoid']\ndf_train = df_train[df_train.ID != 'ID_6431af929_subdural']\ndf_train = df_train[df_train.ID != 'ID_6431af929_any']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.head(50)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_test = pd.read_csv(TEST_CSV_FULLPATH)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_test.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Randomly sample 50,000 the patientIDs\n\ntotal_train_patient_no = int(df_train.shape[0]/NUM_CLASSES)\nprint(total_train_patient_no)\n\ntotal_test_patient_no = int(df_test.shape[0]/NUM_CLASSES)\nprint(total_test_patient_no)\n\ntrain_sample_patient_idx_list = random.sample(range(0,total_train_patient_no), NO_PATIENTS_SELECTED)\nprint(len(train_sample_patient_idx_list))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create new train Dataframe for training resnet with multilabel data\n\ndf_train_multilbl = pd.DataFrame(\n    columns=['ID','patientID','epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural', 'any'])\n\ncnt = 1\nfor patient_idx in train_sample_patient_idx_list:\n    k = patient_idx*6\n    ID_col_val =  df_train.iloc[k]['ID']\n    img_name = 'ID_' + ID_col_val.split('_')[1] + '.dcm'\n    patientID = ID_col_val.split('_')[1]\n    if len(ID_col_val.split('_')) == 3:\n        print(cnt)\n        cnt += 1\n        epidural_lbl = df_train.iloc[k]['Label']\n        intraparenchymal_lbl = df_train.iloc[k+1]['Label']\n        intraventricular_lbl = df_train.iloc[k+2]['Label']\n        subarachnoid_lbl = df_train.iloc[k+3]['Label']\n        subdural_lbl = df_train.iloc[k+4]['Label']\n        any_lbl = df_train.iloc[k+5]['Label']\n        df_train_multilbl = df_train_multilbl.append(\n            {'ID': img_name, \n             'patientID': patientID,\n             'epidural': epidural_lbl, \n             'intraparenchymal': intraparenchymal_lbl, \n             'intraventricular': intraventricular_lbl, \n             'subarachnoid': subarachnoid_lbl, \n             'subdural': subdural_lbl, 'any': any_lbl}, ignore_index=True)\n\nprint(df_train_multilbl.shape)\ndf_train_multilbl.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(df_train_multilbl.shape)\ndf_train_multilbl.head(10)\n\nprint(any(df_train_multilbl['epidural']==1))\nprint(any(df_train_multilbl['intraparenchymal']==1))\nprint(any(df_train_multilbl['intraventricular']==1))\nprint(any(df_train_multilbl['subarachnoid']==1))\nprint(any(df_train_multilbl['subdural']==1))\nprint(any(df_train_multilbl['any']==1))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create new test Dataframe for testing resnet with multilabel data\n'''\ndf_test_multilbl = pd.DataFrame(\n    columns=['ID','patientID','epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural', 'any'])\n\ncnt = 1\nfor k in range(0, total_test_patient_no, NUM_CLASSES):\n    ID_col_val =  df_train.iloc[k]['ID']\n    img_name = 'ID_' + ID_col_val.split('_')[1] + '.dcm'\n    patientID = ID_col_val.split('_')[1]\n    if len(ID_col_val.split('_')) == 3:\n        print(cnt)\n        cnt += 1\n        epidural_lbl = df_test.iloc[k]['Label']\n        intraparenchymal_lbl = df_test.iloc[k+1]['Label']\n        intraventricular_lbl = df_test.iloc[k+2]['Label']\n        subarachnoid_lbl = df_test.iloc[k+3]['Label']\n        subdural_lbl = df_test.iloc[k+4]['Label']\n        any_lbl = df_test.iloc[k+5]['Label']\n        df_test_multilbl.append(\n            {'ID': img_name, \n             'patientID': patientID,\n             'epidural': epidural_lbl, \n             'intraparenchymal': intraparenchymal_lbl, \n             'intraventricular': intraventricular_lbl, \n             'subarachnoid': subarachnoid_lbl, \n             'subdural': subdural_lbl, 'any': any_lbl}, ignore_index=True)\n        \nprint(df_test_multilbl.shape())\ndf_test_multilbl.head(10)\n'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Network Architecture\n\ninput_tensor = Input(shape=(224, 224, NO_CHANNEL))\n        \nbase_model = ResNet50(include_top=False, weights=None, input_tensor=input_tensor)\nbase_model.load_weights(RESNET_WEIGHT_FULLPATH)\n\n    # add a global spatial average pooling layer\nx = base_model.output\noutput = BatchNormalization()(x)\nx = GlobalAveragePooling2D()(x)\n\n# let's add a fully-connected layer\nx = Dense(1024, activation='relu')(x)\n\n# what should be the last layer activation function for multilabel learning with 6 classes?\npredictions = Dense(NUM_CLASSES, activation='softmax')(x) \n\n# this is the model we will train\nmodel = Model(inputs=base_model.input, outputs=predictions)\n\n# first: train only the top layers (which were randomly initialized)\n# i.e. freeze all convolutional Resnet50 layers\nfor layer in base_model.layers:\n    layer.trainable=False\n    \nfor layer in model.layers:\n    layer.trainable=True\n    \nprint(model.summary())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# split train data into train and dev set\n\ny_cols = ['epidural','intraparenchymal','intraventricular','subarachnoid','subdural','any']\nall_cols = df_train_multilbl.columns\nx_cols = list(set(all_cols).difference(set(y_cols)))\n\nX = df_train_multilbl[x_cols]\ny = df_train_multilbl[y_cols]\n\nx_train, x_val, y_train, y_val = train_test_split(X, y,test_size=0.33, random_state=SEED)\n\ndel df_train, df_test, df_train_multilbl, X, y\ngc.collect()\n\nprint(x_train.shape)\nprint(y_train.shape)\n\nprint(x_val.shape)\nprint(y_val.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# pre-processing function for the image generators\n\ndef window_img(dcm, width=None, level=None):\n    pixels = dcm.pixel_array * dcm.RescaleSlope + dcm.RescaleIntercept\n    if not width:\n        width = dcm.WindowWidth\n        if type(width) != pydicom.valuerep.DSfloat:\n            width = width[0]\n    if not level:\n        level = dcm.WindowCenter\n        if type(level) != pydicom.valuerep.DSfloat:\n            level = level[0]\n    lower = level - (width / 2)\n    upper = level + (width / 2)\n    return np.clip(pixels, lower, upper)\n\ndef load_one_image(img_fullpath, width=200, level=80):\n    dcm_data = pydicom.dcmread(img_fullpath)\n    #assert('filepath' in dcm_data.columns)\n    #pixels = window_img(dcm_data, width, level)\n    #print(dcm_data.pixel_array.shape)\n    return dcm_data.pixel_array\n\ndef load_and_normalize_dicom(path, x, y, n):\n    dicom1 = pydicom.read_file(path)\n    dicom_img = dicom1.pixel_array.astype(np.float64)\n    mn = dicom_img.min()\n    mx = dicom_img.max()\n    if (mx - mn) != 0:\n        dicom_img = (dicom_img - mn)/(mx - mn)\n    else:\n        dicom_img[:, :] = 0\n    if dicom_img.shape != (x, y):\n        dicom_img = cv2.resize(dicom_img, (x, y), interpolation=cv2.INTER_CUBIC)\n    \n    if n == 3:\n        image = np.stack([dicom_img,dicom_img,dicom_img])\n        image = image.reshape(x, y, n)\n        \n    return image\n\nsample_img_arr = ['ID_63eb1e259.dcm', 'ID_2669954a7.dcm', 'ID_52c9913b1.dcm', 'ID_4e6ff6126.dcm']\nimg_fullpath = TRAIN_IMG_PATH + sample_img_arr[2]\n\npixels = load_one_image(img_fullpath)\nplt.imshow(pixels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Define customized data generator for training and validation\n\n#y_cols = ['epidural','intraparenchymal','intraventricular','subarachnoid','subdural','any']\n\ndef batch_generator_train_multilbl(path, df, x_col, y_cols, batch_size, target_size):\n    number_of_batches = np.ceil((df.shape[0])/batch_size)\n    counter = 0\n    #random.shuffle(df)\n    df_idx_lst = range(0,df.shape[0])\n    no_batches = df.shape[0]//batch_size\n    while True:\n        df_idx_batch = df_idx_lst[batch_size*counter:batch_size*(counter+1)]\n        image_list = []\n        mask_list = []\n        for idx in df_idx_batch:\n            filename = df.iloc[idx][x_col]\n            image = load_and_normalize_dicom(path + filename, target_size[0], target_size[1], NO_CHANNEL)\n            mask = []\n            for col in y_cols:\n                is_subtype = int(df.iloc[idx][col])\n                mask.append(is_subtype)\n            image = np.stack([image,image,image])\n            image = image.reshape((target_size[0], target_size[1], NO_CHANNEL))\n            image_list.append(image)\n            mask_list.append(mask)\n        counter += 1\n        image_list = np.array(image_list)\n        mask_list = np.array(mask_list)\n        #print(image_list.shape)\n        #print(mask_list.shape)\n        yield (image_list, mask_list)\n        del image_list, mask_list\n        gc.collect()\n        if counter == no_batches-1:\n            counter = 0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Code for creating training and validation data generator\n\n'''train_datagen = image.ImageDataGenerator(rescale=1. / 255, validation_split=0.15, horizontal_flip=True,\n                                         vertical_flip=True, rotation_range=360, zoom_range=0.2, shear_range=0.1#,\n                                         #preprocessing_function=load_one_image \n                                        )\n\ntrain_generator = train_datagen.flow_from_dataframe(dataframe = pd.concat([x_train, y_train], axis=1),\n                                                    directory = TRAIN_IMG_PATH,\n                                                    x_col = 'ID',\n                                                    y_col = y_cols,\n                                                    batch_size = BATCH_SIZE,\n                                                    class_mode = 'multi_output',\n                                                    target_size = (IMG_DIM, IMG_DIM),\n                                                    subset = 'training',\n                                                    shuffle = True,\n                                                    seed = SEED,\n                                                    validate_filenames = False\n                                                    )\n\nvalid_generator = train_datagen.flow_from_dataframe(dataframe = pd.concat([x_val, y_val], axis=1),\n                                                    directory = TRAIN_IMG_PATH,\n                                                    x_col = 'ID',\n                                                    y_col = y_cols,\n                                                    batch_size = BATCH_SIZE,\n                                                    class_mode = 'multi_output',\n                                                    target_size = (IMG_DIM, IMG_DIM),\n                                                    subset = 'validation',\n                                                    shuffle = True,\n                                                    seed = SEED,\n                                                    validate_filenames = False\n                                                    )\n'''\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Code for creating testing data generator\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Configuration for the Network\n\nconf = dict()\n# Change this variable to 0 in case you want to use full dataset\nconf['use_sample_only'] = 1\n# Save weights\nconf['save_weights'] = 0\n# How many patients will be in train and validation set during training. Range: (0; 1)\nconf['train_valid_fraction'] = 0.5\n# Batch size for CNN [Depends on GPU and memory available]\nconf['batch_size'] = 200\n# Number of epochs for CNN training\nconf['nb_epoch'] = 40\n# Early stopping. Stop training after epochs without improving on validation\nconf['patience'] = 3\n# Shape of image for CNN (Larger the better, but you need to increase CNN as well)\nconf['image_shape'] = (64, 64)\n# Learning rate for CNN. Lower better accuracy, larger runtime.\nconf['learning_rate'] = 1e-2\n# Number of random samples to use during training per epoch \nconf['samples_train_per_epoch'] = 10000\n# Number of random samples to use during validation per epoch\nconf['samples_valid_per_epoch'] = 1000\n# Some variables to control CNN structure\nconf['level_1_filters'] = 4\nconf['level_2_filters'] = 8\nconf['dense_layer_size'] = 32\nconf['dropout_value'] = 0.5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Alternative Data generator\nfrom tensorflow.python.keras.utils import Sequence\nimport numpy as np  \n\nclass image_data_generator_multilbl(Sequence):\n    def __init__(self, x_set, y_set, batch_size):\n        self.x, self.y = x_set, y_set\n        self.batch_size = batch_size\n\n    def __len__(self):\n        return int(np.ceil(len(self.x) / float(self.batch_size)))\n\n    def __getitem__(self, idx):\n        x_col = 'ID'\n        y_cols = ['epidural','intraparenchymal','intraventricular','subarachnoid','subdural','any']\n        path = TRAIN_IMG_PATH\n        batch_x = self.x[idx * self.batch_size:(idx + 1) * self.batch_size]\n        batch_y = self.y[idx * self.batch_size:(idx + 1) * self.batch_size]\n        #print(batch_y.shape)\n        # read your data here using the batch lists, batch_x and batch_y\n        x = [load_and_normalize_dicom(path+filename,224,224,NO_CHANNEL) for filename in batch_x[x_col]] \n        y = []\n        for k in range(0,self.batch_size):\n            subtypes_lst = []\n            for col in y_cols:\n                #print(batch_y.iloc[k][col])\n                is_subtype = int(batch_y.iloc[k][col])\n                subtypes_lst.append(is_subtype) \n            y.append(np.array(subtypes_lst))\n        return (np.array(x), np.array(y))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Code for defining callbacks: EarlyStopping and ReduceLROnPlateau\n\neraly_stop = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=3, verbose=1, mode='auto')\n# Reducing the Learning Rate if result is not improving. \nreduce_lr = ReduceLROnPlateau(monitor='val_loss', min_delta=0.0004, patience=2, factor=0.1, min_lr=1e-6, mode='auto',\n                              verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Code for compiling the model\nepochs = 10\nlrate = 0.01\ndecay = lrate/epochs\n#sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)\n#model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer = Adam(lr=1e-5), loss='categorical_crossentropy', metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''xy_train = pd.concat([x_train,y_train], axis=1)\nxy_val = pd.concat([x_val,y_val], axis=1)\nhistory = model.fit_generator(generator=batch_generator_train_multilbl(path=TRAIN_IMG_PATH, df=xy_train, x_col='ID', y_cols=y_cols, batch_size=BATCH_SIZE, target_size=(224, 224)), \n                              validation_data=batch_generator_train_multilbl(path=TRAIN_IMG_PATH, df=xy_val, x_col='ID', y_cols=y_cols, batch_size=BATCH_SIZE, target_size=(224, 224)), \n                              epochs = epochs, \n                              steps_per_epoch=xy_train.shape[0],#//BATCH_SIZE,\n                              validation_steps=xy_val.shape[0],#//BATCH_SIZE,\n                              #samples_per_epoch=BATCH_SIZE,\n                              callbacks=[eraly_stop, reduce_lr],\n                              use_multiprocessing=True, \n                              workers=4,\n                              shuffle=True,\n                              verbose=1\n                            )'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#xy_train = pd.concat([x_train,y_train], axis=1)\n#xy_val = pd.concat([x_val,y_val], axis=1)\nhistory = model.fit_generator(generator=image_data_generator_multilbl(x_train, y_train, BATCH_SIZE), \n                              validation_data=image_data_generator_multilbl(x_train, y_train, BATCH_SIZE), \n                              epochs = epochs, \n                              #steps_per_epoch=x_train.shape[0]//BATCH_SIZE,\n                              #validation_steps=x_val.shape[0]//BATCH_SIZE,\n                              callbacks=[eraly_stop, reduce_lr],\n                              use_multiprocessing=False, \n                              #workers=4,\n                              verbose=1\n                            )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"L=[[1,2,3],[4,5,6]]\nA=np.array([[1,2,3],[4,5,6]])\nprint(A.shape)\nB=np.stack([A,A])\nB=B.reshape((2,3,2))\nprint(B.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen=batch_generator_train_multilbl(path=TRAIN_IMG_PATH, df=xy_train, x_col='ID', y_cols=y_cols, batch_size=BATCH_SIZE, target_size=(224, 224))\ntrain_datagen","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_train.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"(y_train[0:64]).shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}