{"cells":[{"metadata":{"id":"aeppA1t3iLco"},"cell_type":"markdown","source":"## Colab Setup"},{"metadata":{"id":"ihQoHnOpnpIF","trusted":true},"cell_type":"code","source":"import warnings \nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"id":"kOFCQQ6vioP9","outputId":"3fa81d5e-4f51-4d8a-de52-24646569d70f","trusted":true},"cell_type":"code","source":"# importing libraries\nimport os\nimport gc\nimport sys\nimport math\nimport json\nimport glob\nimport random\nfrom pathlib import Path\n\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport skimage.io\nfrom IPython.display import clear_output\n\nimport itertools\nfrom tqdm import tqdm\n\nfrom imgaug import augmenters as iaa\nfrom sklearn.model_selection import StratifiedKFold, KFold\n\nimport tensorflow as tf","execution_count":null,"outputs":[]},{"metadata":{"id":"3qymY3pZimRT","trusted":true},"cell_type":"code","source":"TRAIN_IMAGE_DIR = Path('/kaggle/input/imaterialist-fashion-2019-FGVC6/train')\nDATA_DIR = Path('/kaggle/input/imaterialist-fashion-2019-FGVC6')\nROOT_DIR = Path('/kaggle/working')","execution_count":null,"outputs":[]},{"metadata":{"id":"VmYNz4SOtDQz"},"cell_type":"markdown","source":"## Data Import"},{"metadata":{"id":"ZSb8KQyUieSM","outputId":"4deebac1-f737-4899-fac3-9ab1c3a542b8","trusted":true},"cell_type":"code","source":"# import train file \nimport pandas as pd\ntrain = pd.read_csv(str(DATA_DIR/'train.csv'))\ntrain.head()\n# train = train[train['ClassId'] <= \"10\"]\n# train.head()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(train))","execution_count":null,"outputs":[]},{"metadata":{"id":"e0fa3ptlmgMb","trusted":true},"cell_type":"code","source":"# extracting image metadata fom json file \nwith open(str(DATA_DIR/'label_descriptions.json')) as f:\n    label_descriptions = json.load(f)\n\nlabel_names = [x['name'] for x in label_descriptions['categories']]\nlabel_names = label_names[:11]\nlabel_names","execution_count":null,"outputs":[]},{"metadata":{"id":"pJrR-VPfZPou","outputId":"183c815b-487c-4c6c-c3dd-f0dcccc67af4","trusted":true},"cell_type":"code","source":"label_df = pd.DataFrame(label_names).reset_index()\nlabel_df.columns = ['Id','Labels']\nlabel_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(label_df))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#ClassId = 0,1 and 10\n\nsegment_df = train\nsegment_df['CategoryId'] = segment_df['ClassId'].str.split('_').str[0]\ndf1 = segment_df[segment_df['CategoryId'] <= \"10\"]\n# df2 = segment_df[segment_df['CategoryId'] == \"1\"] \n# df3 = segment_df[segment_df['CategoryId'] == \"10\"]\n\n# segment_df = segment_df[:10]\n# df1 = df1.append(df2)\n# df1 = df1.append(df3)\n\nsegment_df = df1\nprint(\"Total segments: \", len(segment_df))\nsegment_df","execution_count":null,"outputs":[]},{"metadata":{"id":"zdXAO25VmueC","outputId":"4bdb20e6-f253-496d-d163-640100373ece","trusted":true},"cell_type":"code","source":"# segment_df = train\n# segment_df['CategoryId'] = segment_df['ClassId'].str.split('_').str[0]\n# # segment_df = segment_df[segment_df['ClassId'] <= \"10\"]\n# # train.head()\n# print(\"Total segments: \", len(segment_df))\n# segment_df","execution_count":null,"outputs":[]},{"metadata":{"id":"Q5nBd2K1mz4V","outputId":"31f48aec-4479-449f-b0b9-74ce20fa409a","trusted":true},"cell_type":"code","source":"# Rows with the same image are grouped together because the subsequent operations perform at an image level\nimage_df = segment_df.groupby('ImageId')['EncodedPixels', 'CategoryId'].agg(lambda x: list(x))\nsize_df = segment_df.groupby('ImageId')['Height', 'Width'].mean()\nimage_df = image_df.join(size_df, on='ImageId')\n\nprint(\"Total images: \", len(image_df))\nimage_df","execution_count":null,"outputs":[]},{"metadata":{"id":"1aioKf2gcbis"},"cell_type":"markdown","source":"## EDA"},{"metadata":{"id":"QezPVoouk3GD","outputId":"b9e14744-a946-4e07-e987-ac08953779df","trusted":true},"cell_type":"code","source":"plt.figure(figsize=(15, 7))\nsns.jointplot(x=image_df['Width'], y=image_df['Height'])","execution_count":null,"outputs":[]},{"metadata":{"id":"bPXp2cb-PONM","outputId":"fe67248a-c730-49d9-c9e7-ce06cee9af9d","trusted":true},"cell_type":"code","source":"plt.figure(figsize=(7, 5))\nsns.distplot(image_df['Height'], kde=False);\nplt.title(\"Height Distribution\", fontsize=10)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"56fqtfQlR4BS","outputId":"fb84f8bb-1433-427d-bd37-493d954cdfd2","trusted":true},"cell_type":"code","source":"plt.figure(figsize=(7, 5))\nsns.distplot(image_df['Width'], kde=False);\nplt.title(\"Width Distribution\", fontsize=10)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"IKYAijq1R-fO","outputId":"8fff162a-e92f-4cfe-98c1-c52f8095983a","trusted":true},"cell_type":"code","source":"plt.figure(figsize=(10, 5))\nsns.distplot((image_df['Height'] * image_df['Width'])/10000, kde=False);\nplt.title(\"Area Distribution /(10000)\", fontsize=10)\nplt.xlabel(\" Area (in 10k)\", fontsize=10)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"S24gl9DR3yZi","outputId":"264ed2e4-be94-46e3-8c55-800cc5b644e2","trusted":true},"cell_type":"code","source":"# number of labels per image\nlabels_per_image = image_df['CategoryId'].map(lambda x:len(x)).value_counts().to_frame().reset_index().sort_values(by = 'index')\nlabels_per_image.columns = ['#labels','#images']\n\nplt.figure(figsize=(15, 7))\nsns.barplot(labels_per_image['#labels'],labels_per_image['#images'])\nplt.title(\"Number of Labels per Image\", fontsize=20)\nplt.xlabel(\"# of labels\", fontsize=20)\nplt.ylabel(\"# of images\", fontsize=20)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"id":"sxfCSQI_fNQ6","outputId":"8b12a9c6-6abe-4fc6-ed3d-00ad346e125c","trusted":true},"cell_type":"code","source":"segment_df['CategoryId'] = segment_df['CategoryId'].astype('int64')\nlabels_per_image2 = segment_df.merge(label_df, how='left', left_on='CategoryId', right_on='Id')\nlabels_per_image3 = labels_per_image2.groupby('Labels')['ImageId'].nunique().to_frame().reset_index()\nlabels_per_image3.head()","execution_count":null,"outputs":[]},{"metadata":{"id":"2GjNr8Uhr3W8","outputId":"e8589839-e241-4b12-8260-79292696affa","trusted":true},"cell_type":"code","source":"labels_per_image4 = labels_per_image2.groupby('Labels')['ImageId'].count().to_frame().reset_index()\nlabels_per_image4.head()","execution_count":null,"outputs":[]},{"metadata":{"id":"wTQvQ_82E_g6","trusted":true},"cell_type":"code","source":"labels_per_image4.to_csv('word_cloud_data.csv')","execution_count":null,"outputs":[]},{"metadata":{"id":"BqdaikIYjwvE","trusted":true},"cell_type":"code","source":"d = {}\nfor i in range(len(labels_per_image4)):\n    d[labels_per_image4.iloc[i,0]] = labels_per_image4.iloc[i,1]","execution_count":null,"outputs":[]},{"metadata":{"id":"gy2f7MefpCV6","outputId":"f1ed823f-4ae3-4921-9f54-2d81d84a4d19","trusted":true},"cell_type":"code","source":"from wordcloud import WordCloud\n\nwordcloud = WordCloud(background_color='Ghostwhite')\nwordcloud.generate_from_frequencies(frequencies=d)\n\nplt.figure(figsize=(25, 7))\nplt.imshow(wordcloud, interpolation=\"bilinear\")\nplt.axis(\"off\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"sta9ktaBg0K2","outputId":"33828296-2fa5-4e23-b680-2dcd617116f5","trusted":true},"cell_type":"code","source":"plt.figure(figsize=(20, 7))\nsns.barplot(labels_per_image3['Labels'],labels_per_image3['ImageId'])\nplt.xticks(rotation=90)\nplt.title(\"Labels Distribution in Images\", fontsize=20)\nplt.xlabel(\"labels\", fontsize=10)\nplt.ylabel(\"# of images\", fontsize=10)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"ZNWAFGWUtMe7"},"cell_type":"markdown","source":"## Data Setup"},{"metadata":{"id":"_FMO184li4WD","trusted":true},"cell_type":"code","source":"# Since we are training on ~5k images, we will fetch train data for those 5k images\n\nimages = os.listdir(TRAIN_IMAGE_DIR)\nuploaded_images = pd.DataFrame(images, columns = ['image_name'])\nimage_df = image_df[image_df.index.isin(uploaded_images['image_name'])]","execution_count":null,"outputs":[]},{"metadata":{"id":"sRqZ3qAPwlKF","outputId":"93262c3a-294c-415a-9446-d6a2c9805c05","trusted":true},"cell_type":"code","source":"image_df.shape","execution_count":null,"outputs":[]},{"metadata":{"id":"mOl0unwcnAT4","trusted":true},"cell_type":"code","source":"# Partition data in train and test\nFOLD = 0\nN_FOLDS = 10\n\nkf = KFold(n_splits=N_FOLDS, random_state=42, shuffle=True)\nsplits = kf.split(image_df) # ideally, this should be multilabel stratification\n\ndef get_fold():    \n    for i, (train_index, valid_index) in enumerate(splits):\n        if i == FOLD:\n            return image_df.iloc[train_index], image_df.iloc[valid_index]\n        \ntrain_df, valid_df = get_fold()","execution_count":null,"outputs":[]},{"metadata":{"id":"L5reMvwmkmQk"},"cell_type":"markdown","source":"## Setting up Mask RCNN"},{"metadata":{"trusted":true},"cell_type":"code","source":"!rm -rf Mask_RCNN ","execution_count":null,"outputs":[]},{"metadata":{"id":"qPNrm8gdjzDM","outputId":"e5ffef31-2bdd-4a84-d158-3fa7223649e8","trusted":true},"cell_type":"code","source":"# import matterport Mask-RCNN implementation\n!git clone https://github.com/Kedar-V/Mask_RCNN.git\nos.chdir('Mask_RCNN')\n\n!rm -rf .git # to prevent an error when the kernel is committed\n!rm -rf images assets # to prevent displaying images at the bottom of a kernel\n\nsys.path.append(ROOT_DIR/'Mask_RCNN')\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},"cell_type":"code","source":"!wget --quiet https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5\n!ls -lh mask_rcnn_coco.h5\n\nCOCO_WEIGHTS_PATH = \"mask_rcnn_coco.h5\"","execution_count":null,"outputs":[]},{"metadata":{"id":"gsJqumHBkKkB","trusted":true},"cell_type":"code","source":"# # Already have trained weights, we will continue on those weights\n# pre_trained_weight = '/content/drive/My Drive/Projects/iMaterialist/trained weights/weights_0.08133.h5'","execution_count":null,"outputs":[]},{"metadata":{"id":"5CxWGp9elzGD","outputId":"57499cf9-724d-4663-a28f-3f35a5cb7a8c","trusted":true},"cell_type":"code","source":"# Set configuration\n\nNUM_CATS = 11  # classification ignoring attributes (only categories)\nIMAGE_SIZE = 512 # the image size is set to 512, which is the same as the size of submission masks\n\nclass FashionConfig(Config):\n    NAME = \"fashion\"\n    NUM_CLASSES = NUM_CATS + 1 # +1 for the background class\n    \n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 4 # Batch size - memory error occurs when IMAGES_PER_GPU is too high\n    #https://datascience.stackexchange.com/questions/29719/how-to-set-batch-size-steps-per-epoch-and-validation-steps\n    \n    BACKBONE = 'resnet50' #resnet50 will be lighter than resnet101 for training\n    \n    IMAGE_MIN_DIM = IMAGE_SIZE\n    IMAGE_MAX_DIM = IMAGE_SIZE    \n    IMAGE_RESIZE_MODE = \"none\"\n    \n#     RPN_ANCHOR_SCALES = (16, 32, 64, 128, 256)\n    RPN_ANCHOR_SCALES = (4, 8, 16, 32, 64)\n    DETECTION_MIN_CONFIDENCE = 0.7\n    DETECTION_NMS_THRESHOLD = 0.7\n\n    STEPS_PER_EPOCH = 1000\n    VALIDATION_STEPS = 200\n\n    MAX_GT_INSTANCES = 12\n    DETECTION_MAX_INSTANCES = 12\n\n    ## balance out losses\n    # https://stackoverflow.com/questions/55360262/what-exactly-are-the-losses-in-matterport-mask-r-cnn\n    # https://stackoverflow.com/questions/46272841/what-is-the-loss-function-of-the-mask-rcnn\n    LOSS_WEIGHTS = {\n          \"rpn_class_loss\": 1.0, # How well the Region Proposal Network separates background with objetcs\n          \"rpn_bbox_loss\": 0.8, # How well the RPN localize objects\n          \"mrcnn_class_loss\": 6.0, # How well the Mask RCNN localize objects\n          \"mrcnn_bbox_loss\": 6.0, # How well the Mask RCNN recognize each class of object\n          \"mrcnn_mask_loss\": 6.0 # How well the Mask RCNN segment objects\n    }\n    \nconfig = FashionConfig()\nconfig.display()","execution_count":null,"outputs":[]},{"metadata":{"id":"iLwWMXcWl1g7","trusted":true},"cell_type":"code","source":"# resizing image to 512X512;\ndef 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":{"id":"O3Mf92oXl8A5","trusted":true},"cell_type":"code","source":"#  MaskRCNN Class\n\nclass FashionDataset(utils.Dataset):\n\n    def __init__(self, df):\n        super().__init__(self)\n        \n        #Add classes\n        for i, name in enumerate(label_names):\n            self.add_class(\"fashion\", i+1, name)\n#         self.add_class(\"fashion\", 1, \"shirt, blouse\")\n#         self.add_class(\"fashion\", 2, \"top, t-shirt, sweatshirt\")\n#         self.add_class(\"fashion\", 10, \"dress\")\n        \n        # Add images \n        for i, row in df.iterrows():\n            self.add_image(\"fashion\", \n                           image_id=row.name, \n                           path=str(TRAIN_IMAGE_DIR/row.name), \n                           labels=row['CategoryId'],\n                           annotations=row['EncodedPixels'], \n                           height=row['Height'], width=row['Width'])\n\n    def image_reference(self, image_id):\n        info = self.image_info[image_id]\n        return info['path'], [label_names[int(x)] for x in info['labels']]\n    \n    def load_image(self, image_id):\n        return resize_image(self.image_info[image_id]['path'])\n\n    def load_mask(self, image_id):\n        info = self.image_info[image_id]\n                \n        mask = np.zeros((IMAGE_SIZE, 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, (IMAGE_SIZE, 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)","execution_count":null,"outputs":[]},{"metadata":{"id":"Mjgz5SmBmWo0","outputId":"79b9729a-6a53-4d82-b1ba-79df82e04e84","trusted":true},"cell_type":"code","source":"# Visualizing random images\ndataset = FashionDataset(image_df)\ndataset.prepare()\n\nfor i in range(1):\n    image_id = random.choice(dataset.image_ids)\n    print(dataset.image_reference(image_id))\n    \n    image = dataset.load_image(image_id)\n    mask, class_ids = dataset.load_mask(image_id)\n    print(class_ids)\n    print(dataset.class_names)\n    visualize.display_top_masks(image, mask, class_ids, dataset.class_names, limit=4)","execution_count":null,"outputs":[]},{"metadata":{"id":"Oqu7S00ynUPP","trusted":true},"cell_type":"code","source":"# Prepare Data\ntrain_dataset = FashionDataset(train_df)\ntrain_dataset.prepare()\n\nvalid_dataset = FashionDataset(valid_df)\nvalid_dataset.prepare()","execution_count":null,"outputs":[]},{"metadata":{"id":"oFd7gBkmndnV"},"cell_type":"markdown","source":"## Training Model"},{"metadata":{"id":"5IcvzmWF5xTO","trusted":true},"cell_type":"code","source":"# Image augmentation\naugmentation = iaa.Sequential([\n    iaa.OneOf([ ## rotate\n        iaa.Affine(rotate=0),\n        iaa.Affine(rotate=90),\n        iaa.Affine(rotate=180),\n        iaa.Affine(rotate=270),\n    ]),\n    iaa.Fliplr(0.5),\n    iaa.Flipud(0.5),\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.3)),\n        iaa.Sharpen(alpha=(0.0, 0.3)),\n    ]),\n])","execution_count":null,"outputs":[]},{"metadata":{"id":"mbBGcTpUKcFd","outputId":"0c667f6e-4e7b-4c40-d286-1427b0d4b59c","trusted":true},"cell_type":"code","source":"# sample augmentation output\nimggrid = augmentation.draw_grid(image, cols=5, rows=2)\nplt.figure(figsize=(20, 10))\n_ = plt.imshow(imggrid.astype(int))","execution_count":null,"outputs":[]},{"metadata":{"id":"dU8B9fEgnfEv","outputId":"2327da8c-7cdb-44ac-e15b-c74c70409a20","trusted":true},"cell_type":"code","source":"# initiating Mask R-CNN training\n\nmodel = modellib.MaskRCNN(mode='training', config=config, model_dir=ROOT_DIR);\nmodel.load_weights(COCO_WEIGHTS_PATH, by_name=True, exclude=[\n    'mrcnn_class_logits', 'mrcnn_bbox_fc', 'mrcnn_bbox', 'mrcnn_mask'])","execution_count":null,"outputs":[]},{"metadata":{"id":"98VTYrL46NHk","trusted":true},"cell_type":"code","source":"# Declaring learning rate\nLR = 0.0001","execution_count":null,"outputs":[]},{"metadata":{"id":"W0REwZEz6wBb","trusted":true},"cell_type":"code","source":"## train head layer alone\n\n# %%time\n# model.train(train_dataset, valid_dataset,\n#             learning_rate=LR*2,\n#             epochs=2, # EPOCHS[0],\n#             layers='heads',\n#             augmentation=augmentation)\n# history = model.keras_model.history.history\n# history","execution_count":null,"outputs":[]},{"metadata":{"id":"WvtPvTRe6mLA","outputId":"f5797874-fc58-44de-af08-54fae84b6251","trusted":true},"cell_type":"code","source":"# %%time\n# model.train(train_dataset, valid_dataset,\n#             learning_rate=LR/4,\n#             epochs=1,\n#             layers='all',\n#             augmentation=augmentation)\n\n# # new_history = model.keras_model.history.history\n# # for k in new_history: history[k] = history[k] + new_history[k]\n# history = model.keras_model.history.history","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# epochs = range(1, len(history['loss'])+1)\n# pd.DataFrame(history, index=epochs)\n\n# # find best epoch\n# best_epoch = np.argmin(history[\"val_loss\"]) + 1\n# print(\"Best epoch: \", best_epoch)\n# print(\"Valid loss: \", history[\"val_loss\"][best_epoch-1])\n\n# glob_list = glob.glob(f'/kaggle/working/fashion*/mask_rcnn_fashion_{best_epoch:04d}.h5')\n# model_path = glob_list[0] if glob_list else ''\n# print(model_path)","execution_count":null,"outputs":[]},{"metadata":{"id":"-3BJn-n560MQ","outputId":"ab383760-c831-4fbe-9b41-9e29f23fb88d","trusted":true},"cell_type":"code","source":"# %%time\n# model.train(train_dataset, valid_dataset,\n#             learning_rate=LR/8,\n#             epochs=15,\n#             layers='all',\n#             augmentation=augmentation)\n\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":{"id":"oeR8jnK4KvTH","outputId":"7f12f4cf-73cb-4184-be8b-6657abed24ea","trusted":true},"cell_type":"code","source":"# epochs = range(1, len(history['loss'])+1)\n# pd.DataFrame(history, index=epochs)","execution_count":null,"outputs":[]},{"metadata":{"id":"SNllC_067yF7","outputId":"aefe2165-e5d5-47cf-d757-60ddbdcbad79","trusted":true},"cell_type":"code","source":"# find best epoch\n# best_epoch = np.argmin(history[\"val_loss\"]) + 1\n# # best_epoch = 20\n# print(\"Best epoch: \", best_epoch)\n# print(\"Valid loss: \", history[\"val_loss\"][best_epoch-1])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# os.chdir('/kaggle/working')\n# !ls","execution_count":null,"outputs":[]},{"metadata":{"id":"hPFgaGDFDxak","trusted":true},"cell_type":"code","source":"# glob_list = glob.glob(f'/kaggle/working/fashion*/mask_rcnn_fashion_{best_epoch:04d}.h5')\n# model_path = glob_list[0] if glob_list else ''\n# print(model_path)\nmodel_path = \"/kaggle/input/10-classes/mask_rcnn_fashion_0020.h5\"\n","execution_count":null,"outputs":[]},{"metadata":{"id":"9raJRHTgt6gN","trusted":true},"cell_type":"code","source":"# model_path = '/content/fashion20191109T2055/mask_rcnn_fashion_0007.h5'","execution_count":null,"outputs":[]},{"metadata":{"id":"Fi2WKPTpFEet"},"cell_type":"markdown","source":"## Prediction"},{"metadata":{"trusted":true},"cell_type":"code","source":"# import os\n# print(os.listdir(\"/kaggle/input/10-classes/mask_rcnn_fashion_0020.h5\"))","execution_count":null,"outputs":[]},{"metadata":{"id":"AOB7hKkoEoGB","outputId":"ab35a82a-b4ad-4eee-ea29-bdcc42ef0ee3","trusted":true},"cell_type":"code","source":"# Prediction, this cell defines InferenceConfig and loads the best trained model.\n\nclass InferenceConfig(FashionConfig):\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_DIR)\n\nmodel.load_weights(model_path, by_name=True)","execution_count":null,"outputs":[]},{"metadata":{"id":"BTOxLFUbEzY_","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":{"id":"vyKxPF4hE1Sw","outputId":"36c69662-4964-42f9-be5e-f11f228e1ad2","trusted":true},"cell_type":"code","source":"# Let’s load an image and try to see how the model performs. You can use any of your images to test the model.\n\n# Load a random image from the images folder\nimport skimage.io\nimport numpy as np\nimage_path = '/kaggle/input/imaterialist-fashion-2019-FGVC6/test/07960daf191c39d8a5c9ea31d0967b72.jpg'\n\n# original image\nplt.figure(figsize=(12,10))\nskimage.io.imshow(skimage.io.imread(image_path))\n\nimg = skimage.io.imread(image_path)\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\nresult = model.detect([resize_image(image_path)])\nr = result[0]\nif 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)\nelse:\n    masks, rois = r['masks'], r['rois']\n\nvisualize.display_instances(img, rois, masks, r['class_ids'], \n                            ['bg']+label_names, r['scores'])","execution_count":null,"outputs":[]},{"metadata":{"id":"1ZDbDFDzFDIW","outputId":"630efb4b-77f3-4738-c599-ed42369ede44","trusted":true},"cell_type":"code","source":"submission_file = pd.read_csv(\"/kaggle/input/imaterialist-fashion-2019-FGVC6/sample_submission.csv\")\nsubmission_file.head()","execution_count":null,"outputs":[]},{"metadata":{"id":"4ZUB-Lo2FJUJ","trusted":true},"cell_type":"code","source":"# Convert data to run-length encoding\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":{"id":"OTjxuUOSFMuJ","outputId":"d1b8e716-8e58-4568-9c43-0652e8f5be9d","trusted":true},"cell_type":"code","source":"%%time\ntest_path = Path('/kaggle/input/imaterialist-fashion-2019-FGVC6/test')\nsub_list = []\nmissing_count = 0\nfor i, row in tqdm(submission_file.iterrows(), total=len(submission_file)):\n    image = resize_image(str(test_path/row['ImageId']))\n    result = model.detect([image])[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])\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])\n        missing_count += 1","execution_count":null,"outputs":[]},{"metadata":{"id":"FbNw1ZyCFQHE","outputId":"41c30bb1-1734-43e8-f554-858def53e51d","trusted":true},"cell_type":"code","source":"# save predicted data in submission file to upload in Kaggle\nsubmission_df = pd.DataFrame(sub_list, columns=submission_file.columns.values)\nprint(\"Total image results: \", submission_df['ImageId'].nunique())\nprint(\"Missing Images: \", missing_count)\n\nsubmission_df.to_csv(ROOT_DIR/\"submission.csv\", index=False)\n\nsubmission_df","execution_count":null,"outputs":[]},{"metadata":{"id":"b2rE_LbFtVwm","trusted":true},"cell_type":"code","source":"# import time\n# time.sleep(5)\n\n# from google.colab import files\n# files.download('/content/submission.csv') ","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}