{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom matplotlib import pyplot as plt\nimport seaborn as sns\nimport pydicom as dcm\nimport os\nimport cv2\nimport gc\nimport glob\nfrom tqdm import tqdm\nfrom matplotlib.patches import Rectangle\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.applications.mobilenet import preprocess_input","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:18:06.307464Z","iopub.execute_input":"2021-08-31T16:18:06.307923Z","iopub.status.idle":"2021-08-31T16:18:11.906455Z","shell.execute_reply.started":"2021-08-31T16:18:06.307803Z","shell.execute_reply":"2021-08-31T16:18:11.90551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = pd.read_csv('../input/rsna-pneumonia-detection-challenge/stage_2_train_labels.csv')\ndetails = pd.read_csv('../input/rsna-pneumonia-detection-challenge/stage_2_detailed_class_info.csv')","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:18:11.908063Z","iopub.execute_input":"2021-08-31T16:18:11.908421Z","iopub.status.idle":"2021-08-31T16:18:12.047229Z","shell.execute_reply.started":"2021-08-31T16:18:11.908382Z","shell.execute_reply":"2021-08-31T16:18:12.046307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# duplicates in details just have the same class so can be safely dropped\ndetails = details.drop_duplicates('patientId').reset_index(drop=True)\nlabels_w_class = labels.merge(details, how='inner', on='patientId')","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:18:12.05055Z","iopub.execute_input":"2021-08-31T16:18:12.050867Z","iopub.status.idle":"2021-08-31T16:18:12.108006Z","shell.execute_reply.started":"2021-08-31T16:18:12.050832Z","shell.execute_reply":"2021-08-31T16:18:12.10713Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_w_class.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-31T15:55:06.581552Z","iopub.execute_input":"2021-08-31T15:55:06.581883Z","iopub.status.idle":"2021-08-31T15:55:06.605754Z","shell.execute_reply.started":"2021-08-31T15:55:06.581855Z","shell.execute_reply":"2021-08-31T15:55:06.604744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Dealing with missing values","metadata":{}},{"cell_type":"code","source":"labels_w_class.info()\n# No null values in patientId ,Target and Class","metadata":{"execution":{"iopub.status.busy":"2021-08-31T15:55:09.558147Z","iopub.execute_input":"2021-08-31T15:55:09.558469Z","iopub.status.idle":"2021-08-31T15:55:09.58364Z","shell.execute_reply.started":"2021-08-31T15:55:09.558441Z","shell.execute_reply":"2021-08-31T15:55:09.582767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# null values in x, y, width, height indicates that there is no pneumonia. Replacing null with 0\nlabels_w_class.fillna(0, inplace=True)\nlabels_w_class.info()","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:18:14.200298Z","iopub.execute_input":"2021-08-31T16:18:14.200652Z","iopub.status.idle":"2021-08-31T16:18:14.23337Z","shell.execute_reply.started":"2021-08-31T16:18:14.200619Z","shell.execute_reply":"2021-08-31T16:18:14.232248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_df = labels_w_class.head(6000)\nnew_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:18:16.346474Z","iopub.execute_input":"2021-08-31T16:18:16.346857Z","iopub.status.idle":"2021-08-31T16:18:16.370193Z","shell.execute_reply.started":"2021-08-31T16:18:16.346799Z","shell.execute_reply":"2021-08-31T16:18:16.369049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_train, class_val = train_test_split(new_df, test_size=0.20, random_state=42, stratify=new_df['class'])","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:18:19.445703Z","iopub.execute_input":"2021-08-31T16:18:19.44609Z","iopub.status.idle":"2021-08-31T16:18:19.465592Z","shell.execute_reply.started":"2021-08-31T16:18:19.446056Z","shell.execute_reply":"2021-08-31T16:18:19.464604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_SIZE = 1024\nADJUSTED_IMAGE_SIZE=224\nMASK_IMAGE_SIZE = 28\nFACTOR = MASK_IMAGE_SIZE/IMAGE_SIZE","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:18:20.862782Z","iopub.execute_input":"2021-08-31T16:18:20.863358Z","iopub.status.idle":"2021-08-31T16:18:20.867894Z","shell.execute_reply.started":"2021-08-31T16:18:20.863315Z","shell.execute_reply":"2021-08-31T16:18:20.866781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_feature_tr = []\ny_feature_target_tr = []\ny_feature_coordinates_tr = []\nfrom PIL import Image\ntrain_images_dir = '../input/rsna-pneumonia-detection-challenge/stage_2_train_images/'\ndef create_mask(datafm):\n    X = []\n    y=[]\n    masks = np.zeros((int(datafm.shape[0]), MASK_IMAGE_SIZE, MASK_IMAGE_SIZE))\n    for index, patient_id in enumerate(datafm['patientId'].T.to_dict().values()):\n        image_path = train_images_dir+patient_id+\".dcm\"\n        img = dcm.read_file(image_path)\n        img = img.pixel_array\n        img = cv2.resize(img, (ADJUSTED_IMAGE_SIZE, ADJUSTED_IMAGE_SIZE), interpolation=cv2.INTER_NEAREST)\n        img = Image.fromarray(img)\n        img = img.convert('RGB')\n        img = preprocess_input(np.array(img, dtype=np.float32))\n        X.append(img)\n        rows = labels_w_class[labels_w_class['patientId']==patient_id]\n        y.append(rows['Target'].values[0])\n\n        row_data = list(rows.T.to_dict().values())\n        for row in row_data:\n            x1 = int(row['x']*FACTOR)\n            x2 = int((row['x']*FACTOR)+(row['width']*FACTOR))\n            y1 = int(row['y']*FACTOR)\n            y2 = int((row['y']*FACTOR)+(row['height']*FACTOR))\n            masks[index][y1:y2, x1:x2] = 1\n    del img,row,row_data\n    gc.collect()\n    X=np.array(X)\n    y=np.array(y)\n    return X, y, masks","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:18:22.405124Z","iopub.execute_input":"2021-08-31T16:18:22.405519Z","iopub.status.idle":"2021-08-31T16:18:22.41678Z","shell.execute_reply.started":"2021-08-31T16:18:22.405487Z","shell.execute_reply":"2021-08-31T16:18:22.415901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train, y_tr_target, y_train = create_mask(class_train)\nX_val, y_val_target, y_val = create_mask(class_val)","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:18:24.965349Z","iopub.execute_input":"2021-08-31T16:18:24.965732Z","iopub.status.idle":"2021-08-31T16:20:18.455056Z","shell.execute_reply.started":"2021-08-31T16:18:24.965679Z","shell.execute_reply":"2021-08-31T16:20:18.454007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Model I : U-Net\nfrom tensorflow.keras.applications.mobilenet import MobileNet\nfrom tensorflow.keras.layers import Concatenate, Conv2D, Reshape, UpSampling2D\nfrom tensorflow.keras.models import Model, load_model\nimport tensorflow as tf\nfrom tensorflow import keras","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:20:18.456791Z","iopub.execute_input":"2021-08-31T16:20:18.457153Z","iopub.status.idle":"2021-08-31T16:20:18.463793Z","shell.execute_reply.started":"2021-08-31T16:20:18.457115Z","shell.execute_reply":"2021-08-31T16:20:18.463078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#this function will creat U-net model\ndef create_model(trainable=True):\n    model = MobileNet(input_shape=(224, 224, 3), include_top=False, 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((28, 28))(x)\n\n    return Model(inputs=model.input, outputs=x)","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:20:18.465975Z","iopub.execute_input":"2021-08-31T16:20:18.4664Z","iopub.status.idle":"2021-08-31T16:20:18.475294Z","shell.execute_reply.started":"2021-08-31T16:20:18.466365Z","shell.execute_reply":"2021-08-31T16:20:18.474414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = create_model(False)\n#model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:20:18.47671Z","iopub.execute_input":"2021-08-31T16:20:18.477073Z","iopub.status.idle":"2021-08-31T16:20:21.274318Z","shell.execute_reply.started":"2021-08-31T16:20:18.477037Z","shell.execute_reply":"2021-08-31T16:20:21.273276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(X_train.shape)\nprint(y_train.shape)\nprint(X_val.shape)\nprint(y_val.shape)","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:00:52.710846Z","iopub.execute_input":"2021-08-31T16:00:52.711344Z","iopub.status.idle":"2021-08-31T16:00:52.717068Z","shell.execute_reply.started":"2021-08-31T16:00:52.711308Z","shell.execute_reply":"2021-08-31T16:00:52.71616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# define iou or jaccard loss function\ndef 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)\n    union = tf.reduce_sum(y_true) + tf.reduce_sum(y_pred)\n    smooth = tf.ones(tf.shape(intersect))\n    return tf.reduce_mean((intersect + smooth) / (union - intersect + smooth))\n\n\ndef dice_coefficient(y_true, y_pred):\n    numerator = 2 * tensorflow.reduce_sum(y_true * y_pred)\n    denominator = tensorflow.reduce_sum(y_true + y_pred)\n\n    return numerator / (denominator + tensorflow.keras.backend.epsilon())\n","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:20:21.275769Z","iopub.execute_input":"2021-08-31T16:20:21.276235Z","iopub.status.idle":"2021-08-31T16:20:21.285683Z","shell.execute_reply.started":"2021-08-31T16:20:21.276159Z","shell.execute_reply":"2021-08-31T16:20:21.284608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.losses import binary_crossentropy\n\nmodel.compile(optimizer='adam',\n              loss=iou_bce_loss,\n              metrics=['accuracy', mean_iou])","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:20:44.112047Z","iopub.execute_input":"2021-08-31T16:20:44.112415Z","iopub.status.idle":"2021-08-31T16:20:44.130561Z","shell.execute_reply.started":"2021-08-31T16:20:44.112382Z","shell.execute_reply":"2021-08-31T16:20:44.129544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\n\ncheckpoint = ModelCheckpoint(\"model-{val_loss:.2f}.h5\", monitor=\"val_loss\", verbose=1, \n                             save_best_only=True, save_weights_only=True)\n\nstop = EarlyStopping(monitor=\"val_loss\", patience=2)","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:20:46.147511Z","iopub.execute_input":"2021-08-31T16:20:46.147873Z","iopub.status.idle":"2021-08-31T16:20:46.152974Z","shell.execute_reply.started":"2021-08-31T16:20:46.147837Z","shell.execute_reply":"2021-08-31T16:20:46.151865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gc.collect()\ndel model\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:13:40.091451Z","iopub.execute_input":"2021-08-31T16:13:40.091943Z","iopub.status.idle":"2021-08-31T16:13:40.283463Z","shell.execute_reply.started":"2021-08-31T16:13:40.091894Z","shell.execute_reply":"2021-08-31T16:13:40.281988Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nhis = model.fit(X_train, y_train, validation_data = (X_val, y_val), \n          epochs=20, batch_size=10, verbose=1, callbacks=[checkpoint, stop])","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:20:49.782505Z","iopub.execute_input":"2021-08-31T16:20:49.783072Z","iopub.status.idle":"2021-08-31T16:21:54.621106Z","shell.execute_reply.started":"2021-08-31T16:20:49.783029Z","shell.execute_reply":"2021-08-31T16:21:54.620024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mask_predicated = model.predict(X_val)\nprint(model.evaluate(X_train, y_train)) \n#[accuracy: 0.0053 - mean_iou: 0.4078]\nprint(model.evaluate(X_val, y_val)) \nplt.imshow(mask_predicated[1])\n#[accuracy: 0.0053 - mean_iou: 0.3826]","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:22:04.599792Z","iopub.execute_input":"2021-08-31T16:22:04.600238Z","iopub.status.idle":"2021-08-31T16:22:18.448129Z","shell.execute_reply.started":"2021-08-31T16:22:04.600196Z","shell.execute_reply":"2021-08-31T16:22:18.44647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del model\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-08-31T16:23:08.308226Z","iopub.execute_input":"2021-08-31T16:23:08.3086Z","iopub.status.idle":"2021-08-31T16:23:09.010314Z","shell.execute_reply.started":"2021-08-31T16:23:08.308568Z","shell.execute_reply":"2021-08-31T16:23:09.009329Z"},"trusted":true},"execution_count":null,"outputs":[]}]}