{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\n# import numpy as np # linear algebra\n# import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Imports","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# Import required libraries\nimport os\nimport gc\nimport sys\nimport json\nimport random\nfrom pathlib import Path\nimport math\nimport re\nimport time\nimport numpy as np\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport skimage.io\n\n\n\nimport cv2 # CV2 for image manipulation\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nfrom tqdm import tqdm\n\nfrom imgaug import augmenters as iaa\n\nimport seaborn as sns\nimport matplotlib.image as mpimg\nfrom matplotlib import pyplot as plt\n\nfrom sklearn.model_selection import StratifiedKFold, KFold","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Required packages","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"## Required packages\n# ! conda activate tf1\n#!/bin/bash\n# ! conda env list\n!pip install tensorflow==1.15.0\n!pip install keras==2.1.5 --upgrade\n# !pip install keras==2.1.0 --upgrade\n\n\n\nimport tensorflow as tf\nprint(tf.__version__)\nimport keras\nprint(keras.__version__)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Competation and local paths, variables","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# local Notebook\n# label_description_path=r'/root/kaggle/label_descriptions.json'\n# sample_submission_path=r'/root/kaggle/sample_submission.csv'\n# train_path='/root/kaggle/train.csv'\n# COCO_WEIGHTS_PATH='/root/kaggle/Mask_RCNN/mask_rcnn_coco.h5'\n# DATA_DIR = Path('/root/kaggle/')\n# ROOT_DIR = os.path.abspath(\"/root/kaggle/Mask_RCNN/\")\n# ROOT_DIR2 = os.path.abspath(\"/root/kaggle/Mask_RCNN/\")\n# DEVICE = \"/gpu:0\"  # /cpu:0 or /gpu:0\n\n\n# # competation Notebook\nlabel_description_path=r'/kaggle/input/imaterialist-fashion-2020-fgvc7/label_descriptions.json'\nsample_submission_path=r'/kaggle/input/imaterialist-fashion-2020-fgvc7/sample_submission.csv'\ntrain_path=r'/kaggle/input/imaterialist-fashion-2020-fgvc7/train.csv'\nCOCO_WEIGHTS_PATH='mask_rcnn_coco.h5'\nDATA_DIR = Path('/kaggle/input/imaterialist-fashion-2020-fgvc7')\nROOT_DIR = os.path.abspath(\"/kaggle/working/Mask_RCNN/\")\nROOT_DIR2 = os.path.abspath(\"/kaggle/working/Mask_RCNN/\")\nDEVICE = \"/gpu:0\"  # /cpu:0 or /gpu:0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pwd","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# !git clone https://www.github.com/matterport/Mask_RCNN.git\n!git clone https://github.com/matterport/Mask_RCNN.git\nos.chdir('Mask_RCNN')\n\n!rm -rf .git\n!rm -rf images assets\n# \n# !wget --quiet https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5\n# !ls -lh mask_rcnn_coco.h5\n\nsys.path.append(ROOT_DIR)  # To find local version of the library\nsys.path.append(ROOT_DIR2)\nsys.path.append(os.path.abspath(\"../../\"))\n\n\n# !cd ../\n\nfrom mrcnn.config import Config\nfrom mrcnn import utils\nimport mrcnn.model as modellib\nfrom mrcnn import visualize\nfrom mrcnn.model import log\n\n%matplotlib inline \n\n\n# Directory to save logs and trained model\nMODEL_DIR = os.path.join(ROOT_DIR, \"logs\")\n\n# Local path to trained weights file\nCOCO_MODEL_PATH = os.path.join(ROOT_DIR, \"mask_rcnn_coco.h5\")\n# Download COCO trained weights from Releases if needed\nif not os.path.exists(COCO_MODEL_PATH):\n    utils.download_trained_weights(COCO_MODEL_PATH)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nwith open(label_description_path, 'r') as file:\n    label_desc = json.load(file)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_sub_df = pd.read_csv(sample_submission_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_sub_df.head()\nsample_sub_df.tail()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\ntrain_df = pd.read_csv(train_path)","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"train_df.head(20)\n# train_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f'Shape of training dataset: {train_df.shape}')\nprint(f'Num of images in training set: {train_df[\"ImageId\"].nunique()}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (70,7))\n# min_height = list(set(train_df[train_df['Height'] == train_df['Height'].min()]['ImageId']))[0]\nimg_id='00000663ed1ff0c4e0132b9b9ac53f6e'\nplt.imshow(mpimg.imread(f'{DATA_DIR}/train/{img_id}.jpg'))\nplt.grid(False)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"num_classes = len(label_desc['categories'])\nnum_attributes = len(label_desc['attributes'])\nprint(f'Total # of classes: {num_classes}')\nprint(f'Total # of attributes: {num_attributes}')","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"categories_df = pd.DataFrame(label_desc['categories'])\nattributes_df = pd.DataFrame(label_desc['attributes'])\ncategories_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pd.set_option('display.max_rows', 300)\nattributes_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_mask(size):\n    image_ids = train_df['ImageId'].unique()[size:size+size]\n    images_meta=[]\n\n    for image_id in image_ids:\n        img = mpimg.imread(f'{DATA_DIR}/train/{image_id}.jpg')\n#         print(img)\n        images_meta.append({\n            'image': img,\n            'shape': img.shape,\n            'encoded_pixels': train_df[train_df['ImageId'] == image_id]['EncodedPixels'],\n            'class_ids':  train_df[train_df['ImageId'] == image_id]['ClassId']\n        })\n\n    masks = []\n    for image in images_meta:\n        shape = image.get('shape')\n        encoded_pixels = list(image.get('encoded_pixels'))\n        class_ids = list(image.get('class_ids'))\n        \n        # Initialize numpy array with shape same as image size\n        height, width = shape[:2]\n        mask = np.zeros((height, width)).reshape(-1)\n        \n        # Iterate over encoded pixels and create mask\n        for segment, (pixel_str, class_id) in enumerate(zip(encoded_pixels, class_ids)):\n            splitted_pixels = list(map(int, pixel_str.split()))\n            pixel_starts = splitted_pixels[::2]\n            run_lengths = splitted_pixels[1::2]\n            assert max(pixel_starts) < mask.shape[0]\n            for pixel_start, run_length in zip(pixel_starts, run_lengths):\n                pixel_start = int(pixel_start) - 1\n                run_length = int(run_length)\n                mask[pixel_start:pixel_start+run_length] = 255 - class_id * 4\n        masks.append(mask.reshape((height, width), order='F'))  # https://stackoverflow.com/questions/45973722/how-does-numpy-reshape-with-order-f-work\n    return masks, images_meta","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_segmented_images(size=6, figsize=(14, 14)):\n    # First create masks from given segments\n    masks, images_meta = create_mask(size)\n    \n    # Plot images in groups of 4 images\n    n_groups = 4\n    \n    count = 0\n    for index in range(size // 4):\n        fig, ax = plt.subplots(nrows=2, ncols=2, figsize=figsize)\n        for row in ax:\n            for col in row:\n                col.imshow(images_meta[count]['image'])\n                col.imshow(masks[count], alpha=0.75)\n                col.axis('off')\n                count += 1\n        plt.show()\n    gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_segmented_images()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Data Prepration for class only","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = train_df.drop('AttributesIds', axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_df = train_df.groupby('ImageId')['EncodedPixels', 'ClassId'].agg(lambda x: list(x))\nsize_df = train_df.groupby('ImageId')['Height', 'Width'].mean()\nimage_df = image_df.join(size_df, on='ImageId')\nprint(\"Total images: \", len(image_df))\nimage_df.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_df['EncodedPixels'][0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"* # Start working on Mask-RCNN Repo","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"class My158Config(Config):\n    \"\"\"Configuration for training on the toy shapes dataset.\n    Derives from the base Config class and overrides values specific\n    to the toy shapes dataset.\n    \"\"\"\n    # Give the configuration a recognizable name\n    NAME = \"fashion\"\n\n    # Train on 1 GPU and 8 images per GPU. We can put multiple images on each\n    # GPU because the images are small. Batch size is 8 (GPUs * images/GPU).\n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 8\n\n    # Number of classes (including background)\n    NUM_CLASSES = 1 + len(categories_df)  # background + 3 shapes\n\n    # Use small images for faster training. Set the limits of the small side\n    # the large side, and that determines the image shape.\n    IMAGE_MIN_DIM = 256\n    IMAGE_MAX_DIM = 256\n\n    # Use smaller anchors because our image and objects are small\n    RPN_ANCHOR_SCALES = (8, 16, 32, 64, 128)  # anchor side in pixels\n\n    # Reduce training ROIs per image because the images are small and have\n    # few objects. Aim to allow ROI sampling to pick 33% positive ROIs.\n    TRAIN_ROIS_PER_IMAGE = 32\n\n    # Use a small epoch since the data is simple\n    STEPS_PER_EPOCH = 100\n\n    # use small validation steps since the epoch is small\n    VALIDATION_STEPS = 5\n    \n    LEARNING_RATE=0.01\n    \nconfig = My158Config()\nconfig.display()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# IMAGE_SIZE = 256\nclass FashionDataset(utils.Dataset):\n    \"\"\"Generates the shapes synthetic dataset. The dataset consists of simple\n    shapes (triangles, squares, circles) placed randomly on a blank surface.\n    The images are generated on the fly. No file access required.\n    \"\"\"\n    def __init__(self):\n        super().__init__(self)\n        \n        self.IMAGE_SIZE = 256\n\n    def load_images(self,img_df):\n        \"\"\"Generate the requested number of synthetic images.\n        count: number of images to generate.\n        height, width: the size of the generated images.\n        \"\"\"\n        # Add classes\n        for row in label_desc['categories']:\n#             print(row)\n            self.add_class(\"fashion\", int(row['id']),row['name'])\n            \n        # Add images\n        for i, row in img_df.iterrows():\n#             print(i,row)\n            self.add_image(\"fashion\",\n                           image_id=row.name, \n#                            path=str(DATA_DIR/'train'/row.name) + '.jpg',\n                           path=f'{DATA_DIR}/train/{row.name}.jpg',\n                           labels=row['ClassId'],\n                           annotations=row['EncodedPixels'], \n                           height=row['Height'], width=row['Width'],\n                           shape=[row['Height'],row['Width']])\n\n    def load_image(self, image_id):\n        \"\"\"Generate an image from the specs of the given image ID.\n        Typically this function loads the image from a file, but\n        in this case it generates the image on the fly from the\n        specs in image_info.\n        \"\"\"\n        info = self.image_info[image_id]\n#         bg_color = np.array(info['bg_color']).reshape([1, 1, 3])\n#         image = np.ones([info['height'], info['width'], 3], dtype=np.uint8)\n#         image = image * bg_color.astype(np.uint8)\n#         for shape, color, dims in info['shapes']:\n#             image = self.draw_shape(image, shape, dims, color)\n#         return image\n        return info\n\n    def _resize_image(self, image_path):\n            img = cv2.imread(image_path)\n            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n            img = cv2.resize(img, (self.IMAGE_SIZE, self.IMAGE_SIZE), interpolation=cv2.INTER_AREA)  \n            return img\n        \n    def load_image(self, image_id):\n        return self._resize_image(self.image_info[image_id]['path'])\n    \n    def image_reference(self, image_id):\n        info = self.image_info[image_id]\n        return info['path'], [x for x in info['labels']]\n    \n    def load_mask(self, image_id):\n        info = self.image_info[image_id]\n                \n        mask = np.zeros((self.IMAGE_SIZE, self.IMAGE_SIZE, len(info['annotations'])), dtype=np.uint8)\n        labels = []\n        \n        for m, (annotation, label) in enumerate(zip(info['annotations'], info['labels'])):\n            sub_mask = np.full(info['height']*info['width'], 0, dtype=np.uint8)\n            annotation = [int(x) for x in annotation.split(' ')]\n            \n            for i, start_pixel in enumerate(annotation[::2]):\n                sub_mask[start_pixel: start_pixel+annotation[2*i+1]] = 1\n\n            sub_mask = sub_mask.reshape((info['height'], info['width']), order='F')\n            sub_mask = cv2.resize(sub_mask, (self.IMAGE_SIZE, self.IMAGE_SIZE), interpolation=cv2.INTER_NEAREST)\n            \n            mask[:, :, m] = sub_mask\n            labels.append(int(label)+1)\n            \n        return mask, np.array(labels)\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Data prepration for traning Before shuflling and spliting\nfashion_data=FashionDataset()\nfashion_data.load_images(image_df)\nfashion_data.prepare()\n\nprint(\"Image Count: {}\".format(len(fashion_data.image_ids)))\nprint(\"Class Count: {}\".format(fashion_data.num_classes))\n# for i, info in enumerate(fashion_data.class_info):\n#     print(\"{:3}. {:50}\".format(i, info['name']))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# fashion_data.class_names","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(6):\n    image_id = random.choice(fashion_data.image_ids)\n    image = fashion_data.load_image(image_id)\n#     print(image)\n    mask, class_ids = fashion_data.load_mask(image_id)\n    visualize.display_top_masks(image, mask, class_ids, fashion_data.class_names, limit=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Shaflling data \nsufful_img_df=image_df.reindex(np.random.permutation(image_df.index))\n# sufful_img_df\n\n#Spliting data Train and validation\ndef split_vals(a,n): return a[:n], a[n:]\nn_valid = int(len(sufful_img_df)/100*20)\nn_trn = len(sufful_img_df)-n_valid\ntrain_df, valid_df = split_vals(sufful_img_df, n_trn)\nprint('Traning and Validation dataset shapes!')\nprint(train_df.shape)\nprint(valid_df.shape)\n\n#Data prepration for traning\nfashion_data=FashionDataset()\nfashion_data.load_images(train_df)\nfashion_data.prepare()\n\n\n# Data prepration for validation\n# Validation dataset\nvalid_fashion_data=FashionDataset()\nvalid_fashion_data.load_images(valid_df)\nvalid_fashion_data.prepare()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Second method of spliting and shuffling\n#Split to training and validation data \n# from sklearn.utils import shuffle\n\n# random.seed(42)\n# images_data_shuffled = shuffle(image_df)\n# val_size = int(0.05 * len(images_data_shuffled['ClassId']))\n# valid_df = images_data_shuffled[:val_size]\n# train_df = images_data_shuffled[val_size:]\n\n# # print(len(image_data_train), len(image_data_val))\n# print(f'Training set: {train_df.shape} \\nValidation set: {valid_df.shape}')\n\n\n# #Data prepration for traning\n# fashion_data=FashionDataset()\n# fashion_data.load_images(train_df)\n# fashion_data.prepare()\n\n\n# # Data prepration for validation\n# # Validation dataset\n# valid_fashion_data=FashionDataset()\n# valid_fashion_data.load_images(valid_df)\n# valid_fashion_data.prepare()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Traning Dataset Visualization\nfor i in range(6):\n    image_id = random.choice(fashion_data.image_ids)\n    image = fashion_data.load_image(image_id)\n#     print(image)\n    mask, class_ids = fashion_data.load_mask(image_id)\n    visualize.display_top_masks(image, mask, class_ids, fashion_data.class_names, limit=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Validation Dataset Visualization\nfor i in range(6):\n    image_id = random.choice(valid_fashion_data.image_ids)\n    image = valid_fashion_data.load_image(image_id)\n#     print(image)\n    mask, class_ids = valid_fashion_data.load_mask(image_id)\n    visualize.display_top_masks(image, mask, class_ids, valid_fashion_data.class_names, limit=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Note that any hyperparameters here, such as LR, may still not be optimal\nLR = 1e-4\nEPOCHS = [1, 6, 8]\n\nimport warnings \nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with tf.device(DEVICE):\n    model = modellib.MaskRCNN(mode='training',#'',inference\n                              config=config, model_dir=ROOT_DIR2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.load_weights(COCO_WEIGHTS_PATH, by_name=True,\n                   exclude=[\"mrcnn_class_logits\", \"mrcnn_bbox_fc\", \n                            \"mrcnn_bbox\", \"mrcnn_mask\"])#, \"mrcnn_mask\"\n\naugmentation = iaa.Sequential([\n    iaa.Fliplr(0.5) # only horizontal flip here\n])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nmodel.train(fashion_data, valid_fashion_data, \n            learning_rate=config.LEARNING_RATE, \n            epochs=10, \n            layers='heads')\nhistory = model.keras_model.history.history","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Fine tune all layers\n# Passing layers=\"all\" trains all layers. You can also \n# pass a regular expression to select which layers to\n# train by name pattern.\n\n# model.train(fashion_data, valid_fashion_data, \n#             learning_rate=config.LEARNING_RATE / 10,\n#             epochs=2, \n#             layers=\"all\",\n#             augmentation=augmentation)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Save weights\n# Typically not needed because callbacks save after every epoch\n# Uncomment to save manually\nmodel_path = os.path.join(ROOT_DIR2, \"mask_rcnn_fashion.h5\")\nmodel.keras_model.save_weights(model_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"best_epoch = np.argmin(history[\"val_loss\"]) + 1\nprint(\"Best epoch: \", best_epoch)\nprint(\"Valid loss: \", history[\"val_loss\"][best_epoch-1])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df = sample_sub_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class InferenceConfig(My158Config):\n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 1\n\ninference_config = InferenceConfig()\n\nmodel = modellib.MaskRCNN(mode='inference', \n                          config=inference_config,\n                          model_dir=ROOT_DIR2)\n\n\n# assert model_path != '', \"Provide path to trained weights\"\n# print(\"Loading weights from \", model_path)\n# model.load_weights(model_path, by_name=True)\n\n\n# model_path = os.path.join(ROOT_DIR, \"mask_rcnn_fashion.h5\")\nmodel_path = model.find_last()\n\n# Load trained weights\nprint(\"Loading weights from \", model_path)\nmodel.load_weights(model_path, by_name=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Notebook Preferences","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_ax(rows=1, cols=1, size=8):\n    \"\"\"Return a Matplotlib Axes array to be used in\n    all visualizations in the notebook. Provide a\n    central point to control graph sizes.\n    \n    Change the default size attribute to control the size\n    of rendered images\n    \"\"\"\n    _, ax = plt.subplots(rows, cols, figsize=(size*cols, size*rows))\n    return ax## Notebook Preferences","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Ground Truth and Prediction Test","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Test on a random image and load annoted mask\nimage_id = random.choice(valid_fashion_data.image_ids)\noriginal_image, image_meta, gt_class_id, gt_bbox, gt_mask =\\\n    modellib.load_image_gt(valid_fashion_data, 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                            fashion_data.class_names, figsize=(8, 8))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load predictid mask\nresults = model.detect([original_image], verbose=1)\n# print(results)\nr = results[0]\nvisualize.display_instances(original_image, r['rois'], r['masks'], r['class_ids'], \n                            fashion_data.class_names, r['scores'], ax=get_ax())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Convert mask to run-length","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Convert data to run-length encoding\nimport itertools\ndef to_rle(bits):\n    rle = []\n    pos = 0\n    for bit, group in itertools.groupby(bits):\n        group_list = list(group)\n        if bit:\n            rle.extend([pos, sum(group_list)])\n        pos += len(group_list)\n    return rle","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Since the submission system does not permit overlapped masks, we have to fix them\ndef refine_masks(masks, rois):\n    areas = np.sum(masks.reshape(-1, masks.shape[-1]), axis=0)\n    mask_index = np.argsort(areas)\n    union_mask = np.zeros(masks.shape[:-1], dtype=bool)\n    for m in mask_index:\n        masks[:, :, m] = np.logical_and(masks[:, :, m], np.logical_not(union_mask))\n        union_mask = np.logical_or(masks[:, :, m], union_mask)\n    for m in range(masks.shape[-1]):\n        mask_pos = np.where(masks[:, :, m]==True)\n        if np.any(mask_pos):\n            y1, x1 = np.min(mask_pos, axis=1)\n            y2, x2 = np.max(mask_pos, axis=1)\n            rois[m, :] = [y1, x1, y2, x2]\n    return masks, rois","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IMAGE_SIZE = 1024","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def resize_image(image_path):\n    img = cv2.imread(image_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = cv2.resize(img, (IMAGE_SIZE, IMAGE_SIZE), interpolation=cv2.INTER_AREA)  \n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nsub_list = []\nmissing_count = 0\nfor i, row in tqdm(sample_df.iterrows(), total=len(sample_df)):\n#     image = resize_image(str(DATA_DIR/'test'/row['ImageId']) + '.jpg')\n    image = resize_image(f'{DATA_DIR}/test/{row[\"ImageId\"]}.jpg')\n    \n    result = model.detect([image], verbose=1)[0]\n    if result['masks'].size > 0:\n        masks, _ = refine_masks(result['masks'], result['rois'])\n        for m in range(masks.shape[-1]):\n            mask = masks[:, :, m].ravel(order='F')\n            rle = to_rle(mask)\n            label = result['class_ids'][m] - 1\n#             sub_list.append([row['ImageId'], ' '.join(list(map(str, rle))), label, np.NaN])#111,137\n            sub_list.append([row['ImageId'], ' '.join(list(map(str, rle))), label, '111,137'])\n            \n#         print(sub_list)\n    else:\n        # The system does not allow missing ids, this is an easy way to fill them \n        sub_list.append([row['ImageId'], '1 1', 23, '111,137'])\n        missing_count += 1\n#         print('Misssssss')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_sub_df.columns","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df = pd.DataFrame(sub_list, columns=sample_df.columns.values)\nprint(\"Total image results: \", submission_df['ImageId'].nunique())\nprint(\"Missing Images: \", missing_count)\nsubmission_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(9):\n    image_id = sample_df.sample()['ImageId'].values[0]\n#     image_path = str(DATA_DIR/'test'/image_id)\n    image_path = fr'{DATA_DIR}/test/{image_id}.jpg'\n#     print(image_id)\n#     print(image_path)\n    \n    \n    img = cv2.imread(image_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    result = model.detect([resize_image(image_path)])\n    r = result[0]\n    \n    if r['masks'].size > 0:\n        masks = np.zeros((img.shape[0], img.shape[1], r['masks'].shape[-1]), dtype=np.uint8)\n        for m in range(r['masks'].shape[-1]):\n            masks[:, :, m] = cv2.resize(r['masks'][:, :, m].astype('uint8'), \n                                        (img.shape[1], img.shape[0]), interpolation=cv2.INTER_NEAREST)\n        \n        y_scale = img.shape[0]/IMAGE_SIZE\n        x_scale = img.shape[1]/IMAGE_SIZE\n        rois = (r['rois'] * [y_scale, x_scale, y_scale, x_scale]).astype(int)\n        \n        masks, rois = refine_masks(masks, rois)\n    else:\n        masks, rois = r['masks'], r['rois']\n        \n    visualize.display_instances(img, rois, masks, r['class_ids'],fashion_data.class_names,\n                                 r['scores'],\n                                title=image_id, figsize=(12, 12))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Evaluation","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Compute VOC-Style mAP @ IoU=0.5\n# Running on 10 images. Increase for better accuracy.\nimage_ids = np.random.choice(valid_fashion_data.image_ids, 10)\nAPs = []\nfor image_id in image_ids:\n    # Load image and ground truth data\n    image, image_meta, gt_class_id, gt_bbox, gt_mask =\\\n        modellib.load_image_gt(valid_fashion_data, inference_config,\n                               image_id, use_mini_mask=False)\n    molded_images = np.expand_dims(modellib.mold_image(image, inference_config), 0)\n    # Run object detection\n    results = model.detect([image], verbose=0)\n    r = results[0]\n    # Compute AP\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    \nprint(\"mAP: \", np.mean(APs))","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}