{"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":"%%capture\n!pip install pycocotools\n!pip install -U albumentations\n!git clone https://github.com/pytorch/vision.git\n!cd vision\n!git checkout v0.3.0\n\n!cp vision/references/detection/utils.py ./coco_utils.py","metadata":{"execution":{"iopub.status.busy":"2021-08-06T22:21:10.945659Z","iopub.execute_input":"2021-08-06T22:21:10.946092Z","iopub.status.idle":"2021-08-06T22:21:49.281760Z","shell.execute_reply.started":"2021-08-06T22:21:10.946009Z","shell.execute_reply":"2021-08-06T22:21:49.280457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os, sys\nimport zipfile\nimport json\nimport math\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nimport albumentations as A\nfrom pycocotools.coco import COCO\n\nimport torch\nimport torchvision\nimport coco_utils as utils\n\nroot = \"/kaggle/input/cowboyoutfits\"\ncats = ['belt', 'sunglasses', 'boot', 'cowboy_hat', 'jacket']\ncat2num = {i: v for v, i in enumerate([87, 1034, 131, 318, 588], 1)}\nnum2cat = {i: v for v, i in cat2num.items()}\ndevice = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\nBATCH_SIZE = 2\ndevice, cat2num","metadata":{"execution":{"iopub.status.busy":"2021-08-06T22:22:08.575649Z","iopub.execute_input":"2021-08-06T22:22:08.576268Z","iopub.status.idle":"2021-08-06T22:22:12.019148Z","shell.execute_reply.started":"2021-08-06T22:22:08.576233Z","shell.execute_reply":"2021-08-06T22:22:12.018171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CoCoDate(torchvision.datasets.CocoDetection):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n    \n    def _load_image(self, id: int) -> Image.Image:\n        path = self.coco.loadImgs(id)[0][\"file_name\"]\n        return Image.open(os.path.join(self.root, path)).convert(\"RGB\")\n\n    def _load_target(self, id):\n        return self.coco.loadAnns(self.coco.getAnnIds(id))\n    \n    def get_labels(self):\n        return list(cat2num.keys())\n    \n    def __getitem__(self, index: int):\n        id = self.ids[index]\n        img = self._load_image(id)\n        annos = self._load_target(id)\n        img_w, img_h = img.size\n        \n        boxes = []\n        labels = []\n        \n        for anno in annos:\n            boxes.append(anno[\"bbox\"])\n            cat_id = anno['category_id']\n            label = cat2num[cat_id]\n            labels.append(label)\n            \n        img_dict = transform(\n            image=np.array(img), \n            bboxes=boxes, \n            category_ids=labels\n        )\n        \n        image = torchvision.transforms.ToTensor()(img_dict[\"image\"])\n        if img_dict[\"bboxes\"] and img_dict[\"bboxes\"][0]:\n            bbox = torch.as_tensor(img_dict[\"bboxes\"], dtype=torch.float32)\n            bbox[:, 2:] += bbox[:, :2]\n            target = {\n                \"boxes\": bbox,\n                \"labels\": torch.as_tensor(img_dict[\"category_ids\"], dtype=torch.int64)\n            }\n        else:\n            target = None\n\n        return image, target","metadata":{"execution":{"iopub.status.busy":"2021-08-06T21:59:24.122713Z","iopub.execute_input":"2021-08-06T21:59:24.123356Z","iopub.status.idle":"2021-08-06T21:59:24.134994Z","shell.execute_reply.started":"2021-08-06T21:59:24.123294Z","shell.execute_reply":"2021-08-06T21:59:24.134105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_data_weights():\n    coco = COCO(os.path.join(root, \"train.json\"))\n\n    class_dict = {}\n    for cat in cats:\n        catId = coco.getCatIds(catNms=cat)\n        img_count = len(coco.getImgIds(catIds=catId))\n        ann_count = len(coco.getAnnIds(catIds=catId))\n        class_dict[cat] = (img_count + ann_count) / (img_count * ann_count) * 100\n\n    ids = list(sorted(coco.imgs.keys()))\n    weights = [0] * len(ids)\n    for i, idx in enumerate(ids):\n        annos = coco.loadAnns(coco.getAnnIds(idx))\n        for anno in annos:\n             weights[i] += class_dict[cats[\n                 cat2num[anno['category_id']] - 1\n             ]]\n    \n    return weights","metadata":{"execution":{"iopub.status.busy":"2021-08-06T21:59:24.136499Z","iopub.execute_input":"2021-08-06T21:59:24.136846Z","iopub.status.idle":"2021-08-06T21:59:24.149411Z","shell.execute_reply.started":"2021-08-06T21:59:24.136807Z","shell.execute_reply":"2021-08-06T21:59:24.148501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transform = A.Compose(\n    [A.HorizontalFlip(),\n     A.RandomResizedCrop(800, 1300, (.5, 1.), p=.5),\n     A.Rotate(15, p=.4),\n     A.Rotate(-15, p=.4),\n     A.RandomBrightnessContrast(p=.5)\n    ],\n    bbox_params=A.BboxParams(\"coco\", [\"category_ids\"])\n)\n\ntrain_dataset = CoCoDate(\n    os.path.join(root, \"images\"), os.path.join(root, \"train.json\")\n)\ntrain_iter = torch.utils.data.DataLoader(\n    train_dataset, batch_size=3, num_workers=4,\n    collate_fn=utils.collate_fn,\n    sampler=torch.utils.data.WeightedRandomSampler(\n        get_data_weights(), 3000, replacement=True\n    )\n)","metadata":{"execution":{"iopub.status.busy":"2021-08-06T21:59:24.150702Z","iopub.execute_input":"2021-08-06T21:59:24.151115Z","iopub.status.idle":"2021-08-06T21:59:24.411528Z","shell.execute_reply.started":"2021-08-06T21:59:24.151075Z","shell.execute_reply":"2021-08-06T21:59:24.410719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)\nin_features = model.roi_heads.box_predictor.cls_score.in_features\nmodel.roi_heads.box_predictor = torchvision.models.detection.faster_rcnn\\\n    .FastRCNNPredictor(in_features, len(cats) + 1)\nmodel.to(device);\nmodel.load_state_dict(torch.load(\"../input/weights/faster-rcnn.pt\"))","metadata":{"execution":{"iopub.status.busy":"2021-08-06T21:59:24.414564Z","iopub.execute_input":"2021-08-06T21:59:24.414825Z","iopub.status.idle":"2021-08-06T21:59:35.123881Z","shell.execute_reply.started":"2021-08-06T21:59:24.414798Z","shell.execute_reply":"2021-08-06T21:59:35.122984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_one_epoch(model, optimizer, data_loader, device, epoch, print_freq):\n    model.train()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value:.6f}'))\n    header = 'Epoch: [{}]'.format(epoch)\n\n    lr_scheduler = None\n    if epoch == 0:\n        warmup_factor = 1. / 1000\n        warmup_iters = min(1000, len(data_loader) - 1)\n\n        lr_scheduler = utils.warmup_lr_scheduler(optimizer, warmup_iters, warmup_factor)\n\n    for data_images, data_targets in metric_logger.log_every(data_loader, print_freq, header):\n        try:\n            images = list(image.to(device) for image in data_images)\n            targets = [{k: v.to(device) for k, v in t.items()} for t in data_targets]\n        except AttributeError:\n            continue\n\n        loss_dict = model(images, targets)\n\n        losses = sum(loss for loss in loss_dict.values())\n\n        # reduce losses over all GPUs for logging purposes\n        loss_dict_reduced = utils.reduce_dict(loss_dict)\n        losses_reduced = sum(loss for loss in loss_dict_reduced.values())\n\n        loss_value = losses_reduced.item()\n\n        if not math.isfinite(loss_value):\n            print(\"Loss is {}, stopping training\".format(loss_value))\n            print(loss_dict_reduced)\n            sys.exit(1)\n\n        optimizer.zero_grad()\n        losses.backward()\n        optimizer.step()\n\n        if lr_scheduler is not None:\n            lr_scheduler.step()\n\n        metric_logger.update(loss=losses_reduced, **loss_dict_reduced)\n        metric_logger.update(lr=optimizer.param_groups[0][\"lr\"])\n\n    return metric_logger","metadata":{"execution":{"iopub.status.busy":"2021-08-06T13:52:16.220136Z","iopub.execute_input":"2021-08-06T13:52:16.220699Z","iopub.status.idle":"2021-08-06T13:52:16.234168Z","shell.execute_reply.started":"2021-08-06T13:52:16.220647Z","shell.execute_reply":"2021-08-06T13:52:16.233257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_model(epochs=18):\n    opt = torch.optim.Adam(\n        [p for p in model.parameters() if p.requires_grad],\n        lr=1e-4\n    )\n    lr_scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(opt, epochs)\n    \n    for epoch in range(epochs):\n        train_one_epoch(model, opt, train_iter, device, epoch, 10000)\n        lr_scheduler.step()\n        \n    torch.save(model.state_dict(), \"faster-rcnn.pt\")","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-08-06T13:52:16.630707Z","iopub.execute_input":"2021-08-06T13:52:16.631289Z","iopub.status.idle":"2021-08-06T13:52:16.638186Z","shell.execute_reply.started":"2021-08-06T13:52:16.631241Z","shell.execute_reply":"2021-08-06T13:52:16.636821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_model()","metadata":{"execution":{"iopub.status.busy":"2021-08-06T13:52:16.977067Z","iopub.execute_input":"2021-08-06T13:52:16.977497Z","iopub.status.idle":"2021-08-06T13:53:28.252913Z","shell.execute_reply.started":"2021-08-06T13:52:16.977464Z","shell.execute_reply":"2021-08-06T13:53:28.251446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class JeansDatasetTest(torch.utils.data.Dataset):\n    def __init__(self, data):\n        self.data = data\n    \n    def __len__(self):\n        return len(self.data)\n    \n    def __getitem__(self, idx):\n        row = self.data.loc[idx]\n        \n        image = Image.open(row[\"file_name\"]).convert(\"RGB\")\n        image = torchvision.transforms.ToTensor()(image)\n        \n        return image.to(device), int(row[\"id\"])","metadata":{"execution":{"iopub.status.busy":"2021-08-06T21:59:35.125461Z","iopub.execute_input":"2021-08-06T21:59:35.125866Z","iopub.status.idle":"2021-08-06T21:59:35.135021Z","shell.execute_reply.started":"2021-08-06T21:59:35.125825Z","shell.execute_reply":"2021-08-06T21:59:35.131571Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def submisstion(file_name=\"vaild.csv\"):\n    df = pd.read_csv(os.path.join(root, file_name))\n    df[\"file_name\"] = df[\"file_name\"].apply(lambda x: os.path.join(root, \"images\", x))\n    data = JeansDatasetTest(df)\n    data_load = torch.utils.data.DataLoader(\n        data, batch_size=1, collate_fn=utils.collate_fn\n    )\n    model.eval()\n    resultes = []\n    with torch.no_grad():\n        for x, y in data_load:\n            output = model(x)\n            for num, item in enumerate(output):\n                for l in range(item[\"scores\"].shape[0]):\n                    bbox = item[\"boxes\"][l]\n                    bbox[2:] -= bbox[:2]\n                    pred = {\n                        \"image_id\": y[num],\n                        \"category_id\": num2cat[item[\"labels\"][l].item()],\n                        \"bbox\": bbox.tolist(),\n                        \"score\": item[\"scores\"][l].item()\n                    }\n                    resultes.append(pred)\n    return resultes","metadata":{"execution":{"iopub.status.busy":"2021-08-06T21:59:35.137434Z","iopub.execute_input":"2021-08-06T21:59:35.137857Z","iopub.status.idle":"2021-08-06T21:59:35.466983Z","shell.execute_reply.started":"2021-08-06T21:59:35.137815Z","shell.execute_reply":"2021-08-06T21:59:35.46586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"res = submisstion(\"test.csv\")","metadata":{"execution":{"iopub.status.busy":"2021-08-06T21:59:35.468904Z","iopub.execute_input":"2021-08-06T21:59:35.469485Z","iopub.status.idle":"2021-08-06T22:01:27.387751Z","shell.execute_reply.started":"2021-08-06T21:59:35.469439Z","shell.execute_reply":"2021-08-06T22:01:27.386793Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_name = '/kaggle/working/answer.json'\nwith open(submission_name, 'w') as f:\n    json.dump(res, f)\nzf = zipfile.ZipFile('/kaggle/working/sample_answer.zip', 'w')\nzf.write(submission_name, 'answer.json')\nzf.close()","metadata":{"execution":{"iopub.status.busy":"2021-08-06T22:22:20.065846Z","iopub.execute_input":"2021-08-06T22:22:20.066234Z","iopub.status.idle":"2021-08-06T22:22:20.073182Z","shell.execute_reply.started":"2021-08-06T22:22:20.066197Z","shell.execute_reply":"2021-08-06T22:22:20.072389Z"},"trusted":true},"execution_count":null,"outputs":[]}]}