{"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":"import os, glob\nimport sys\nimport json\nfrom PIL import Image\nfrom collections import Counter\n\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\nimport plotly.graph_objects as go\nimport tifffile as tiff\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\n\nimport cv2\n\nfrom sklearn.model_selection import KFold\n\nsys.path.append(\"/kaggle/input/detection-wheel\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install pycocotools","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EPOCHS = 20","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport numpy as np\nimport torch\nfrom PIL import Image\n\n\nclass PennFudanDataset(torch.utils.data.Dataset):\n    def __init__(self, imgs, masks, transforms):\n        self.transforms = transforms\n        # load all image files, sorting them to\n        # ensure that they are aligned\n        self.imgs = imgs#sorted(glob.glob('/kaggle/input/hubmap-data-processing/train/image/*.png'))\n        self.masks = masks#sorted(glob.glob('/kaggle/input/hubmap-data-processing/train/mask/*.png'))\n\n    def __getitem__(self, idx):\n        # load images and masks\n        img_path = self.imgs[idx]\n        mask_path = self.masks[idx]\n        img = Image.open(img_path).convert(\"RGB\")\n        # note that we haven't converted the mask to RGB,\n        # because each color corresponds to a different instance\n        # with 0 being background\n        mask = Image.open(mask_path).convert('L')\n        # convert the PIL Image into a numpy array\n        mask = np.array(mask)\n        # instances are encoded as different colors\n        obj_ids = np.unique(mask)\n        # first id is the background, so remove it\n        obj_ids = obj_ids[1:]\n\n        # split the color-encoded mask into a set\n        # of binary masks\n        #masks = (mask == obj_ids[:, None, None])\n        #print((obj_ids[:, None, None]).shape)\n        #masks = mask == obj_ids[:, None, None]\n        masks = [np.where(mask== obj_ids[i, None, None],1,0) for i in range(len(obj_ids))]\n        masks = np.array(masks)\n\n        # get bounding box coordinates for each mask\n        num_objs = len(obj_ids)\n        boxes = []\n        for i in range(num_objs):\n            pos = np.nonzero(masks[i])\n            xmin = np.min(pos[1])\n            xmax = np.max(pos[1])\n            ymin = np.min(pos[0])\n            ymax = np.max(pos[0])\n            boxes.append([xmin, ymin, xmax, ymax])\n\n        # convert everything into a torch.Tensor\n        boxes = torch.as_tensor(boxes, dtype=torch.float32)\n        # there is only one class\n        labels = torch.ones((num_objs,), dtype=torch.int64)\n        masks = torch.as_tensor(masks, dtype=torch.uint8)\n\n        image_id = torch.tensor([idx])\n        try:\n            area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])\n            #print(area,area.shape,area.dtype)\n        except:\n            area = torch.tensor([[0],[0]])\n        # suppose all instances are not crowd\n        iscrowd = torch.zeros((num_objs,), dtype=torch.int64)\n        \n        #print(masks.shape)\n\n        target = {}\n        target[\"boxes\"] = boxes\n        target[\"labels\"] = labels\n        target[\"masks\"] = masks\n        target[\"image_id\"] = image_id\n        target[\"area\"] = area\n        target[\"iscrowd\"] = iscrowd\n\n        if self.transforms is not None:\n            img, target = self.transforms(img, target)\n\n        return img, target\n\n    def __len__(self):\n        return len(self.imgs)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torchvision\nfrom torchvision.models import list_models\ndetection_models = list_models(module=torchvision.models.detection)\ndetection_models","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torchvision\nimport torchvision\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nfrom torchvision.models.detection.mask_rcnn import MaskRCNNPredictor\nfrom torchvision.models.resnet import ResNet50_Weights\n\ndef get_model_instance_segmentation(num_classes):\n    # load an instance segmentation model pre-trained on COCO\n    model = torchvision.models.detection.maskrcnn_resnet50_fpn_v2(weights=\"DEFAULT\", weights_backbone=ResNet50_Weights.IMAGENET1K_V2)\n\n    # get number of input features for the classifier\n    in_features = model.roi_heads.box_predictor.cls_score.in_features\n    # replace the pre-trained head with a new one\n    model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)\n\n    # now get the number of input features for the mask classifier\n    in_features_mask = model.roi_heads.mask_predictor.conv5_mask.in_channels\n    hidden_layer = 256\n    # and replace the mask predictor with a new one\n    model.roi_heads.mask_predictor = MaskRCNNPredictor(in_features_mask,\n                                                       hidden_layer,\n                                                       num_classes)\n    return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import transforms as T\n\ndef get_transform(train):\n    transforms = []\n    transforms.append(T.PILToTensor())\n    transforms.append(T.ConvertImageDtype(torch.float))\n    if train:\n        transforms.append(T.RandomHorizontalFlip(0.5))\n    return T.Compose(transforms)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from engine import train_one_epoch, evaluate\nimport utils","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"n_imgs = len(glob.glob('/kaggle/input/hubmap-data-processing/train/image/*'))\nn_imgs","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kf = KFold(n_splits=5, shuffle=True, random_state=43)\nfor i, (train_index, test_index) in enumerate(kf.split(range(n_imgs))):\n    if i!=0: continue\n    all_imgs = sorted(glob.glob('/kaggle/input/hubmap-data-processing/train/image/*.png'))\n    all_masks = sorted(glob.glob('/kaggle/input/hubmap-data-processing/train/mask/*.png'))\n    all_imgs = np.array(all_imgs)\n    all_masks = np.array(all_masks)\n    train_img = all_imgs[train_index]\n    train_mask = all_masks[train_index]\n    val_img = all_imgs[test_index]\n    val_mask = all_masks[test_index]\n    dataset_train = PennFudanDataset(train_img, train_mask, get_transform(train=True))\n    dataset_val = PennFudanDataset(val_img, val_mask, get_transform(train=False))\n    train_dl = torch.utils.data.DataLoader(\n        dataset_train, batch_size=4, shuffle=True, num_workers=os.cpu_count(), pin_memory=True, drop_last=True, collate_fn=utils.collate_fn)\n    val_dl = torch.utils.data.DataLoader(\n        dataset_val, batch_size=1, shuffle=False, num_workers=os.cpu_count(), pin_memory=True,collate_fn=utils.collate_fn)\n    \n    model = get_model_instance_segmentation(num_classes=2)\n    print(model)\n    model.to(device)\n    params = [p for p in model.parameters() if p.requires_grad]\n    optimizer = torch.optim.Adam(params, lr=0.0002, weight_decay=1e-6)\n    scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.9)\n    \n    for epoch in range(EPOCHS):\n        train_one_epoch(model, optimizer, train_dl, device, epoch, print_freq=50)\n        evaluate(model, val_dl, device=device)\n        scheduler.step()\n        model_path = f'fold_{i}_epoch{epoch}.pth'\n        torch.save(model.state_dict(), model_path)\n        ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}