{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import warnings; warnings.filterwarnings('ignore')\nimport pandas as pd, numpy as np\nimport matplotlib.pyplot as plt\n\nimport os, zipfile, random, csv\nimport seaborn as sns\nimport pydicom as dcm\nfrom glob import glob\nimport cv2","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# # Install packages\n#!pip install -q pydicom","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nprint(f'Current working directory: {os.getcwd()}')\nprint('Folder and Files in current directory: {}'.format(os.listdir()))\nPATH = '/kaggle/'\nDATA_FOLDER = os.path.join(PATH, 'input/rsna-pneumonia-detection-challenge/')\nFolder_DCM_IMAGES = os.path.join(DATA_FOLDER,'stage_2_train_images/')\n\nWORKING_FOLDER = os.path.join(PATH,'working/')\nSAVE_PATH = os.path.join(WORKING_FOLDER,'Saved_Data/')\n\nif not os.path.exists(SAVE_PATH):\n    os.makedirs(SAVE_PATH)\n    \n\nprint(\"DATA_FOLDER: \", DATA_FOLDER)  \nprint(\"Folder_DCM_IMAGES: \", Folder_DCM_IMAGES) \nprint(\"SAVE_PATH: \", SAVE_PATH) \nprint(\"WORKING_FOLDER: \", WORKING_FOLDER) \n\nos.chdir(WORKING_FOLDER)\nprint(f'Current working directory: {os.getcwd()}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Loading Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_labels = pd.read_csv(os.path.join(DATA_FOLDER,'stage_2_train_labels.csv'))\nclass_info = pd.read_csv(os.path.join(DATA_FOLDER,'stage_2_detailed_class_info.csv'))\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"EDA","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f'Train Labels dataframe has {train_labels.shape[0]} rows and {train_labels.shape[1]} columns')\nprint(f'Class info dataframe has {class_info.shape[0]} rows and {class_info.shape[1]} columns')\nprint('Number of duplicates in patientID in train labels dataframe: {}'.format(len(train_labels) - (train_labels['patientId'].nunique())))\nprint('Number of duplicates in patientID in class info dataframe: {}'.format(len(class_info) - (class_info['patientId'].nunique())))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Train labels dataframe:\\n'); display(train_labels.head())\nprint('\\nClass info dataframe:\\n'); display(class_info.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Checking value counts for the targets: {}'.format(train_labels['Target'].value_counts().to_dict()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def fetchDCMFileInfo(patient_id):\n    dcm_file = Folder_DCM_IMAGES + '{}.dcm'.format(patient_id)\n    dcm_data = dcm.read_file(dcm_file)\n    return dcm_data\n\nprint(fetchDCMFileInfo(train_labels['patientId'][1]))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Observation\nDCM file contains some of the information such as \n* patient sex, age\n* body part of which image is taken (Here, in this case its chest)\n* view position and modality\n* Size of this image is 1024 x 1024","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"patientId = train_labels['patientId'][0]\npatient = train_labels.loc[train_labels['patientId'] == patientId].iloc[0]\npatient","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def showImage(patient):\n    path = Folder_DCM_IMAGES + '{}.dcm'.format(patient['patientId'])\n    dsimage = dcm.dcmread(path)\n    plt.figure(figsize= (5,5))  \n    plt.imshow(dsimage.pixel_array, cmap = plt.cm.bone)\n    #print(f'patient_id: {patient[\"patientid\"]}')\n    plt.show()\n\npatientId = train_labels['patientId'][1]\npatient = train_labels.loc[train_labels['patientId'] == patientId].iloc[0]\nshowImage(patient)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def count_missing_data(data_df):\n    total = data_df.isnull().sum().sort_values(ascending = False)\n    #percent = (data_df.isnull().sum()/data_df.isnull().count()*100).sort_values(ascending = False)\n    return pd.concat([total], axis=1, keys=['Total'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"count_missing_data(train_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"count_missing_data(class_info)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Observation\n* The train labels dataset (stage_2_train_labels.csv with target value) have lots of missing x,y and bounding box data\n* There is no data missing for the class information dataset (stage_2_detailed_class_info.csv with class)\n* As next steps, we will merge both the dataset and then again look for missing data in merge dataset","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"#  Class distribution from the class details","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"f, ax = plt.subplots(1,1, figsize=(8,8))\nsns.countplot(class_info['class'],order = class_info['class'].value_counts().index)\n\ntotal = float(len(class_info))\nfor p in ax.patches:\n    height = p.get_height()\n    ax.text(p.get_x()+p.get_width()/2,\n            height + 113,'{:d}'.format(height),\n            ha=\"center\") \nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Merge train and class info details","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_class_df = train_labels.merge(class_info, left_on='patientId', right_on='patientId', how='inner')\ntrain_class_df.sample(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_class_df.describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_class_df.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_class_df['class'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Observation\nThe records are as expected\n* All records with Target = 1 associated with class: Lung Opacity.\n* All records with Target = 0 are either of class: \"Normal\" or \"No Lung Opacity / Not Normal\".","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"#### Determining presence of null values","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_class_df.isna().sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_class_df.isnull().sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_class_df.Target.value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Observation\n* There is **NO** null values in dataset","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#number of patient ids having multiple id's with there count of entries\ntrain_class_df['patientId'].value_counts().value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# check for duplicate reconrds in training set\nprint(\"Unique patientId in  train_class_df: \", train_class_df['patientId'].nunique())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"No of rows in train_class_df: \", train_class_df.shape[0])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Determing how the duplicates are in each class and target","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_class_df.Target.value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tmp = train_class_df.groupby(['patientId','Target', 'class'])['patientId'].count()\ndf = pd.DataFrame(data={'Records': tmp.values}, index=tmp.index).reset_index()\ndupcount = df.groupby(['Records','Target','class']).count()\ndupcount","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# getting duplicate count for Target == 1; pneumonia present\ntrain_class_df[train_class_df['Target'] == 1]['patientId'].value_counts().value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# getting duplicate count for Target == 0; pneumonia absent\ntrain_class_df[train_class_df['Target'] == 0]['patientId'].value_counts().value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Observation\n* There is *NO\" duplicate entries for patients without pneunmonia.\n* There are duplicate entries for patients having pneunmonia. Duplicate entries correspond to multiple Bounding boxes \n* The duplicates might *NOT* have a significant impact, so **dropping the duplicates**","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#train_class_df.drop_duplicates(inplace=True)\n#train_class_df.reset_index(inplace=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_class_df.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Class info for Pneumonia and Non Pneumonia cases\ntrain_class_df['class'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Let's plot the number of patients for each class grouped by Target value.\nfig, ax = plt.subplots(nrows=1,figsize=(12,6))\ntmp = train_class_df.groupby('Target')['class'].value_counts()\ndf = pd.DataFrame(data={'Counts': tmp.values}, index=tmp.index).reset_index()\nsns.barplot(ax=ax,x = 'Target', y='Counts',hue='class',data=df)\nplt.title(\"Class and Target\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Determining if there are x,y values of bounding boxes info for Pneumonia and Non Pneumonia cases\nprint ('X value count of bounding box information for pnuemonia Cases: ',train_class_df[train_class_df.Target==1]['x'].count())\nprint ('X value count of bounding box information for Non-pnuemonia Cases: ',train_class_df[train_class_df.Target==0]['x'].count())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Observation\nif pneumonia is detected, there is Bounding Box and for Non pneumonia cases, there is no Bounding Box\n* if Lung Opacity is present, it indicates Pneunomonia and vice versa.\n* if Lung Opacity is absent, it indicates normal / not Normal.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"#### Plot the density of x, y, width and height for Target = 1","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"target1 = train_class_df[train_class_df['Target']==1]\nplt.figure()\nfig, ax = plt.subplots(2,2,figsize=(12,12))\nsns.distplot(target1['x'],kde=True,bins=50, color=\"red\", ax=ax[0,0])\nsns.distplot(target1['y'],kde=True,bins=50, color=\"green\", ax=ax[0,1])\nsns.distplot(target1['width'],kde=True,bins=50, color=\"blue\", ax=ax[1,0])\nsns.distplot(target1['height'],kde=True,bins=50, color=\"yellow\", ax=ax[1,1])\nlocs, labels = plt.xticks()\nplt.tick_params(axis='both')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Process dicom images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def fetch_image_details(i,data_row,f, ax):\n        patientImage = data_row['patientId']+'.dcm'\n        imagePath = os.path.join(Folder_DCM_IMAGES,patientImage)\n        data_row_img_data = dcm.read_file(imagePath)\n        modality = data_row_img_data.Modality\n        age = data_row_img_data.PatientAge\n        sex = data_row_img_data.PatientSex\n        data_row_img = dcm.dcmread(imagePath)\n        ax[i//3, i%3].imshow(data_row_img.pixel_array, cmap=plt.cm.bone) \n        ax[i//3, i%3].axis('off')\n        ax[i//3, i%3].set_title('ID: {}\\nModality: {} Age: {} Sex: {} Target: {}\\nClass: {}'.format(\n                data_row['patientId'],modality, age, sex, data_row['Target'], data_row['class']))\n\ndef show_dicom_images(data):\n    img_data = list(data.T.to_dict().values())\n    f, ax = plt.subplots(2,3, figsize=(16,12))\n    for i,data_row in enumerate(img_data):\n        fetch_image_details(i,data_row,f, ax)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Images with target = 0 (Not having pneunmonia, class = No lung opacity / Not Normal)\")\nshow_dicom_images(train_class_df[train_class_df['Target']==0].sample(6))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Images with target = 1 (having pneunmonia, class = lung opacity)\")\nshow_dicom_images(train_class_df[train_class_df['Target']==1].sample(6))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Overlay of the bounding boxes on opacity","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from matplotlib.patches import Rectangle\nimport matplotlib.patches as patches\ndef show_dicom_images_with_boxes(data):\n    img_data = list(data.T.to_dict().values())\n    f, ax = plt.subplots(2,3, figsize=(16,12))\n    for i,data_row in enumerate(img_data):\n        fetch_image_details(i,data_row,f, ax)\n        rows = train_class_df[train_class_df['patientId']==data_row['patientId']]\n        box_data = list(rows.T.to_dict().values())\n        for j, row in enumerate(box_data):\n            ax[i//3, i%3].add_patch(patches.Rectangle(xy=(row['x'], row['y']),\n                        width=row['width'],height=row['height'],  linewidth=2, edgecolor='r', facecolor='none'))\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_dicom_images_with_boxes(train_class_df[train_class_df['Target']==1].sample(6))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"MODEL\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#01b15f07-1149-4ff8-9756-bc821e41b97c.dcm\nprint(fetchDCMFileInfo('01b15f07-1149-4ff8-9756-bc821e41b97c'))\nprint(fetchDCMFileInfo('ce84731f-95b7-473e-ad1b-125523a3a71e'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport csv\nimport random\nimport pydicom\nimport numpy as np\nimport pandas as pd\nfrom skimage import io\nfrom skimage import measure\nfrom skimage.transform import resize\n\nimport tensorflow as tf\nfrom tensorflow import keras\n\nfrom matplotlib import pyplot as plt\nimport matplotlib.patches as patches","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# empty dictionary\npneumonia_locations = {}\n# load table\nwith open(os.path.join(DATA_FOLDER+'/stage_2_train_labels.csv'), mode='r') as infile:\n    # open reader\n    reader = csv.reader(infile)\n    # skip header\n    next(reader, None)\n    # loop through rows\n    for rows in reader:\n        # retrieve information\n        filename = rows[0]\n        location = rows[1:5]\n        pneumonia = rows[5]\n        # if row contains pneumonia add label to dictionary\n        # which contains a list of pneumonia locations per filename\n        if pneumonia == '1':\n            # convert string to float to int\n            location = [int(float(i)) for i in location]\n            # save pneumonia location in dictionary\n            if filename in pneumonia_locations:\n                pneumonia_locations[filename].append(location)\n            else:\n                pneumonia_locations[filename] = [location]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#load and shuffle filenames\nfolder = Folder_DCM_IMAGES #PATH+'/stage_2_train_images'\nfilenames = os.listdir(folder)\nrandom.shuffle(filenames)\n# split into train and validation filenames\nn_valid_samples = 2560\ntrain_filenames = filenames[n_valid_samples:]\nvalid_filenames = filenames[:n_valid_samples]\nprint('n train samples', len(train_filenames))\nprint('n valid samples', len(valid_filenames))\nn_train_samples = len(filenames) - n_valid_samples\nprint('Total train images:',len(filenames))\nprint('Images with pneumonia:', len(pneumonia_locations))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class generator(keras.utils.Sequence):\n    \n    def __init__(self, folder, filenames, pneumonia_locations=None, batch_size=32, image_size=128, shuffle=True, augment=False, predict=False):\n        self.folder = folder\n        self.filenames = filenames\n        self.pneumonia_locations = pneumonia_locations\n        self.batch_size = batch_size\n        self.image_size = image_size\n        self.shuffle = shuffle\n        self.augment = augment\n        self.predict = predict\n        self.on_epoch_end()\n        \n    def __load__(self, filename):\n        # load dicom file as numpy array\n        img = pydicom.dcmread(os.path.join(self.folder, filename)).pixel_array\n        # create empty mask\n        msk = np.zeros(img.shape)\n        # get filename without extension\n        filename = filename.split('.')[0]\n        # if image contains pneumonia\n        if filename in self.pneumonia_locations:\n            # loop through pneumonia\n            for location in self.pneumonia_locations[filename]:\n                # add 1's at the location of the pneumonia\n                x, y, w, h = location\n                msk[y:y+h, x:x+w] = 1\n        # resize both image and mask\n        img = resize(img, (self.image_size, self.image_size), mode='reflect')\n        msk = resize(msk, (self.image_size, self.image_size), mode='reflect') > 0.5\n        # if augment then horizontal flip half the time\n        if self.augment and random.random() > 0.5:\n            img = np.fliplr(img)\n            msk = np.fliplr(msk)\n        # add trailing channel dimension\n        img = np.expand_dims(img, -1)\n        msk = np.expand_dims(msk, -1)\n        return img, msk\n    \n    def __loadpredict__(self, filename):\n        # load dicom file as numpy array\n        img = pydicom.dcmread(os.path.join(self.folder, filename)).pixel_array\n        # resize image\n        img = resize(img, (self.image_size, self.image_size), mode='reflect')\n        # add trailing channel dimension\n        img = np.expand_dims(img, -1)\n        return img\n        \n    def __getitem__(self, index):\n        # select batch\n        filenames = self.filenames[index*self.batch_size:(index+1)*self.batch_size]\n        # predict mode: return images and filenames\n        if self.predict:\n            # load files\n            imgs = [self.__loadpredict__(filename) for filename in filenames]\n            # create numpy batch\n            imgs = np.array(imgs)\n            return imgs, filenames\n        # train mode: return images and masks\n        else:\n            # load files\n            items = [self.__load__(filename) for filename in filenames]\n            # unzip images and masks\n            imgs, msks = zip(*items)\n            # create numpy batch\n            imgs = np.array(imgs)\n            msks = np.array(msks)\n            return imgs, msks\n        \n    def on_epoch_end(self):\n        if self.shuffle:\n            random.shuffle(self.filenames)\n        \n    def __len__(self):\n        if self.predict:\n            # return everything\n            return int(np.ceil(len(self.filenames) / self.batch_size))\n        else:\n            # return full batches only\n            return int(len(self.filenames) / self.batch_size)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_downsample(channels, inputs):\n    x = keras.layers.BatchNormalization(momentum=0.9)(inputs)\n    x = keras.layers.LeakyReLU(0)(x)\n    x = keras.layers.Conv2D(channels, 1, padding='same', use_bias=False)(x)\n    x = keras.layers.MaxPool2D(2)(x)\n    return x\n\n\ndef create_resblock(channels, inputs):\n    x = keras.layers.BatchNormalization(momentum=0.9)(inputs)\n    x = keras.layers.LeakyReLU(0)(x)\n    x = keras.layers.Conv2D(channels, 3, padding='same', use_bias=False)(x)\n    x = keras.layers.BatchNormalization(momentum=0.9)(x)\n    x = keras.layers.LeakyReLU(0)(x)\n    x = keras.layers.Conv2D(channels, 3, padding='same', use_bias=False)(x)\n    return keras.layers.add([x, inputs])\n\ndef create_network(input_size, channels, n_blocks=2, depth=4):\n    # input\n    inputs = keras.Input(shape=(input_size, input_size, 1))\n    x = keras.layers.Conv2D(channels, 3, padding='same', use_bias=False)(inputs)\n    # residual blocks\n    for d in range(depth):\n        channels = channels * 2\n        x = create_downsample(channels, x)\n        for b in range(n_blocks):\n            x = create_resblock(channels, x)\n    # output\n    x = keras.layers.BatchNormalization(momentum=0.9)(x)\n    x = keras.layers.LeakyReLU(0)(x)\n    x = keras.layers.Conv2D(1, 1, activation='sigmoid')(x)\n    outputs = keras.layers.UpSampling2D(2**depth)(x)\n    model = keras.Model(inputs=inputs, outputs=outputs)\n    return model\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def iou_loss(y_true, y_pred):\n    y_true = tf.reshape(y_true, [-1])\n    y_pred = tf.reshape(y_pred, [-1])\n    intersection = tf.reduce_sum(y_true * y_pred)\n    score = (intersection + 1.) / (tf.reduce_sum(y_true) + tf.reduce_sum(y_pred) - intersection + 1.)\n    return 1 - score\n\n# combine bce loss and iou loss\ndef iou_bce_loss(y_true, y_pred):\n    return 0.5 * keras.losses.binary_crossentropy(y_true, y_pred) + 0.5 * iou_loss(y_true, y_pred)\n\n# mean iou as a metric\ndef mean_iou(y_true, y_pred):\n    y_pred = tf.round(y_pred)\n    intersect = tf.reduce_sum(y_true * y_pred, axis=[1, 2, 3])\n    union = tf.reduce_sum(y_true, axis=[1, 2, 3]) + tf.reduce_sum(y_pred, axis=[1, 2, 3])\n    smooth = tf.ones(tf.shape(intersect))\n    return tf.reduce_mean((intersect + smooth) / (union - intersect + smooth))\n\ndef cosine_annealing(x):\n    lr = 0.001\n    epochs = 25\n    return lr*(np.cos(np.pi*x/epochs)+1.)/2\nlearning_rate = tf.keras.callbacks.LearningRateScheduler(cosine_annealing)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# from tensorflow.keras.applications.mobilenet import MobileNet, preprocess_input\n# from tensorflow.keras.layers import Concatenate, Conv2D, UpSampling2D, Reshape\n# from tensorflow.keras.models import Model\n\n# IMAGE_HEIGHT = 1024\n# IMAGE_WIDTH = 1024\n# image_size = 224\n# ALPHA = 1 # Width hyper parameter for MobileNet (0.25, 0.5, 0.75, 1.0). Higher width means more accurate but slower\n\n# HEIGHT_CELLS = 128\n# WIDTH_CELLS = 128\n\n# CELL_WIDTH = IMAGE_WIDTH / WIDTH_CELLS\n# CELL_HEIGHT = IMAGE_HEIGHT / HEIGHT_CELLS\n\n# EPOCHS = 1\n# BATCH_SIZE = 4\n# PATIENCE = 10\n\n# THREADS = 1\n\n# def create_modelUnet(trainable=True):\n#      model = MobileNet(input_shape=(IMAGE_HEIGHT, IMAGE_WIDTH, 3), include_top=False, alpha=ALPHA, weights=\"imagenet\")\n\n#     for layer in model.layers:\n#         layer.trainable = trainable\n\n#     block1 = model.get_layer(\"conv_pw_5_relu\").output\n#     block2 = model.get_layer(\"conv_pw_11_relu\").output\n#     block3 = model.get_layer(\"conv_pw_13_relu\").output\n\n#     x = Concatenate()([UpSampling2D()(block3), block2])\n#     x = Concatenate()([UpSampling2D()(x), block1])\n\n#     x = Conv2D(1, kernel_size=1, activation=\"sigmoid\")(x)\n#     x = Reshape((HEIGHT_CELLS, WIDTH_CELLS))(x)\n\n#     return Model(inputs=model.input, outputs=x)\n\n# def dice_coefficient(y_true, y_pred):\n#     numerator = 2 * tf.reduce_sum(y_true * y_pred)\n#     denominator = tf.reduce_sum(y_true + y_pred)\n\n#     return numerator / (denominator + tf.keras.backend.epsilon())\n\n# def loss(y_true, y_pred):\n#     return 0.5 * keras.losses.binary_crossentropy(y_true, y_pred) + 0.5 * iou_loss(y_true, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n# create network and compiler\nmodel = create_network(input_size=128, channels=32, n_blocks=2, depth=4) #create_model(True) # \n\n                       \n# model.compile(optimizer='adam',\n#               loss=iou_bce_loss,\n#               metrics=['accuracy', mean_iou])\n\n\n#model.compile(loss=\"mean_squared_error\", optimizer=\"adam\", metrics=['accuracy', mean_iou]) # Regression loss is MSE\n\n#model.compile(loss='categorical_crossentropy', optimizer=\"adam\", metrics=['accuracy', mean_iou]) # Regression loss is MSE\n\nmodel.compile(loss='binary_crossentropy', optimizer=\"adam\", metrics=['accuracy', mean_iou]) # Regression loss is MSE\n\n\n#model = create_modelUnet(create_model(True)) # \n\nprint(\"model summary:\", model.summary())\n# cosine learning rate annealing","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau\n# model = create_model(False)\n\n\n# optimizer = Adam(lr=1e-4, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)\n# model.compile(loss=loss, optimizer=optimizer, metrics=[dice_coefficient])\n\n# model.summary()\nPATIENCE = 10\n\ncheckpoint = ModelCheckpoint(SAVE_PATH + \"model-{val_loss:.2f}.h5\", monitor=\"val_loss\", verbose=1, save_best_only=True,\n                             save_weights_only=True, mode=\"auto\", period=1)\nstop = EarlyStopping(monitor=\"val_loss\", patience=PATIENCE, mode=\"auto\")\nreduce_lr = ReduceLROnPlateau(monitor=\"val_loss\", factor=0.2, patience=5, min_lr=1e-6, verbose=1, mode=\"auto\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# create train and validation generators\nfolder = Folder_DCM_IMAGES #PATH+'/stage_2_train_images'\ntrain_gen = generator(folder, train_filenames[0:500], pneumonia_locations, batch_size=16, image_size=128, shuffle=True, augment=True, predict=False)\nvalid_gen = generator(folder, valid_filenames[0:100], pneumonia_locations, batch_size=16, image_size=128, shuffle=False, predict=False)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit_generator(generator=train_gen,\n                    epochs=5,\n                    validation_data=valid_gen,\n                    callbacks=[checkpoint, reduce_lr, stop],\n                    workers=4,\n                    use_multiprocessing=False,\n                    shuffle=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pickle\nhistory_data_pickle_file = SAVE_PATH + \"history_data.pickle\" \nwith open(history_data_pickle_file, \"wb\") as file_:\n    pickle.dump(history.history, file_, -1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"datafrompickle = pickle.load(open(history_data_pickle_file, \"rb\", -1))\ndatafrompickle\nmodelHistory = datafrompickle","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(25,6))\nplt.subplot(131)\nplt.plot(modelHistory.epoch, modelHistory.history[\"loss\"], label=\"Train loss\")\nplt.plot(modelHistory.epoch, modelHistory.history[\"val_loss\"], label=\"Valid loss\")\nplt.legend()\nplt.subplot(132)\nplt.plot(modelHistory.epoch, modelHistory.history[\"accuracy\"], label=\"Train accuracy\")\nplt.plot(modelHistory.epoch, modelHistory.history[\"val_accuracy\"], label=\"Valid accuracy\")\nplt.legend()\nplt.subplot(133)\nplt.plot(modelHistory.epoch, modelHistory.history[\"mean_iou\"], label=\"Train iou\")\nplt.plot(modelHistory.epoch, modelHistory.history[\"val_mean_iou\"], label=\"Valid iou\")\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# load and shuffle filenames\nfolder = '/stage_2_test_images'\ntest_filenames = os.listdir(folder)[:100]\nprint('n test samples:', len(test_filenames))\n\n# create test generator with predict flag set to True\ntest_gen = generator(folder, test_filenames, None, batch_size=25, image_size=image_dimension, shuffle=False, predict=True)\n\n# create submission dictionary\nsubmission_dict = {}\n# loop through testset\nfor imgs, filenames in test_gen:\n    # predict batch of images\n    preds = model.predict(imgs)\n    # loop through batch\n    for pred, filename in zip(preds, filenames):\n        # resize predicted mask\n        pred = resize(pred, (1024, 1024), mode='reflect')\n        # threshold predicted mask\n        comp = pred[:, :, 0] > 0.5\n        # apply connected components\n        comp = measure.label(comp)\n        # apply bounding boxes\n        predictionString = ''\n        for region in measure.regionprops(comp):\n            # retrieve x, y, height and width\n            y, x, y2, x2 = region.bbox\n            height = y2 - y\n            width = x2 - x\n            # proxy for confidence score\n            conf = np.mean(pred[y:y+height, x:x+width])\n            # add to predictionString\n            predictionString += str(conf) + ' ' + str(x) + ' ' + str(y) + ' ' + str(width) + ' ' + str(height) + ' '\n        # add filename and predictionString to dictionary\n        filename = filename.split('.')[0]\n        submission_dict[filename] = predictionString\n    # stop if we've got them all\n    if len(submission_dict) >= len(test_filenames):\n        break\n\n# save dictionary as csv file\nsub = pd.DataFrame.from_dict(submission_dict,orient='index')\nsub.index.names = ['patientId']\nsub.columns = ['PredictionString']\nsub.to_csv(SAVE_PATH+'pneumonia_model_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\npred = model.predict(x_test)\npred = np.argmax(pred,axis = 1) \ny_true = np.argmax(y_test,axis = 1)","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":4}