{"cells":[{"metadata":{"id":"4kjcC6QqywWl","trusted":true,"_uuid":"40c67b3ff0fa04587dec508363308adaa3ceaf34"},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport os\nimport random\nimport sys\nimport json\nimport datetime\n# import numpy as np\nimport skimage.io\nfrom imgaug import augmenters as iaa\nimport glob, pylab, pandas as pd\nimport pydicom, numpy as np\nimport os \nimport sys\nimport random\nimport math\nimport numpy as np\nimport cv2\nimport matplotlib.pyplot as plt\nimport json\nimport pydicom\nfrom imgaug import augmenters as iaa\nfrom tqdm import tqdm\nimport pandas as pd \nimport glob\nfrom sklearn.model_selection import KFold","execution_count":null,"outputs":[]},{"metadata":{"id":"yP0XLJx_x_6o","trusted":true,"_uuid":"6e5764759e6a0a9b698b44645658f66873edd807"},"cell_type":"code","source":"DATA_DIR = '/kaggle/input/rsna-pneumonia-detection-challenge'\nROOT_DIR = '/kaggle/working'\ntrain_dir=os.path.join(DATA_DIR, 'stage_2_train_images')\ntest_dir=os.path.join(DATA_DIR, 'stage_2_test_images')","execution_count":null,"outputs":[]},{"metadata":{"id":"KgllzLnDr7kF","outputId":"6c978df7-2013-437e-acd1-5011048dfb53","trusted":true,"_uuid":"b37d22551d332f0f7b722cc7204eb614524b6c21"},"cell_type":"code","source":"!git clone https://www.github.com/matterport/Mask_RCNN.git\n","execution_count":null,"outputs":[]},{"metadata":{"id":"-KZXyWwhzOVU","outputId":"2576cc17-7484-4311-ad72-3c5643dcb5bb","trusted":true,"_uuid":"3acbbbe055b6a409d3c50ae0f893acf51b5ae7ba"},"cell_type":"code","source":"# Import Mask RCNN\nos.chdir('Mask_RCNN')\nsys.path.append(os.path.join(ROOT_DIR, 'Mask_RCNN'))  # To find local version of the library\nfrom mrcnn.config import Config\nfrom mrcnn import utils\nimport mrcnn.model as modellib\nfrom mrcnn import visualize\nfrom mrcnn.model import log","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c3ee0cd0ee0b1defdec97b94bc736587c1f7631f"},"cell_type":"code","source":"!wget --quiet https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5\nCOCO_WEIGHTS_PATH = \"mask_rcnn_coco.h5\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def parse_data(df):\n    \"\"\"\n    Method to read a CSV file (Pandas dataframe) and parse the \n    data into the following nested dictionary:\n\n      parsed = {\n        \n        'patientId-00': {\n            'dicom': path/to/dicom/file,\n            'label': either 0 or 1 for normal or pnuemonia, \n            'boxes': list of box(es)\n        },\n        'patientId-01': {\n            'dicom': path/to/dicom/file,\n            'label': either 0 or 1 for normal or pnuemonia, \n            'boxes': list of box(es)\n        }, ...\n\n      }\n\n    \"\"\"\n    # --- Define lambda to extract coords in list [y, x, height, width]\n    extract_box = lambda row: [row['y'], row['x'], row['height'], row['width']]\n\n    parsed = {}\n    for n, row in df.iterrows():\n        # --- Initialize patient entry into parsed \n        pid = row['patientId']\n        if pid not in parsed:\n            parsed[pid] = {\n                'dicom': train_dir+ '/%s.dcm' % pid,\n                'label': row['Target'],\n                'boxes': []}\n\n        # --- Add box if opacity is present\n        if parsed[pid]['label'] == 1:\n            parsed[pid]['boxes'].append(extract_box(row))\n\n    return parsed","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv(os.path.join(DATA_DIR,'stage_2_train_labels.csv'))\ndf.head()\nparsed = parse_data(df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_list=list(parsed.keys())\nprint(len(img_list))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class pneumoniaConfig(Config):\n    \"\"\"Configuration for training on the nucleus segmentation dataset.\"\"\"\n    # Give the configuration a recognizable name\n    NAME = \"pneumonia\"\n\n    # Adjust depending on your GPU memory\n    IMAGES_PER_GPU = 8\n    GPU_COUNT = 1\n    # Number of classes (including background)\n    NUM_CLASSES = 1 + 1  # Background + nucleus\n\n    # Number of training and validation steps per epoch\n    STEPS_PER_EPOCH = 200\n\n    DETECTION_MIN_CONFIDENCE = 0.78\n\n    # Backbone network architecture\n    # Supported values are: resnet50, resnet101\n    BACKBONE = \"resnet50\"\n\n\n    IMAGE_MIN_DIM = 256\n    IMAGE_MAX_DIM = 256\n\n    # Length of square anchor side in pixels\n    RPN_ANCHOR_SCALES = (8, 16, 32, 64, 128)\n\n\n    # Number of ROIs per image to feed to classifier/mask heads\n    # The Mask RCNN paper uses 512 but often the RPN doesn't generate\n    # enough positive proposals to fill this and keep a positive:negative\n    # ratio of 1:3. You can increase the number of proposals by adjusting\n    # the RPN NMS threshold.\n    TRAIN_ROIS_PER_IMAGE = 50\n\n    # Maximum number of ground truth instances to use in one image\n    MAX_GT_INSTANCES = 4\n\n    # Max number of final detections per image\n    DETECTION_MAX_INSTANCES = 3\n    DETECTION_NMS_THRESHOLD = 0.01\nclass InferenceConfig(pneumoniaConfig):\n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 1\n    \nconfig=pneumoniaConfig()\nconfig.display()\n","execution_count":null,"outputs":[]},{"metadata":{"id":"8EBVA1M60yAj","trusted":true,"_uuid":"52bd3ffbdde0173a363055482d675da51c2aba99"},"cell_type":"code","source":"class pneumoniaDataset(utils.Dataset):\n    \"\"\"Dataset class for training pneumonia detection on the RSNA pneumonia dataset.\n    \"\"\"\n\n    def __init__(self, image_list, parsed, h,w):\n        super().__init__(self)\n        \n        # Add classes\n        self.add_class('pneumonia', 1, 'Lung Opacity')\n        \n        # add images \n        for pid in image_list:\n            boxes = parsed[pid]['boxes']\n            self.add_image('pneumonia', image_id=pid, path=parsed[pid]['dicom'],boxes=boxes, \n                            h=h, w=w)\n            \n    def image_reference(self, image_id):\n        info = self.image_info[image_id]\n        return info['path']\n\n    def load_image(self, image_id):\n        info = self.image_info[image_id]\n        fp = info['path']\n        d = pydicom.read_file(fp)\n        im = d.pixel_array\n\n    # --- Convert from single-channel grayscale to 3-channel RGB\n        im = np.stack([im] * 3, axis=2)\n        return im\n\n    def load_mask(self, image_id):\n#          Generate instance masks for an image.\n#        Returns:\n#         masks: A bool array of shape [height, width, instance count] with\n#             one mask per instance.\n#         class_ids: a 1D array of class IDs of the instance masks.\n#         \n        info = self.image_info[image_id]\n        boxes = info['boxes']\n        count = len(boxes)\n        if count == 0:\n            mask = np.zeros((info['h'], info['w'], 1), dtype=np.bool)\n            class_ids = np.zeros((1,), dtype=np.int32)\n        else:\n            mask = np.zeros((info['h'], info['w'], count), dtype=np.bool)\n            class_ids = np.ones((count,), dtype=np.int32)\n            for i, box in enumerate(boxes):\n                box = [int(b) for b in box]\n                y1, x1, height, width = box\n                y2 = y1 + height\n                x2 = x1 + width\n                mask[y1:y2, x1:x2 ,i]=1\n        return mask, class_ids","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"random.seed(42)\nrandom.shuffle(img_list)\nval = 1500\nim_val = img_list[:val]\nim_train = img_list[val:]","execution_count":null,"outputs":[]},{"metadata":{"id":"EdhUEFDr0yDA","outputId":"1715a5df-a577-41fd-bf20-f1a27aadb28c","trusted":true,"_uuid":"793b1c6c6ba4e5f0d51e130080aa799f230b5ef6"},"cell_type":"code","source":"# Training dataset.\ndataset_train = pneumoniaDataset(im_train, parsed, 1024,1024)\ndataset_train.prepare()\n\n# Validation dataset\ndataset_val = pneumoniaDataset(im_val,parsed, 1024,1024)\ndataset_val.prepare()","execution_count":null,"outputs":[]},{"metadata":{"id":"STZnQTE61lME","trusted":true,"_uuid":"4ab9d6086ce611a46f189c047956c43b29783e6d"},"cell_type":"code","source":"# Image augmentation (light but constant)\naugmentation = iaa.Sequential([\n    iaa.OneOf([ ## geometric transform\n        iaa.Affine(\n            scale={\"x\": (0.98, 1.02), \"y\": (0.98, 1.04)},\n            translate_percent={\"x\": (-0.02, 0.02), \"y\": (-0.04, 0.04)},\n            rotate=(-2, 2),\n            shear=(-1, 1),\n        ),\n        iaa.PiecewiseAffine(scale=(0.001, 0.025)),\n    ]),\n    iaa.OneOf([ ## brightness or contrast\n        iaa.Multiply((0.9, 1.1)),\n        iaa.ContrastNormalization((0.9, 1.1)),\n    ]),\n    iaa.OneOf([ ## blur or sharpen\n        iaa.GaussianBlur(sigma=(0.0, 0.1)),\n        iaa.Sharpen(alpha=(0.0, 0.1)),\n    ]),\n])\n\n# test on the same image as above\n# imggrid = augmentation.draw_grid(image[:, :, 0], cols=5, rows=2)\n# plt.figure(figsize=(30, 12))\n# _ = plt.imshow(imggrid[:, :, 0], cmap='gray')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"138d6197fc8dce9f1f8a7b5a6c27aa2069698e03"},"cell_type":"code","source":"# model = modellib.MaskRCNN(mode='training', config=config, model_dir=ROOT_DIR)\n\n# # Exclude the last layers because they require a matching\n# # number of classes\n# # model.load_weights(\"/kaggle/input/weights/mask_rcnn_pneumonia_0013.h5\", by_name=True, exclude=[\n# #     \"mrcnn_class_logits\", \"mrcnn_bbox_fc\",\n# #     \"mrcnn_bbox\", \"mrcnn_mask\"])\n# model.load_weights(\"/kaggle/input/latest/latest.h5\", by_name=True)","execution_count":null,"outputs":[]},{"metadata":{"id":"RVgNhHjl1lOS","outputId":"2cba9efc-eeea-472d-d155-3c3d856585bf","trusted":true,"_uuid":"64cce2581ffdb8c2b1cb07948ada4a93f64874b0"},"cell_type":"code","source":"LEARNING_RATE = 0.006\n\n# Train Mask-RCNN Model \nimport warnings \nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.train(dataset_train, dataset_val,\n#             learning_rate=LEARNING_RATE/5,\n#             epochs=3,\n#             layers='all',\n#             augmentation=None)\n\n# history = model.keras_model.history.history","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.train(dataset_train, dataset_val,\n#             learning_rate=LEARNING_RATE/5,\n#             epochs=6,\n#             layers='all',\n#             augmentation=None)\n# history = model.keras_model.history.history\n# # new_history = model.keras_model.history.history\n# # for k in new_history: history[k] = history[k] + new_history[k]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.keras_model.save_weights(ROOT_DIR+\"/11.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.train(dataset_train, dataset_val,\n#             learning_rate=LEARNING_RATE/5,\n#             epochs=11,\n#             layers='all',\n#             augmentation=augmentation)\n# # history = model.keras_model.history.history\n# new_history = model.keras_model.history.history\n# for k in new_history: history[k] = history[k] + new_history[k]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.keras_model.save_weights(ROOT_DIR+\"/21.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.train(dataset_train, dataset_val,\n#             learning_rate=LEARNING_RATE/5,\n#             epochs=16,\n#             layers='all',\n#             augmentation=augmentation)\n# # history = model.keras_model.history.history\n# new_history = model.keras_model.history.history\n# for k in new_history: history[k] = history[k] + new_history[k]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.keras_model.save_weights(ROOT_DIR+\"/31.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# print(history)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model_path=\"/kaggle/input/weights/mask_rcnn_pneumonia_0013.h5\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# epochs = range(1,len(next(iter(history.values())))+1)\n# best_epoch = np.argmin(history[\"val_loss\"])\n# print(\"Best Epoch:\", best_epoch + 1, history[\"val_loss\"][best_epoch])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# dir_names = next(os.walk(model.model_dir))[1]\n# key = config.NAME.lower()\n# dir_names = filter(lambda f: f.startswith(key), dir_names)\n# dir_names = sorted(dir_names)\n\n# if not dir_names:\n#     import errno\n#     raise FileNotFoundError(\n#         errno.ENOENT,\n#         \"Could not find model directory under {}\".format(self.model_dir))\n    \n# fps = []\n# # Pick last directory\n# for d in dir_names: \n#     dir_name = os.path.join(model.model_dir, d)\n#     # Find the last checkpoint\n#     checkpoints = next(os.walk(dir_name))[2]\n#     checkpoints = filter(lambda f: f.startswith(\"mask_rcnn\"), checkpoints)\n#     checkpoints = sorted(checkpoints)\n#     if not checkpoints:\n#         print('No weight files in {}'.format(dir_name))\n#     else:\n#         checkpoint = os.path.join(dir_name, checkpoints[best_epoch])\n#         fps.append(checkpoint)\n\n# model_path = sorted(fps)[-1]\n# print('Found model {}'.format(model_path))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model_path=ROOT_DIR+\"/3.h5\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_path=\"/kaggle/input/latest2/mask_rcnn_pneumonia_0011.h5\"","execution_count":null,"outputs":[]},{"metadata":{"id":"TgpT9AzC2Bgz","outputId":"60f5a175-4666-497d-b4e8-0bdab39a92d0","trusted":true,"_uuid":"52138636b2ae5bf444bba808518cd8313bde65cd"},"cell_type":"code","source":"inference_config = InferenceConfig()\n\n# Recreate the model in inference mode\nmodel = modellib.MaskRCNN(mode='inference', \n                          config=inference_config,\n                          model_dir=ROOT_DIR)\n\n# Load trained weights (fill in path to trained weights here)\nassert model_path != \"\", \"Provide path to trained weights\"\nprint(\"Loading weights from \", model_path)\nmodel.load_weights(model_path, by_name=True)","execution_count":null,"outputs":[]},{"metadata":{"id":"C6UWVrbM2Bob","trusted":true,"_uuid":"4a5c0c6134408ddbf5a34496d7e9d7be5692e9a1"},"cell_type":"code","source":"def predict(image_fps, filepath='submission.csv', min_conf=0.96):\n    # assume square image\n    resize_factor = 1024 / config.IMAGE_SHAPE[0]\n    #resize_factor = ORIG_SIZE\n    with open(filepath, 'w') as file:\n        file.write(\"patientId,PredictionString\\n\")\n\n        for image_id in tqdm(image_fps):\n            ds = pydicom.read_file(image_id)\n            image = ds.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\")\n#             print(out_str)","execution_count":null,"outputs":[]},{"metadata":{"id":"C5cBpNka2Bsv","outputId":"a2af9176-d9d6-49f6-f22a-5a1c455d144f","trusted":true,"_uuid":"0406e7f5aaa4867782c4f9c064f90bba386128e7"},"cell_type":"code","source":"test_lis = glob.glob(test_dir+'/'+'*.dcm')\ntest_im=list(set(test_lis))\nprint(len(test_im))\n# print(test_im)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_path = os.path.join(ROOT_DIR, 'submission_final.csv')\npredict(test_im, filepath=submission_path)\n# print(submission_fp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_path2 = os.path.join(ROOT_DIR, 'submission_final2.csv')\npredict(test_im, submission_path2,0.95)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# from IPython.display import FileLink\n# FileLink(model_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# torch.save(model.state_dict(), ROOT_DIR+\"/checkpoint.pth\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# import keras\n# import json\n\n# def save_model(trained_model, out_fname=\"model.json\"):\n#     jsonObj = trained_model.keras_model.to_json()\n#     with open(out_fname, \"w\") as fh:\n#         fh.write(jsonObj)\n#     fh.close()\n\n# save_model(model, ROOT_DIR+\"/mymodel.json\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.keras_model.save_weights(ROOT_DIR+\"/last_7.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.keras_model.save_weights(ROOT_DIR+\"/last_7.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# json_file = open(ROOT_DIR+\"/mymodel.json\", 'r')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# from keras.models import model_from_json\n# loaded_model_json = json_file.read()\n# json_file.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# loaded_model = model_from_json(loaded_model_json)\n# loaded_model.load_weights(ROOT_DIR+\"/last_7.h5\")","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}