{"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":"!pip install scipy==1.1.0\n","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:09:39.84445Z","iopub.execute_input":"2022-01-28T09:09:39.844717Z","iopub.status.idle":"2022-01-28T09:09:54.835743Z","shell.execute_reply.started":"2022-01-28T09:09:39.844636Z","shell.execute_reply":"2022-01-28T09:09:54.834859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import PIL","metadata":{"execution":{"iopub.status.busy":"2022-01-27T23:19:01.076168Z","iopub.execute_input":"2022-01-27T23:19:01.076462Z","iopub.status.idle":"2022-01-27T23:19:01.082829Z","shell.execute_reply.started":"2022-01-27T23:19:01.076426Z","shell.execute_reply":"2022-01-27T23:19:01.082045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport matplotlib.pyplot as plt\nfrom skimage.morphology import label\nfrom scipy.misc.pilutil import imread\nimport os\nimport time\nimport sys","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-28T09:10:07.400343Z","iopub.execute_input":"2022-01-28T09:10:07.400626Z","iopub.status.idle":"2022-01-28T09:10:08.433358Z","shell.execute_reply.started":"2022-01-28T09:10:07.400581Z","shell.execute_reply":"2022-01-28T09:10:08.432596Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nTRAINING_VALIDATION_RATIO = 0.2\nWORKING_DIR = '/kaggle/working'\nINPUT_DIR = '/kaggle/input'\nOUTPUT_DIR = '/kaggle/output'\nLOGS_DIR = os.path.join(WORKING_DIR, \"logs\")\nTRAIN_DATA_PATH = os.path.join(INPUT_DIR, 'airbus-ship-detection/train_v2')\nTEST_DATA_PATH = os.path.join(INPUT_DIR, 'airbus-ship-detection/test_v2')\nSAMPLE_SUBMISSION_PATH = os.path.join(INPUT_DIR, 'airbus-ship-detection/sample_submission_v2.csv')\nTRAIN_SHIP_SEGMENTATIONS_PATH = os.path.join(INPUT_DIR, 'airbus-ship-detection/train_ship_segmentations_v2.csv')\nMASK_RCNN_PATH = os.path.join(WORKING_DIR, 'Mask_RCNN-master')\nCOCO_WEIGHTS_PATH = os.path.join(WORKING_DIR, \"mask_rcnn_coco.h5\")\nSHIP_CLASS_NAME = 'ship'\nIMAGE_WIDTH = 768\nIMAGE_HEIGHT = 768\nSHAPE = (IMAGE_WIDTH, IMAGE_HEIGHT)\n\ntest_ds = os.listdir(TEST_DATA_PATH)\ntrain_ds = os.listdir(TRAIN_DATA_PATH)\n\nprint('Working Dir:', WORKING_DIR, os.listdir(WORKING_DIR))\nprint('Input Dir:', INPUT_DIR, os.listdir(INPUT_DIR))\nprint('train dataset from: {}, {}'.format(TRAIN_DATA_PATH, len(train_ds)))\nprint('test dataset from: {}, {}'.format(TRAIN_DATA_PATH, len(test_ds)))\nprint(TRAIN_SHIP_SEGMENTATIONS_PATH)","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:10:16.310307Z","iopub.execute_input":"2022-01-28T09:10:16.310589Z","iopub.status.idle":"2022-01-28T09:10:20.435743Z","shell.execute_reply.started":"2022-01-28T09:10:16.310552Z","shell.execute_reply":"2022-01-28T09:10:20.43501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"masks = pd.read_csv(TRAIN_SHIP_SEGMENTATIONS_PATH)\nmasks.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:10:24.186206Z","iopub.execute_input":"2022-01-28T09:10:24.186779Z","iopub.status.idle":"2022-01-28T09:10:25.214052Z","shell.execute_reply.started":"2022-01-28T09:10:24.18674Z","shell.execute_reply":"2022-01-28T09:10:25.213301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def multi_rle_encode(img):\n    labels = label(img[:, :, 0])\n    return [rle_encode(labels==k) for k in np.unique(labels[labels>0])]\n\ndef rle_encode(img):\n  \n    pixels = img.T.flatten() \n  \n    pixels = np.concatenate([[0], pixels, [0]])\n \n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n  \n    runs[1::2] -= runs[::2]\n   \n    return ' '.join(str(x) for x in runs)\n\ndef rle_decode(mask_rle, shape=SHAPE):\n\n    s = mask_rle.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0::2], s[1::2])]\n    starts -= 1\n    ends = starts + lengths\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape).T\n\ndef masks_as_image(in_mask_list, shape=SHAPE):\n    all_masks = np.zeros(shape, dtype = np.int16)\n    for mask in in_mask_list:\n        if isinstance(mask, str):\n            all_masks += rle_decode(mask)\n    return np.expand_dims(all_masks, -1)\n\ndef shows_decode_encode(image_id, path=TRAIN_DATA_PATH):\n   \n    fig, axarr = plt.subplots(1, 3, figsize = (10, 5))\n    img_0 = imread(os.path.join(path, image_id))\n    axarr[0].imshow(img_0)\n    axarr[0].set_title(image_id)\n    rle_1 = masks.query('ImageId==\"{}\"'.format(image_id))['EncodedPixels']\n    img_1 = masks_as_image(rle_1)\n    axarr[1].imshow(img_1[:, :, 0])\n    axarr[1].set_title('Ship Mask')\n    rle_2 = multi_rle_encode(img_1)\n    img_2 = masks_as_image(rle_2)\n    axarr[2].imshow(img_0)\n    axarr[2].imshow(img_2[:, :, 0], alpha=0.3)\n    axarr[2].set_title('Encoded & Decoded Mask')\n    plt.show()\n    print(image_id , ' Check Decoding->Encoding',\n          'RLE_0:', len(rle_1), '->',\n          'RLE_1:', len(rle_2))\n\nshows_decode_encode('000155de5.jpg')\nshows_decode_encode('00003e153.jpg')\nprint('It could be different when there is no mask.')\nshows_decode_encode('00021ddc3.jpg')\nprint('It could be different when there are masks overlapped.')","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:10:28.198039Z","iopub.execute_input":"2022-01-28T09:10:28.198763Z","iopub.status.idle":"2022-01-28T09:10:30.3752Z","shell.execute_reply.started":"2022-01-28T09:10:28.198727Z","shell.execute_reply":"2022-01-28T09:10:30.374537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nmasks['ships'] = masks['EncodedPixels'].map(lambda encoded_pixels: 1 if isinstance(encoded_pixels, str) else 0)\n\nstart_time = time.time()\nunique_img_ids = masks.groupby('ImageId').agg({'ships': 'sum'})\nunique_img_ids['RleMaskList'] = masks.groupby('ImageId')['EncodedPixels'].apply(list)\nunique_img_ids = unique_img_ids.reset_index()\nend_time = time.time() - start_time\nprint(\"unique_img_ids groupby took: {}\".format(end_time))\nunique_img_ids = unique_img_ids[unique_img_ids['ships'] > 0]\nunique_img_ids['ships'].hist()\nunique_img_ids.sample(3)","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:10:35.536156Z","iopub.execute_input":"2022-01-28T09:10:35.536965Z","iopub.status.idle":"2022-01-28T09:10:39.857294Z","shell.execute_reply.started":"2022-01-28T09:10:35.536921Z","shell.execute_reply":"2022-01-28T09:10:39.856493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nfrom sklearn.model_selection import train_test_split\ntrain_ids, val_ids = train_test_split(unique_img_ids, \n                 test_size = TRAINING_VALIDATION_RATIO, \n                 stratify = unique_img_ids['ships'])\nprint(train_ids.shape[0], 'training masks')\nprint(val_ids.shape[0], 'validation masks')\ntrain_ids['ships'].hist()\nval_ids['ships'].hist()\n","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:10:42.534171Z","iopub.execute_input":"2022-01-28T09:10:42.534425Z","iopub.status.idle":"2022-01-28T09:10:43.09046Z","shell.execute_reply.started":"2022-01-28T09:10:42.534395Z","shell.execute_reply":"2022-01-28T09:10:43.08963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nUPDATE_MASK_RCNN = False\n\nos.chdir(WORKING_DIR)\nif UPDATE_MASK_RCNN:\n    !rm -rf {MASK_RCNN_PATH}\n\nif not os.path.exists(MASK_RCNN_PATH):\n    ! wget https://github.com/matterport/Mask_RCNN/archive/master.zip -O Mask_RCNN-master.zip\n    ! unzip Mask_RCNN-master.zip 'Mask_RCNN-master/mrcnn/*'\n    ! rm Mask_RCNN-master.zip\nsys.path.append(MASK_RCNN_PATH)","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:10:46.687009Z","iopub.execute_input":"2022-01-28T09:10:46.687847Z","iopub.status.idle":"2022-01-28T09:10:54.522989Z","shell.execute_reply.started":"2022-01-28T09:10:46.687806Z","shell.execute_reply":"2022-01-28T09:10:54.521887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install tensorflow==1.13.1\n!pip install keras==2.0.8\n!pip install h5py==2.10.0","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:11:09.761118Z","iopub.execute_input":"2022-01-28T09:11:09.761424Z","iopub.status.idle":"2022-01-28T09:12:08.306049Z","shell.execute_reply.started":"2022-01-28T09:11:09.761392Z","shell.execute_reply":"2022-01-28T09:12:08.305198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"UPDATE_MASK_RCNN = False\n\nos.chdir(WORKING_DIR)\nif UPDATE_MASK_RCNN:\n    !rm -rf {MASK_RCNN_PATH}\n\nif not os.path.exists(MASK_RCNN_PATH):\n    ! wget https://github.com/abhinavsagar/Mask_RCNN/archive/master.zip -O Mask_RCNN-master.zip\n    ! unzip Mask_RCNN-master.zip 'Mask_RCNN-master/mrcnn/*'\n    ! rm Mask_RCNN-master.zip\n\n\nsys.path.append(MASK_RCNN_PATH)  \nfrom mrcnn.config import Config\nfrom mrcnn import utils\nimport mrcnn.model as modellib\nfrom mrcnn import visualize\nfrom mrcnn.model import log ","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:12:42.507687Z","iopub.execute_input":"2022-01-28T09:12:42.507975Z","iopub.status.idle":"2022-01-28T09:12:46.089935Z","shell.execute_reply.started":"2022-01-28T09:12:42.507944Z","shell.execute_reply":"2022-01-28T09:12:46.089181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AirbusShipDetectionChallengeDataset(utils.Dataset):\n    def __init__(self, image_file_dir, ids, masks, image_width=IMAGE_WIDTH, image_height=IMAGE_HEIGHT):\n        super().__init__(self)\n        self.image_file_dir = image_file_dir\n        self.ids = ids\n        self.masks = masks\n        self.image_width = image_width\n        self.image_height = image_height\n        \n        self.add_class(SHIP_CLASS_NAME, 1, SHIP_CLASS_NAME)\n        self.load_dataset()\n        \n    def load_dataset(self):\n        for index, row in self.ids.iterrows():\n            image_id = row['ImageId']\n            image_path = os.path.join(self.image_file_dir, image_id)\n            rle_mask_list = row['RleMaskList']\n            self.add_image(\n                SHIP_CLASS_NAME,\n                image_id=image_id,\n                path=image_path,\n                width=self.image_width, height=self.image_height,\n                rle_mask_list=rle_mask_list)\n\n    def load_mask(self, image_id):\n        info = self.image_info[image_id]\n        rle_mask_list = info['rle_mask_list']\n        mask_count = len(rle_mask_list)\n        mask = np.zeros([info['height'], info['width'], mask_count],\n                        dtype=np.uint8)\n        i = 0\n        for rel in rle_mask_list:\n            if isinstance(rel, str):\n                np.copyto(mask[:,:,i], rle_decode(rel))\n            i += 1\n        return mask.astype(np.bool), np.ones([mask.shape[-1]], dtype=np.int32)\n    \n    def image_reference(self, image_id):\n        info = self.image_info[image_id]\n        if info['source'] == SHIP_CLASS_NAME:\n            return info['path']\n        else:\n            super(self.__class__, self).image_reference(image_id)","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:12:49.009368Z","iopub.execute_input":"2022-01-28T09:12:49.009652Z","iopub.status.idle":"2022-01-28T09:12:49.021312Z","shell.execute_reply.started":"2022-01-28T09:12:49.009602Z","shell.execute_reply":"2022-01-28T09:12:49.020629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AirbusShipDetectionChallengeGPUConfig(Config):\n    NAME = 'ASDC_GPU'\n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 2\n    \n    NUM_CLASSES = 2  \n    IMAGE_MIN_DIM = IMAGE_WIDTH\n    IMAGE_MAX_DIM = IMAGE_WIDTH\n    STEPS_PER_EPOCH = 300\n    VALIDATION_STEPS = 50\n    SAVE_BEST_ONLY = True\n    DETECTION_MIN_CONFIDENCE = 0.95\n    DETECTION_NMS_THRESHOLD = 0.05\n\nconfig = AirbusShipDetectionChallengeGPUConfig()\nconfig.display()","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:12:52.82691Z","iopub.execute_input":"2022-01-28T09:12:52.827185Z","iopub.status.idle":"2022-01-28T09:12:52.84283Z","shell.execute_reply.started":"2022-01-28T09:12:52.827156Z","shell.execute_reply":"2022-01-28T09:12:52.841878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from mrcnn import visualize\nstart_time = time.time()\ndataset_train = AirbusShipDetectionChallengeDataset(image_file_dir=TRAIN_DATA_PATH, ids=train_ids, masks=masks)\ndataset_train.prepare()\ndataset_val = AirbusShipDetectionChallengeDataset(image_file_dir=TRAIN_DATA_PATH, ids=val_ids, masks=masks)\ndataset_val.prepare()\n\nimage_ids = np.random.choice(dataset_train.image_ids, 3)\nfor image_id in image_ids:\n    image = dataset_train.load_image(image_id)\n    mask, class_ids = dataset_train.load_mask(image_id)\n    visualize.display_top_masks(image, mask, class_ids, dataset_train.class_names, limit=1)\n\nend_time = time.time() - start_time\nprint(\"dataset prepare: {}\".format(end_time))","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:12:57.106926Z","iopub.execute_input":"2022-01-28T09:12:57.107543Z","iopub.status.idle":"2022-01-28T09:13:00.426956Z","shell.execute_reply.started":"2022-01-28T09:12:57.107501Z","shell.execute_reply":"2022-01-28T09:13:00.426222Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"start_time = time.time()\nmodel = modellib.MaskRCNN(mode=\"training\", config=config, model_dir=WORKING_DIR)\n\nimport errno\ntry:\n    weights_path = model.find_last()\n    load_weights = True\nexcept FileNotFoundError:\n    load_weights = True\n    weights_path = COCO_WEIGHTS_PATH\n    utils.download_trained_weights(weights_path)\n    \nif load_weights:\n    print(\"Loading weights: \", weights_path)\n    model.load_weights(weights_path, by_name=True, exclude=[\n                \"mrcnn_class_logits\", \"mrcnn_bbox_fc\",\n                \"mrcnn_bbox\", \"mrcnn_mask\"])\n\nend_time = time.time() - start_time\nprint(\"loading weights: {}\".format(end_time))","metadata":{"execution":{"iopub.status.busy":"2022-01-28T09:13:05.200168Z","iopub.execute_input":"2022-01-28T09:13:05.200434Z","iopub.status.idle":"2022-01-28T09:13:22.934133Z","shell.execute_reply.started":"2022-01-28T09:13:05.200405Z","shell.execute_reply":"2022-01-28T09:13:22.933305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"start_time = time.time()    \nmodel.train(dataset_train, dataset_val,\n            learning_rate=config.LEARNING_RATE * 1.5,\n            epochs=2,\n            layers='all')\nend_time = time.time() - start_time\nprint(\"Train model: {}\".format(end_time))","metadata":{"execution":{"iopub.status.busy":"2022-01-28T18:45:37.346746Z","iopub.execute_input":"2022-01-28T18:45:37.347742Z","iopub.status.idle":"2022-01-28T18:45:37.427852Z","shell.execute_reply.started":"2022-01-28T18:45:37.347594Z","shell.execute_reply":"2022-01-28T18:45:37.426701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class InferenceConfig(AirbusShipDetectionChallengeGPUConfig):\n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 1\n\ninference_config = InferenceConfig()\ninfer_model = modellib.MaskRCNN(mode=\"inference\", \n                          config=inference_config,\n                          model_dir=WORKING_DIR)\n\nmodel_path = infer_model.find_last()\n\nprint(\"Loading weights from \", model_path)\ninfer_model.load_weights(model_path, by_name=True)\n\nimage_id = np.random.choice(dataset_val.image_ids)\noriginal_image, image_meta, gt_class_id, gt_bbox, gt_mask =\\\n    modellib.load_image_gt(dataset_val, inference_config, \n                           image_id, use_mini_mask=False)\n\nlog(\"original_image\", original_image)\nlog(\"image_meta\", image_meta)\nlog(\"gt_class_id\", gt_class_id)\nlog(\"gt_bbox\", gt_bbox)\nlog(\"gt_mask\", gt_mask)\n\nvisualize.display_instances(original_image, gt_bbox, gt_mask, gt_class_id, \n                            dataset_train.class_names, figsize=(8, 8))\n\nresults = infer_model.detect([original_image], verbose=1)\n\nr = results[0]\nvisualize.display_instances(original_image, r['rois'], r['masks'], r['class_ids'], \n                            dataset_val.class_names, r['scores'])\n\nimage_ids = np.random.choice(dataset_val.image_ids, 20)\nAPs = []\ninference_start = time.time()\nfor image_id in image_ids:\n    image, image_meta, gt_class_id, gt_bbox, gt_mask =\\\n        modellib.load_image_gt(dataset_val, inference_config,\n                               image_id, use_mini_mask=False)\n    molded_images = np.expand_dims(modellib.mold_image(image, inference_config), 0)\n    results = infer_model.detect([image], verbose=1)\n    r = results[0]\n    visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'], \n                            dataset_val.class_names, r['scores'])\n\n    AP, precisions, recalls, overlaps =\\\n        utils.compute_ap(gt_bbox, gt_class_id, gt_mask,\n                         r[\"rois\"], r[\"class_ids\"], r[\"scores\"], r['masks'])\n    APs.append(AP)\n\ninference_end = time.time()\nprint('Inference Time: %0.2f Minutes'%((inference_end - inference_start)/60))\nprint(\"mAP: \", np.mean(APs))\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class InferenceConfig(AirbusShipDetectionChallengeGPUConfig):\n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 1\n\ninference_config = InferenceConfig()\ninfer_model = modellib.MaskRCNN(mode=\"inference\", \n                          config=inference_config,\n                          model_dir=WORKING_DIR)\n\nmodel_path = infer_model.find_last()\n\nprint(\"Loading weights from \", model_path)\ninfer_model.load_weights(model_path, by_name=True)\n\nimage_id = np.random.choice(dataset_val.image_ids)\noriginal_image, image_meta, gt_class_id, gt_bbox, gt_mask =\\\n    modellib.load_image_gt(dataset_val, inference_config, \n                           image_id, use_mini_mask=False)\n\nlog(\"original_image\", original_image)\nlog(\"image_meta\", image_meta)\nlog(\"gt_class_id\", gt_class_id)\nlog(\"gt_bbox\", gt_bbox)\nlog(\"gt_mask\", gt_mask)\n\nvisualize.display_instances(original_image, gt_bbox, gt_mask, gt_class_id, \n                            dataset_train.class_names, figsize=(8, 8))\n\nresults = infer_model.detect([original_image], verbose=1)\n\nr = results[0]\nvisualize.display_instances(original_image, r['rois'], r['masks'], r['class_ids'], \n                            dataset_val.class_names, r['scores'])\n\nimage_ids = np.random.choice(dataset_val.image_ids, 20)\nAPs = []\ninference_start = time.time()\nfor image_id in image_ids:\n    image, image_meta, gt_class_id, gt_bbox, gt_mask =\\\n        modellib.load_image_gt(dataset_val, inference_config,\n                               image_id, use_mini_mask=False)\n    molded_images = np.expand_dims(modellib.mold_image(image, inference_config), 0)\n    results = infer_model.detect([image], verbose=1)\n    r = results[0]\n    visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'], \n                            dataset_val.class_names, r['scores'])\n\n    AP, precisions, recalls, overlaps =\\\n        utils.compute_ap(gt_bbox, gt_class_id, gt_mask,\n                         r[\"rois\"], r[\"class_ids\"], r[\"scores\"], r['masks'])\n    APs.append(AP)\n\ninference_end = time.time()\nprint('Inference Time: %0.2f Minutes'%((inference_end - inference_start)/60))\nprint(\"mAP: \", np.mean(APs))\n","metadata":{},"execution_count":null,"outputs":[]}]}