{"cells":[{"metadata":{"trusted":true,"_uuid":"cb6a7757975bfb8bb836c11fecc74f4ca330c2dc"},"cell_type":"code","source":"IMG_SIZE = (512, 512)\nBOX_MAX_SIZE = 0.25\nBOX_THRESHOLD = 0.5\nTOP_BOXES = 10\nCLASS_THRESHOLD = 0.5\nGAUSSIAN_DEGREE = 4\n!ls ../input","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"%matplotlib inline\nimport os, sys\nimport numpy as np, pandas as pd, matplotlib.pyplot as plt\nimport pydicom\nfrom keras import layers, models\nfrom glob import glob\nfrom scipy.ndimage import zoom\nrsna_comp_dir = '../input/rsna-pneumonia-detection-challenge'\n# calculate test image paths and ids\ntest_dicoms = glob(os.path.join(rsna_comp_dir, 'stage_2_test_images', '*.dcm'))\ntest_dicoms_dict = {os.path.splitext(os.path.basename(x))[0]: x for x in test_dicoms}\ndef process_dicom(in_path, out_shape = IMG_SIZE):\n    c_dicom = pydicom.read_file(in_path, stop_before_pixels=False)\n    base_img = c_dicom.pixel_array\n    c_size = base_img.shape\n    x_fact = out_shape[0]/c_size[0]\n    y_fact = out_shape[1]/c_size[1]\n    rs_img = zoom(base_img, (x_fact, y_fact))\n    return rs_img","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c239d3ca17ce5f44872c603061185b6d865c363c"},"cell_type":"markdown","source":"# Baseline Predictions\nWe use the pretrained model to determine which images it makes sense to run the full model on"},{"metadata":{"trusted":true,"_uuid":"b9ead3057d0a9da93a48319d0d793788d8d8796f"},"cell_type":"code","source":"class_prod_df = pd.read_csv('../input/lung-opacity-classification-transfer-learning/image_level_class_probs.csv')\nclass_prod_df['Lung Opacity'].plot.hist()\nclass_prod_df.sample(3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1bcf5219330db8632edc16f888a6fb45fed37b85"},"cell_type":"code","source":"print(class_prod_df[class_prod_df['Lung Opacity']>CLASS_THRESHOLD].shape[0], '/', class_prod_df.shape[0])\nclass_prod_df.sample(3)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"# does not work pred_model = models.load_model('../input/lung-opacity-inception-sharp-boxnet/boxnet.h5', compile=False)\ncoord_model = models.load_model('../input/lung-opacity-inception-sharp-boxnet/coordinate_model.h5', compile=False)\ndef run_prediction(in_id):\n    in_path = test_dicoms_dict.get(in_id, in_id)\n    dicom_array = process_dicom(in_path)\n    dicom_tensor = np.expand_dims(np.expand_dims(dicom_array, 0), -1)\n    return coord_model.predict(dicom_tensor)[0]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e916d53acc01f3fa4217036a433052cca2cdb8f1"},"cell_type":"markdown","source":"# Test Coordinate Model\nHere we check the coordinate model against the training data"},{"metadata":{"trusted":true,"_uuid":"a76bb03de37bbd8edd02050bc0b3f19252e3982e"},"cell_type":"code","source":"train_df = pd.read_csv(os.path.join(rsna_comp_dir, 'stage_2_train_labels.csv')).query('Target>0')\ntrain_dir = os.path.join(rsna_comp_dir, 'stage_2_train_images')\ntrain_df['path'] = train_df['patientId'].map(lambda x: os.path.join(train_dir, '{}.dcm'.format(x)))\ntrain_df.sample(3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7ba65e66b1a6bbccdae429d7927778aa178af1ab"},"cell_type":"code","source":"def project_gaussians(gaus_coord,  # type: tf.Tensor\n                      proj_grid # type: tf.Tensor \n                       ):\n    # type: (...) -> tf.Tensor\n    \"\"\"\n    Project M gaussians on a grid of points\n    :param gaus_coord: the n, m, 5 (x, y, w, h, I)\n    :param proj_grid: the xx yy grid to project on (n, R, C, 2)\n    :return:\n    \"\"\"\n    with tf.variable_scope('gauss_proj'):\n        batch_size = tf.shape(gaus_coord)[0]\n        n_gaus = tf.shape(gaus_coord)[1]\n        xg_wid = tf.shape(proj_grid)[1]\n        yg_wid = tf.shape(proj_grid)[2]\n        with tf.variable_scope('create_m_grids'):\n            \"\"\"create a grid for each gaussian\"\"\"\n            grid_prep = lambda x: tf.tile(tf.expand_dims(x, 1), [1, n_gaus, 1, 1])\n            xx_grid = grid_prep(proj_grid[:, :, :, 0])\n            yy_grid = grid_prep(proj_grid[:, :, :, 1])\n\n        with tf.variable_scope('create_rc_coords'):\n            \"\"\"create coordinates for each position and \"\"\"\n            coord_prep = lambda x: tf.tile(tf.expand_dims(tf.expand_dims(x, 2), 3), \n                                      [1, 1, xg_wid, yg_wid])\n            c_x = coord_prep(gaus_coord[:, :, 0])\n            c_y = coord_prep(gaus_coord[:, :, 1])\n            c_w = BOX_MAX_SIZE*coord_prep(0.5+0.45*gaus_coord[:, :, 2])\n            c_h = BOX_MAX_SIZE*coord_prep(0.5+0.45*gaus_coord[:, :, 3])\n            c_norm_max=gaus_coord[:, :, 4]\n            c_max = coord_prep(0.5+0.5*c_norm_max)\n        with tf.variable_scope('transform_coords'):\n            x_trans = (xx_grid-c_x)/c_w\n            xe_trans = tf.exp(-tf.pow(x_trans, GAUSSIAN_DEGREE))\n            y_trans = (yy_grid-c_y)/c_h\n            ye_trans = tf.exp(-tf.pow(y_trans, GAUSSIAN_DEGREE))\n            all_gauss = c_max*xe_trans*ye_trans\n            sum_gauss = tf.clip_by_value(tf.reduce_sum(all_gauss, 1), 0, 1)\n            return tf.expand_dims(sum_gauss, -1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4b6e5b6f69ca8f77c102cb1a6259e6fd1d44639b"},"cell_type":"code","source":"w_scale_factor = np.sqrt(2)\nfig, ax1 = plt.subplots(1, 1, figsize = (10, 10))\nx = np.linspace(-1, 1, 512)\nsigma = 0.1\ny = np.exp(-np.power(x/sigma, GAUSSIAN_DEGREE))\nax1.plot(x, y)\nW = w_scale_factor*sigma\nax1.axvline(-W/2)\nax1.axvline(W/2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0783280a0d115365e85240d6d98972ccda23c012"},"cell_type":"code","source":"from IPython.display import display\ndef box_vec_as_df(in_boxs, out_size):\n    out_df = pd.DataFrame(in_boxs, columns = ['y', 'x', 'height', 'width', 'score'])\n    for c_s, c_col in zip(out_size, 'xy'):\n        out_df[c_col] = out_df[c_col]*c_s/2+c_s/2\n    for c_s, c_col in zip(out_size, ['width', 'height']):\n        out_df[c_col] = BOX_MAX_SIZE*(0.5+0.45*out_df[c_col])\n        out_df[c_col] = out_df[c_col]*c_s/2+c_s/2\n    out_df['score'] = 0.5+0.5*out_df['score']\n    #out_df['width'] = w_scale_factor*out_df['width']\n    #out_df['height'] = w_scale_factor*out_df['height']\n    out_df['x'] = out_df['x']-out_df['width']/2\n    out_df['y'] = out_df['y']-out_df['height']/2\n    return out_df\ndef bbox_str(in_boxes):\n    new_boxes = in_boxes[in_boxes['score']>BOX_THRESHOLD].sort_values('score', ascending=False).head(TOP_BOXES)\n    out_str_list = new_boxes.apply(lambda x: '{score:.2f} {x:.0f} {y:.0f} {width:.0f} {height:.0f}'.format(**x), 1)\n    return ' '.join(out_str_list)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2cffa419fd4b49a587343f3c3d8b9b48bd2b806b"},"cell_type":"code","source":"test_df = train_df[train_df['patientId']==train_df['patientId'].iloc[0]]\ntest_path = test_df['path'].iloc[0]\ntest_array = pydicom.read_file(test_path).pixel_array\ntest_boxes_df = box_vec_as_df(run_prediction(test_path), (1024, 1024))\ndisplay(test_boxes_df)\nprint(bbox_str(test_boxes_df))\ntest_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7c0d60e37a614178e94affbb6033fd17c655871f"},"cell_type":"code","source":"from matplotlib.patches import Rectangle\nfig, m_axs = plt.subplots(1, 3, figsize = (20, 10))\nfor c_ax, c_rows in zip(m_axs, [test_df, \n                                test_boxes_df, \n                                test_boxes_df.sort_values('score', ascending=False).head(TOP_BOXES)]):\n    c_ax.imshow(test_array, cmap='bone')\n    for i, (_, c_row) in enumerate(c_rows.dropna().iterrows()):\n        c_ax.plot(c_row['x'], c_row['y'], 's')\n        confidence = 0.5*c_row.get('score', 1.0)\n        c_ax.add_patch(Rectangle(xy=(c_row['x'], c_row['y']),\n                                width=c_row['width'],\n                                height=c_row['height'], \n                                 alpha = confidence))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2d20dae88d55314ef14d2d5f01ddea226aeebd69"},"cell_type":"code","source":"%%time\ndef full_pred(in_row):\n    if in_row['Lung Opacity']>CLASS_THRESHOLD:\n        c_boxes = box_vec_as_df(run_prediction(in_row['patientId']), (1024, 1024))\n        return bbox_str(c_boxes)\n    else:\n        return ''\nclass_prod_df['PredictionString'] = class_prod_df.apply(full_pred, 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c973de49f892597bba28336af363a32e063723c0"},"cell_type":"code","source":"class_prod_df[['patientId','PredictionString']].head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b748f38860fdda48e71a941d01a8f1e423f70fa9"},"cell_type":"code","source":"class_prod_df[['patientId','PredictionString']].to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"aaa1cd962ad3ad47d004aaf5f9538a0d610273e6"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}