{"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":"!mkdir -p /root/.cache/torch/hub/\n!mkdir -p /root/.cache/torch/hub/checkpoints\n!cp /kaggle/input/detrssoc/resnet50-0676ba61.pth /root/.cache/torch/hub/checkpoints/\n!cp -r /kaggle/input/detrweight/resources/detr /root/.cache/torch/hub/\n!mv /root/.cache/torch/hub/detr /root/.cache/torch/hub/facebookresearch_detr_main","metadata":{"execution":{"iopub.status.busy":"2023-06-29T12:39:46.823660Z","iopub.execute_input":"2023-06-29T12:39:46.824252Z","iopub.status.idle":"2023-06-29T12:39:53.819297Z","shell.execute_reply.started":"2023-06-29T12:39:46.824182Z","shell.execute_reply":"2023-06-29T12:39:53.817836Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport random\nimport numpy as np\nimport torch\n\n# call before train\nSEED = 42\ndef seed_everything(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True\n\n# dataset config\nDATA_DIR = '/kaggle/input/global-wheat-detection'\nTRAIN_ROOT_PATH = DATA_DIR + 'train'\n\n# train cache\nCACHE_DIR = '/kaggle/working/'\n\ndef format_prediction_string(boxes, scores):\n    pred_strings = []\n    for j in zip(scores, boxes):\n        pred_strings.append(\"{0:.4f} {1} {2} {3} {4}\".format(j[0], j[1][0], j[1][1], j[1][2], j[1][3]))\n    return \" \".join(pred_strings)\n","metadata":{"execution":{"iopub.status.busy":"2023-06-29T12:39:53.825430Z","iopub.execute_input":"2023-06-29T12:39:53.828330Z","iopub.status.idle":"2023-06-29T12:39:56.947355Z","shell.execute_reply.started":"2023-06-29T12:39:53.828287Z","shell.execute_reply":"2023-06-29T12:39:56.946419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport numpy as np \nimport pandas as pd \nfrom datetime import datetime\nimport time\nimport random\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset,DataLoader\nfrom torch.utils.data.sampler import SequentialSampler, RandomSampler\nfrom sklearn.model_selection import StratifiedKFold\nimport cv2\nimport sys\nsys.path.append('/kaggle/input/detrssoc/resources')\nsys.path.append('/kaggle/input/detrssoc/resources/detr')\n\n# to solve import error\nimport torchvision\n_version = torchvision.__version__\ntorchvision.__version__ = '0.8'\nfrom detr.models.matcher import HungarianMatcher\nfrom detr.models.detr import SetCriterion\n# to solve import error\ntorchvision.__version__ = _version\n\nimport albumentations as A\nimport matplotlib.pyplot as plt\nfrom albumentations.pytorch.transforms import ToTensorV2\nfrom glob import glob\n\ndef normalize_bbox(bbox, rows, cols):\n    \"\"\"Normalize coordinates of a bounding box. Divide x-coordinates by image width and y-coordinates\n    by image height.\n\n    Args:\n        bbox (tuple): Denormalized bounding box `(x_min, y_min, x_max, y_max)`.\n        rows (int): Image height.\n        cols (int): Image width.\n\n    Returns:\n        tuple: Normalized bounding box `(x_min, y_min, x_max, y_max)`.\n\n    Raises:\n        ValueError: If rows or cols is less or equal zero\n\n    \"\"\"\n    (x_min, y_min, x_max, y_max), tail = bbox[:4], tuple(bbox[4:])\n\n    if rows <= 0:\n        raise ValueError(\"Argument rows must be positive integer\")\n    if cols <= 0:\n        raise ValueError(\"Argument cols must be positive integer\")\n\n    x_min, x_max = x_min / cols, x_max / cols\n    y_min, y_max = y_min / rows, y_max / rows\n\n    return (x_min, y_min, x_max, y_max) + tail\n\n\ndef denormalize_bbox(bbox, rows, cols):\n    \"\"\"Denormalize coordinates of a bounding box. Multiply x-coordinates by image width and y-coordinates\n    by image height. This is an inverse operation for :func:`~albumentations.augmentations.bbox.normalize_bbox`.\n\n    Args:\n        bbox (tuple): Normalized bounding box `(x_min, y_min, x_max, y_max)`.\n        rows (int): Image height.\n        cols (int): Image width.\n\n    Returns:\n        tuple: Denormalized bounding box `(x_min, y_min, x_max, y_max)`.\n\n    Raises:\n        ValueError: If rows or cols is less or equal zero\n\n    \"\"\"\n    (x_min, y_min, x_max, y_max), tail = bbox[:4], tuple(bbox[4:])\n\n    if rows <= 0:\n        raise ValueError(\"Argument rows must be positive integer\")\n    if cols <= 0:\n        raise ValueError(\"Argument cols must be positive integer\")\n\n    x_min, x_max = x_min * cols, x_max * cols\n    y_min, y_max = y_min * rows, y_max * rows\n\n    return (x_min, y_min, x_max, y_max) + tail\n\n\ndef normalize_bboxes(bboxes, rows, cols):\n    \"\"\"Normalize a list of bounding boxes.\n\n    Args:\n        bboxes (List[tuple]): Denormalized bounding boxes `[(x_min, y_min, x_max, y_max)]`.\n        rows (int): Image height.\n        cols (int): Image width.\n\n    Returns:\n        List[tuple]: Normalized bounding boxes `[(x_min, y_min, x_max, y_max)]`.\n\n    \"\"\"\n    return [normalize_bbox(bbox, rows, cols) for bbox in bboxes]\n\n\ndef denormalize_bboxes(bboxes, rows, cols):\n    \"\"\"Denormalize a list of bounding boxes.\n\n    Args:\n        bboxes (List[tuple]): Normalized bounding boxes `[(x_min, y_min, x_max, y_max)]`.\n        rows (int): Image height.\n        cols (int): Image width.\n\n    Returns:\n        List[tuple]: Denormalized bounding boxes `[(x_min, y_min, x_max, y_max)]`.\n\n    \"\"\"\n    return [denormalize_bbox(bbox, rows, cols) for bbox in bboxes]\n\n# model definition\nclass DETRModel(nn.Module):\n    def __init__(self,num_classes,num_queries, pretrained=False):\n        super(DETRModel,self).__init__()\n        self.num_classes = num_classes\n        self.num_queries = num_queries\n        \n        self.model = torch.hub.load('facebookresearch/detr', 'detr_resnet50', pretrained=pretrained)\n        self.in_features = self.model.class_embed.in_features\n        \n        self.model.class_embed = nn.Linear(in_features=self.in_features,out_features=self.num_classes)\n        self.model.num_queries = self.num_queries\n        \n    def forward(self,images):\n        return self.model(images)\n\nclass TrainGlobalConfig:\n    folder = CACHE_DIR + '/detr'\n\n    num_workers = 2\n    batch_size = 8\n    n_epochs = 50\n    lr = 2e-5\n    num_classes = 2\n    num_queries = 100\n    null_class_coef = 0.5\n\n    \n    verbose = True\n    verbose_step = 1\n    step_scheduler = False  # do scheduler.step after optimizer.step\n    validation_scheduler = True  # do scheduler.step after validation stage loss\n\n    SchedulerClass = torch.optim.lr_scheduler.ReduceLROnPlateau\n    scheduler_params = dict(\n        mode='min',\n        factor=0.5,\n        patience=1,\n        verbose=False,\n        threshold=0.0001,\n        threshold_mode='abs',\n        cooldown=0,\n        min_lr=1e-8,\n        eps=1e-08\n    )\n\ndef detect_detr(testLoader, path2weight):\n    device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n\n    net = DETRModel(num_classes=TrainGlobalConfig.num_classes,num_queries=TrainGlobalConfig.num_queries)\n    net.load_state_dict(torch.load(path2weight)['model_state_dict'])\n    net.to(device)\n    net.eval()\n\n    results = []\n\n    for images, image_ids in testLoader:\n        inputs = list(img.to(device) for img in images)\n        outputs = net(inputs)\n        outputs = [{k: v.to(device) for k, v in outputs.items()}]\n        for i, image in enumerate(images):\n            h = 1024\n            w = 1024\n            boxes = outputs[0]['pred_boxes'][0].detach().cpu().numpy()\n            boxes = np.stack([np.array(box).astype(np.int32) for box in denormalize_bboxes(boxes,h,w)])\n            scores = outputs[0]['pred_logits'][0].softmax(1).detach().cpu().numpy()[:,0]\n            mask = scores > 0.9\n            scores = scores[mask]\n            boxes = boxes[mask]\n            image_id = image_ids[i]\n            result = {\n                'image_id': image_id,\n                'PredictionString': format_prediction_string(boxes, scores)\n            }\n            results.append(result)\n    \n    return results","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-06-29T12:39:56.948999Z","iopub.execute_input":"2023-06-29T12:39:56.949663Z","iopub.status.idle":"2023-06-29T12:39:58.962017Z","shell.execute_reply.started":"2023-06-29T12:39:56.949627Z","shell.execute_reply":"2023-06-29T12:39:58.961009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATA_ROOT_PATH = '../input/global-wheat-detection/test'\n\ndef get_valid_transforms():\n    return A.Compose([A.Resize(height=512, width=512, p=1.0),\n                      ToTensorV2(p=1.0)], \n                      p=1.0)\n\nclass DatasetRetriever(Dataset):\n    def __init__(self, image_ids, transforms=None):\n        super().__init__()\n        self.image_ids = image_ids\n        self.transforms = transforms\n\n    def __getitem__(self, index: int):\n        image_id = self.image_ids[index]\n        image = cv2.imread(f'{DATA_ROOT_PATH}/{image_id}.jpg', cv2.IMREAD_COLOR)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n        image /= 255.0\n        if self.transforms:\n            sample = {\n                'image': image\n            }\n            sample = self.transforms(**sample)\n            image = sample['image']\n        return image, image_id\n\n    def __len__(self) -> int:\n        return self.image_ids.shape[0]\n\ndataset = DatasetRetriever(\n    image_ids=np.array([path.split('/')[-1][:-4] for path in glob(f'{DATA_ROOT_PATH}/*.jpg')]),\n    transforms=get_valid_transforms()\n)\n\ndef collate_fn(batch):\n    return tuple(zip(*batch))\n\ndata_loader = DataLoader(\n    dataset,\n    batch_size=2,\n    shuffle=False,\n    num_workers=4,\n    drop_last=False,\n    collate_fn=collate_fn\n)","metadata":{"execution":{"iopub.status.busy":"2023-06-29T12:39:58.964755Z","iopub.execute_input":"2023-06-29T12:39:58.965062Z","iopub.status.idle":"2023-06-29T12:39:58.989312Z","shell.execute_reply.started":"2023-06-29T12:39:58.965035Z","shell.execute_reply":"2023-06-29T12:39:58.988325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"results = detect_detr(data_loader, path2weight = '/kaggle/input/detrweight/kaggle/working/detr/best-checkpoint-047epoch.bin')","metadata":{"execution":{"iopub.status.busy":"2023-06-29T12:39:58.990834Z","iopub.execute_input":"2023-06-29T12:39:58.991678Z","iopub.status.idle":"2023-06-29T12:40:32.067634Z","shell.execute_reply.started":"2023-06-29T12:39:58.991653Z","shell.execute_reply":"2023-06-29T12:40:32.063378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\ntest_df.to_csv('submission.csv', index=False)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-29T12:40:32.072277Z","iopub.execute_input":"2023-06-29T12:40:32.073697Z","iopub.status.idle":"2023-06-29T12:40:32.128471Z","shell.execute_reply.started":"2023-06-29T12:40:32.073622Z","shell.execute_reply":"2023-06-29T12:40:32.125665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import matplotlib.pyplot as plt\n# path2weight = '/kaggle/input/detrweight/kaggle/working/detr/best-checkpoint-049epoch.bin'\n# device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n\n# net = DETRModel(num_classes=TrainGlobalConfig.num_classes,num_queries=TrainGlobalConfig.num_queries)\n# net.load_state_dict(torch.load(path2weight)['model_state_dict'])\n# net.to(device)\n# net.eval()\n# images, image_ids = next(iter(data_loader))\n# _,h,w = images[0].shape # for de normalizing images\n\n# images = list(img.to(device) for img in images)\n\n# sample = images[0].permute(1,2,0).cpu().numpy()\n\n# outputs = net(images)\n# outputs = [{k: v.to(device) for k, v in outputs.items()}]\n\n# fig, ax = plt.subplots(1, 1, figsize=(16, 8))\n\n\n\n# oboxes = outputs[0]['pred_boxes'][0].detach().cpu().numpy()\n# oboxes = [np.array(box).astype(np.int32) for box in denormalize_bboxes(oboxes,h,w)]\n# prob   = outputs[0]['pred_logits'][0].softmax(1).detach().cpu().numpy()[:,0]\n\n# for box,p in zip(oboxes,prob):\n#     if p > 0.05:\n#         color = (0,0,255)\n#         cv2.rectangle(sample,\n#               (box[0], box[1]),\n#               (box[2]+box[0], box[3]+box[1]),\n#               color, 2)\n\n# ax.set_axis_off()\n# ax.imshow(sample)","metadata":{"execution":{"iopub.status.busy":"2023-06-29T12:40:32.134406Z","iopub.execute_input":"2023-06-29T12:40:32.134765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model = net\n\n# num_params = sum(p.numel() for p in model.parameters())\n\n# print(f\"Number of parameters: {num_params/(1e6)}\")","metadata":{"execution":{"iopub.status.busy":"2023-06-29T12:41:38.941670Z","iopub.execute_input":"2023-06-29T12:41:38.942438Z","iopub.status.idle":"2023-06-29T12:41:38.949777Z","shell.execute_reply.started":"2023-06-29T12:41:38.942402Z","shell.execute_reply":"2023-06-29T12:41:38.948749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}