{"cells":[{"metadata":{},"cell_type":"markdown","source":"Current problem: GPU version imcompatible with required tensorflow in matterport's implementation.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"[Reference notebook 1](https://www.kaggle.com/hmendonca/mask-rcnn-and-coco-transfer-learning-lb-0-155)\n\n[Reference notebook 2](https://www.kaggle.com/ipythonx/keras-global-wheat-detection-with-mask-rcnn/data?select=mask_rcnn_coco.h5)\n\n[Matterport's implementation of Mask-RCNN](https://github.com/matterport/Mask_RCNN)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip uninstall -y tensorflow","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!pip install -U tensorflow==1.14.0\n!pip install -U tensorflow-gpu==1.18.4\n!pip install -U keras==2.2.4\n#!pip install kerassurgeon\n#!pip install tensorflow_probability==0.8.0rc0 --user --upgrade","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"restart session by ctrl+shift+p at this cell","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"!cp -r ../input/mask-rcnn/Mask_RCNN-master/* ./","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport pydicom\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nimport os\nimport sys\nimport math\nfrom tqdm import tqdm\nimport seaborn as sns\nimport random\n\nimport cv2\nfrom mrcnn.config import Config\nfrom mrcnn import model as modellib\nfrom mrcnn import visualize\nfrom mrcnn import utils\nfrom mrcnn.model import log\n\nimport tensorflow as tf\n#import keras","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(tf.__version__)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tf.test.is_gpu_available()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dirname = '../input/rsna-pneumonia-detection-challenge/'\ntrain = pd.read_csv(dirname+'stage_2_train_labels.csv')\n#train.fillna(value=-1, inplace=True)\nprint(train.head())\nprint(train.describe())\n#print(train.isnull())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pneumonia_locations = {}\ntrain_images = []\ntarget = []\nfor i in range(len(train)):\n    n = str(dirname + 'stage_2_train_images/' + train['patientId'][i] + '.dcm')\n    if n not in train_images:\n        train_images.append(n)\n        target.append(train['Target'][i])\n    if train['Target'][i]==1:\n        loc = [int(train['x'][i]), int(train['y'][i]),\n               int(train['width'][i]), int(train['height'][i])]\n        if n in pneumonia_locations:\n            pneumonia_locations[n].append(loc)\n        else:\n            pneumonia_locations[n] = [loc]\ntrain_images = pd.DataFrame(train_images)\ntrain_images.columns = ['filepath']\ntrain_images['Target'] = target","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del train\nprint(train_images.head())\nlen(train_images)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X = list(train_images['filepath'])\nrandom.seed(42)\nrandom.shuffle(X)\nl = int(0.2*len(X))\ntrain_X = X[l:]\nval_X =X[:l]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(train_X))\nprint(len(val_X))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.countplot(train_images.Target)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"i=0\nln = []\nfor item in pneumonia_locations:\n    ln.append(len(pneumonia_locations[item]))\n    i+=1\nsns.countplot(ln)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nim = (pydicom.dcmread(train_images['filepath'][0]).pixel_array)\nplt.imshow(im)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize = (15,10))\ncolumns = 5\nrows = 2\nfor i in [0,1]:\n    df = train_images[train_images['Target']==i].sample(5)\n    df = list(df['filepath'])\n    for j in range(5):\n        fig.add_subplot(rows, columns, i*columns + j +1)\n        plt.imshow((pydicom.dcmread(df[j]).pixel_array)) #cmap = plt.cm.bone\n    del df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"f, axarr = plt.subplots(2, 5, figsize=(20, 15))\naxarr = axarr.ravel()\naxidx = 0\ndf1 = train_images[train_images['Target']==0].sample(5)\ndf2 = train_images[train_images['Target']==1].sample(5)\ndf = np.concatenate((np.array(df1['filepath']),np.array(df2['filepath'])),axis=0)\ndf = list(df)\nfor i in range(len(df)):\n    axarr[axidx].imshow(pydicom.dcmread(df[i]).pixel_array)\n    if df[i] in pneumonia_locations:\n        l = pneumonia_locations[df[i]]\n        for j in l:\n            axarr[axidx].add_patch(patches.Rectangle((j[0], j[1]), j[2], j[3], linewidth=2, edgecolor='b', facecolor='none'))\n    axidx+=1\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class PneumoniaConfig(Config):\n    NAME = 'Pneumonia'\n    \n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 8\n    \n    BACKBONE = 'resnet50'\n    \n    NUM_CLASSES = 2  # background + 1 pneumonia classes\n    \n    IMAGE_MIN_DIM = 256\n    IMAGE_MAX_DIM = 256\n    RPN_ANCHOR_SCALES = (16, 32, 64, 128, 256)\n    TRAIN_ROIS_PER_IMAGE = 32\n    MAX_GT_INSTANCES = 4\n    DETECTION_MAX_INSTANCES = 3\n    DETECTION_MIN_CONFIDENCE = 0.78  ## match target distribution\n    DETECTION_NMS_THRESHOLD = 0.01\n\n    STEPS_PER_EPOCH = 200\n\nconfig = PneumoniaConfig()\nconfig.display()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class DatasetGenerator(utils.Dataset):\n    \n    def __init__(self, fp, pneumonia_locations=None, batch_size=32, image_size=1024, predict=False):\n        super().__init__(self)\n        self.fp = fp\n        self.pneumonia_locations = pneumonia_locations\n        self.batch_size = batch_size\n        self.image_size = image_size\n        self.predict = predict\n        \n        self.add_class('Pneumonia', 1, 'pneumonia')\n        for id, fps in enumerate(fp):\n            self.add_image('Pneumonia',image_id=id,\n                          path =fps)\n        \n    def load_mask(self, image_id):\n        info = self.image_info[image_id]\n        fps = info['path']\n        if fps in self.pneumonia_locations:\n            l = self.pneumonia_locations[fps]\n            mask = np.zeros((self.image_size, self.image_size, len(l)), dtype=np.uint8)\n            class_ids = np.zeros((len(l),), dtype=np.int32)\n            i=0\n            for a in l:\n                x=int(a[0])\n                y=int(a[1])\n                w=int(a[2])\n                h=int(a[3])\n                mask_instance = mask[:,:,i].copy()\n                cv2.rectangle(mask_instance, (x,y), (x+w,y+h), 255, -1)\n                mask[:,:,i] = mask_instance\n                class_ids[i] = 1\n                i+=1\n        else:\n            mask = np.zeros((self.image_size, self.image_size, 1), dtype=np.uint8)\n            class_ids = np.zeros((1,), dtype=np.int32)\n        return mask.astype(np.bool), class_ids.astype(np.int32)\n    \n    def load_image(self, image_id):\n        info = self.image_info[image_id]\n        fps = info['path']\n        image = pydicom.dcmread(fps).pixel_array\n        if len(image.shape) != 3 or image.shape[2] != 3:\n            image = np.stack((image,) * 3, -1)\n        return image\n    \n    def image_reference(self, image_id):\n        info = self.image_info[image_id]\n        return info['path']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_gen = DatasetGenerator(train_X, pneumonia_locations)\ntrain_gen.prepare()\n\nval_gen = DatasetGenerator(val_X, pneumonia_locations)\nval_gen.prepare()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load and display random samples\nimage_ids = np.random.choice(train_gen.image_ids,5)\nfor image_id in image_ids:\n    image = train_gen.load_image(image_id)\n    mask, class_ids = train_gen.load_mask(image_id)\n    visualize.display_top_masks(image, mask, class_ids, \n                                train_gen.class_names, limit=1)\n    print(mask.shape)\n    print(image.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load random image and mask.\nimage_id = np.random.choice(train_gen.image_ids, 1)[0]\nimage = train_gen.load_image(image_id)\nmask, class_ids = train_gen.load_mask(image_id)\n\n# Compute Bounding box\nbbox = utils.extract_bboxes(mask)\n\n# Display image and instances\nvisualize.display_instances(image, bbox, mask, class_ids, \n                            train_gen.class_names)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def model_definition():\n    print(\"loading mask R-CNN model\")\n    model = modellib.MaskRCNN(mode='training', \n                              config=config, \n                              model_dir='/kaggle/working')\n    \n    # load the weights for COCO\n    model.load_weights('/kaggle/input' + '/cocowg/mask_rcnn_coco.h5',\n                       by_name=True, \n                       exclude=[\"mrcnn_class_logits\",\n                                \"mrcnn_bbox_fc\",  \n                                \"mrcnn_bbox\",\"mrcnn_mask\"])\n    return model   \n\nmodel = model_definition()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import (ModelCheckpoint, ReduceLROnPlateau, CSVLogger)\n\ndef callback():\n    cb = []\n    checkpoint = ModelCheckpoint('/kaggle/working'+'wheat_wg.h5',\n                                 save_best_only=True,\n                                 mode='min',\n                                 monitor='val_loss',\n                                 save_weights_only=True, verbose=1)\n    cb.append(checkpoint)\n    reduceLROnPlat = ReduceLROnPlateau(monitor='val_loss',\n                                   factor=0.3, patience=5,\n                                   verbose=1, mode='auto',\n                                   epsilon=0.0001, cooldown=1, min_lr=0.00001)\n    log = CSVLogger('/kaggle/working'+'/pneumonia_history.csv')\n    cb.append(log)\n    cb.append(reduceLROnPlat)\n    return cb","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import warnings \nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"CB = callback()\nLEARNING_RATE = 0.006\n\nmodel.train(train_gen, val_gen, \n                learning_rate=LEARNING_RATE*2,\n                custom_callbacks = CB,\n                epochs=2, layers='all') ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.keras_model.history.history","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"CB = callback()\nLEARNING_RATE = 0.006\n\nmodel.train(train_gen, val_gen, \n                learning_rate=LEARNING_RATE,\n                custom_callbacks = CB,\n                epochs=6, layers='heads') ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Inference","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"class InferenceConfig(PneumoniaConfig):\n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 1\n    \ninferconfig = InferenceConfig()\nmodel = modellib.MaskRCNN(mode='inference', \n                              config=inferconfig,\n                              model_dir='/kaggle/working')\nmodel.load_weights(,\n                  by_name = True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"test = []\nfor dname, _, filenames in os.walk('/kaggle/input/rsna-pneumonia-detection-challenge/stage_2_test_images/'):\n    for filename in filenames:\n        test.append(str(os.path.join(dname, filename)))\nprint(test[:5])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def predict(fp, filepath='submission.csv', min_conf=0.75):\n    with open(filepath, 'w') as file:\n        resize_factor = 1024/ config.IMAGE_SHAPE[0]\n        \n        file.write(\"patientId,PredictionString\\n\")\n\n        for image_id in tqdm(image_fps):\n            image = pydicom.read_file(image_id).pixel_array\n            # If grayscale. Convert to RGB for consistency.\n            if len(image.shape) != 3 or image.shape[2] != 3:\n                image = np.stack((image,) * 3, -1)\n            image, window, scale, padding, crop = utils.resize_image(\n                image,\n                min_dim=config.IMAGE_MIN_DIM,\n                min_scale=config.IMAGE_MIN_SCALE,\n                max_dim=config.IMAGE_MAX_DIM,\n                mode=config.IMAGE_RESIZE_MODE)\n\n            patient_id = os.path.splitext(os.path.basename(image_id))[0]\n\n            results = model.detect([image])\n            r = results[0]\n\n            out_str = \"\"\n            out_str += patient_id\n            out_str += \",\"\n            assert( len(r['rois']) == len(r['class_ids']) == len(r['scores']) )\n            if len(r['rois']) == 0:\n                pass\n            else:\n                num_instances = len(r['rois'])\n\n                for i in range(num_instances):\n                    if r['scores'][i] > min_conf:\n                        out_str += ' '\n                        out_str += str(round(r['scores'][i], 2))\n                        out_str += ' '\n\n                        # x1, y1, width, height\n                        x1 = r['rois'][i][1]\n                        y1 = r['rois'][i][0]\n                        width = r['rois'][i][3] - x1\n                        height = r['rois'][i][2] - y1\n                        bboxes_str = \"{} {} {} {}\".format(x1*resize_factor, y1*resize_factor, \\\n                                                           width*resize_factor, height*resize_factor)\n                        out_str += bboxes_str\n\n            file.write(out_str+\"\\n\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = os.path.join('/kaggle/working', 'submission.csv')\npredict(test, filepath=submission)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submit = pd.read_csv(submission)\nsubmit.head(10)","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}