{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":114094,"databundleVersionId":13610510,"sourceType":"competition"}],"dockerImageVersionId":31193,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"pip install effdet","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:16:14.361786Z","iopub.execute_input":"2025-11-09T18:16:14.362587Z","iopub.status.idle":"2025-11-09T18:17:30.39448Z","shell.execute_reply.started":"2025-11-09T18:16:14.362544Z","shell.execute_reply":"2025-11-09T18:17:30.39336Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport torch\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom torch.utils.data import Dataset, DataLoader\nfrom effdet import EfficientDet, get_efficientdet_config, DetBenchTrain\nfrom effdet.efficientdet import HeadNet\nfrom torch.optim import AdamW","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:19:45.814403Z","iopub.execute_input":"2025-11-09T18:19:45.815125Z","iopub.status.idle":"2025-11-09T18:19:50.451836Z","shell.execute_reply.started":"2025-11-09T18:19:45.815098Z","shell.execute_reply":"2025-11-09T18:19:50.451245Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def reverseStandardise(x, xmax):\n    return float(xmax * x)\n\n\ndef boxConvert(coors):\n    cx, cy, w, h = coors\n    cx, cy, w, h = cx, cy, w, h\n    x1 = cx - w / 2\n    y1 = cy - h / 2\n    x2 = cx + w / 2\n    y2 = cy + h / 2\n    return [x1, y1, x2, y2]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:19:54.704594Z","iopub.execute_input":"2025-11-09T18:19:54.705171Z","iopub.status.idle":"2025-11-09T18:19:54.709555Z","shell.execute_reply.started":"2025-11-09T18:19:54.705149Z","shell.execute_reply":"2025-11-09T18:19:54.708749Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class GroceryDataset(Dataset):\n    def __init__(self, root, transform=None):\n        self.root = root\n        self.transform = transform\n        self.imgsPath = sorted(os.listdir(os.path.join(root, \"images\")))\n        self.labelsPath = sorted(os.listdir(os.path.join(root, \"labels\")))\n\n    def __len__(self):\n        return len(self.imgsPath)\n\n    def boxConvert(self, coors, img_w, img_h):\n        cx, cy, w, h = coors\n        cx, cy, w, h = cx * img_w, cy * img_h, w * img_w, h * img_h\n        x1 = cx - w / 2\n        y1 = cy - h / 2\n        x2 = cx + w / 2\n        y2 = cy + h / 2\n        return [x1, y1, x2, y2]\n\n    def splitter(self, coor, img_w, img_h):\n        coor = list(map(float, coor))\n        coors, targets, fcoor = [], [], []\n        c = 0\n        for i in coor:\n            if (c == 0) or (c % 5 == 0):\n                targets.append(int(i))\n            else:\n                coors.append(i)\n            c += 1\n            if c % 5 == 0:\n                fcoor.append(self.boxConvert(coors, img_w, img_h))\n                coors = []\n        return targets, fcoor\n\n    def __getitem__(self, idx):\n        imgPath = os.path.join(self.root, \"images\", self.imgsPath[idx])\n        labelPath = os.path.join(self.root, \"labels\", self.labelsPath[idx])\n\n        img = cv2.imread(imgPath)\n        if img is None:\n            raise FileNotFoundError(imgPath)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        img_h, img_w = img.shape[:2]\n\n        lal = open(labelPath).read().split()\n        labels, coors = self.splitter(lal, img_w, img_h)\n\n        # Albumentations transform\n        tt = self.transform(image=img, bboxes=coors, labels=labels)\n        target = {\n            \"bbox\": torch.tensor(tt[\"bboxes\"], dtype=torch.float32),\n            \"cls\": torch.tensor(tt[\"labels\"], dtype=torch.int64)\n        }\n        return tt[\"image\"], target\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:19:54.914587Z","iopub.execute_input":"2025-11-09T18:19:54.914833Z","iopub.status.idle":"2025-11-09T18:19:54.924096Z","shell.execute_reply.started":"2025-11-09T18:19:54.914807Z","shell.execute_reply":"2025-11-09T18:19:54.923416Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class GroceryDatasetEval(Dataset):\n    def __init__(self, root, transform=None):\n        self.root = root\n        self.transform = transform\n        self.imgsPath = sorted(os.listdir(os.path.join(root, \"images\")))\n        self.labelsPath = sorted(os.listdir(os.path.join(root, \"labels\")))\n    def __len__(self):\n        return len(self.imgsPath)\n    def boxConvert(self, coors, img_w, img_h):\n        cx, cy, w, h = coors\n        cx, cy, w, h = cx *img_w, cy * img_h, w * img_w, h * img_h\n        x1 = cx - w / 2\n        y1 = cy - h / 2\n        x2 = cx + w / 2\n        y2 = cy + h / 2\n        return [x1, y1, x2, y2]\n\n    \n    \n    def splitter(self, coor, img_w, img_h):\n        coor = list(map(float, coor))\n        coors, targets, fcoor = [], [], []\n        c = 0\n        for i in coor:\n            if (c == 0) or (c % 5 == 0):\n                targets.append(int(i))\n            else:\n                coors.append(i)\n            c += 1\n            if c % 5 == 0:\n                fcoor.append(self.boxConvert(coors, img_w, img_h))\n                coors = []\n        return targets, fcoor\n    def __getitem__(self, idx):\n        imgPath = os.path.join(self.root, \"images\", self.imgsPath[idx])\n        labelPath = os.path.join(self.root, \"labels\", self.labelsPath[idx])\n\n        img = cv2.imread(imgPath)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        img_h, img_w = img.shape[:2]\n\n        lal = open(labelPath).read().split()\n        labels, coors = self.splitter(lal, img_w, img_h)\n\n        tt = self.transform(image=img, bboxes=coors, labels=labels)\n        target = {\n            \"bbox\": torch.tensor(tt[\"bboxes\"], dtype=torch.float32),\n            \"cls\": torch.tensor(tt[\"labels\"], dtype=torch.int64)\n        }\n        return tt[\"image\"], target\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:19:55.150588Z","iopub.execute_input":"2025-11-09T18:19:55.150801Z","iopub.status.idle":"2025-11-09T18:19:55.159947Z","shell.execute_reply.started":"2025-11-09T18:19:55.150785Z","shell.execute_reply":"2025-11-09T18:19:55.159251Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transform = A.Compose(\n    [A.Resize(height=640, width=640), A.Normalize(mean=(0.485, 0.456, 0.406),std=(0.229, 0.224, 0.225)), ToTensorV2()],\n    bbox_params=A.BboxParams(format=\"pascal_voc\", label_fields=[\"labels\"])\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:59:56.336146Z","iopub.execute_input":"2025-11-09T18:59:56.336801Z","iopub.status.idle":"2025-11-09T18:59:56.342755Z","shell.execute_reply.started":"2025-11-09T18:59:56.336772Z","shell.execute_reply":"2025-11-09T18:59:56.342034Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def collate_fn(batch):\n    imgs, targets = zip(*batch)\n    imgs = torch.stack(imgs)\n    return imgs, list(targets)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:59:57.473864Z","iopub.execute_input":"2025-11-09T18:59:57.47413Z","iopub.status.idle":"2025-11-09T18:59:57.478174Z","shell.execute_reply.started":"2025-11-09T18:59:57.474109Z","shell.execute_reply":"2025-11-09T18:59:57.477465Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dataset = GroceryDataset(\"/kaggle/input/grocery-items-multi-class-object-detection/train/train\", transform)\nevaldataset = GroceryDatasetEval(\"/kaggle/input/grocery-items-multi-class-object-detection/val/val\", transform)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:59:57.980998Z","iopub.execute_input":"2025-11-09T18:59:57.98134Z","iopub.status.idle":"2025-11-09T18:59:57.992072Z","shell.execute_reply.started":"2025-11-09T18:59:57.981319Z","shell.execute_reply":"2025-11-09T18:59:57.991319Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dataLoaderTrain = DataLoader(dataset, batch_size=5, collate_fn=collate_fn, shuffle=False)\ndataLoaderVal = DataLoader(evaldataset, batch_size=5, collate_fn=collate_fn, shuffle=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T19:15:13.296368Z","iopub.execute_input":"2025-11-09T19:15:13.296681Z","iopub.status.idle":"2025-11-09T19:15:13.300716Z","shell.execute_reply.started":"2025-11-09T19:15:13.296658Z","shell.execute_reply":"2025-11-09T19:15:13.300112Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"config = get_efficientdet_config('efficientdetv2_dt')\nconfig.num_classes = 3\nconfig.image_size = (640, 640)\nconfig.legacy_focal = True\n\nnet = EfficientDet(config, pretrained_backbone=True)\noptimizer = AdamW(net.parameters(), lr=1e-4)\nnet.class_net = HeadNet(config, num_outputs=config.num_classes)\nmodel = DetBenchTrain(net, config)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T19:15:19.737317Z","iopub.execute_input":"2025-11-09T19:15:19.737614Z","iopub.status.idle":"2025-11-09T19:15:20.261221Z","shell.execute_reply.started":"2025-11-09T19:15:19.737593Z","shell.execute_reply":"2025-11-09T19:15:20.260435Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"imgs, targets = next(iter(dataLoaderTrain))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T19:15:21.576333Z","iopub.execute_input":"2025-11-09T19:15:21.576804Z","iopub.status.idle":"2025-11-09T19:15:21.996247Z","shell.execute_reply.started":"2025-11-09T19:15:21.576779Z","shell.execute_reply":"2025-11-09T19:15:21.995433Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"targets","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T19:15:21.997382Z","iopub.execute_input":"2025-11-09T19:15:21.997605Z","iopub.status.idle":"2025-11-09T19:15:22.004447Z","shell.execute_reply.started":"2025-11-09T19:15:21.997589Z","shell.execute_reply":"2025-11-09T19:15:22.003805Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"targets[0][\"bbox\"].shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T19:00:11.51409Z","iopub.execute_input":"2025-11-09T19:00:11.514387Z","iopub.status.idle":"2025-11-09T19:00:11.519575Z","shell.execute_reply.started":"2025-11-09T19:00:11.514366Z","shell.execute_reply":"2025-11-09T19:00:11.518856Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"imgs[0].shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T19:00:11.690463Z","iopub.execute_input":"2025-11-09T19:00:11.690923Z","iopub.status.idle":"2025-11-09T19:00:11.695282Z","shell.execute_reply.started":"2025-11-09T19:00:11.690904Z","shell.execute_reply":"2025-11-09T19:00:11.694692Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img = imgs[0].numpy()\nimgr = img.transpose(1, 2, 0).copy()  \nfor box in targets[0][\"bbox\"].numpy():\n    x1, y1, x2, y2 = map(int, box)\n    cv2.rectangle(imgr, (x1, y1), (x2, y2), (255, 0, 0), 3)\nplt.imshow(imgr)\nplt.axis(\"off\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T19:00:14.340795Z","iopub.execute_input":"2025-11-09T19:00:14.341353Z","iopub.status.idle":"2025-11-09T19:00:14.480501Z","shell.execute_reply.started":"2025-11-09T19:00:14.341327Z","shell.execute_reply":"2025-11-09T19:00:14.479819Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for imgs, targets in dataLoaderTrain:\n    img = imgs[0].numpy()\n    imgr = img.transpose(1, 2, 0).copy()  \n    for box in targets[0][\"bbox\"].numpy():\n        x1, y1, x2, y2 = map(int, box)\n        cv2.rectangle(imgr, (x1, y1), (x2, y2), (255, 0, 0), 3)\n    plt.imshow(imgr)\n    plt.axis(\"off\")\n    plt.show()\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:18:42.888814Z","iopub.execute_input":"2025-11-09T18:18:42.889116Z","iopub.status.idle":"2025-11-09T18:18:48.208671Z","shell.execute_reply.started":"2025-11-09T18:18:42.889087Z","shell.execute_reply":"2025-11-09T18:18:48.207545Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\nimport cv2\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T19:00:20.360274Z","iopub.execute_input":"2025-11-09T19:00:20.360969Z","iopub.status.idle":"2025-11-09T19:00:20.364235Z","shell.execute_reply.started":"2025-11-09T19:00:20.360948Z","shell.execute_reply":"2025-11-09T19:00:20.363529Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel.to(device)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T19:03:11.015466Z","iopub.execute_input":"2025-11-09T19:03:11.016217Z","iopub.status.idle":"2025-11-09T19:03:11.081414Z","shell.execute_reply.started":"2025-11-09T19:03:11.016175Z","shell.execute_reply":"2025-11-09T19:03:11.08079Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"scaler=torch.cuda.amp.GradScaler()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:24:57.674135Z","iopub.execute_input":"2025-11-09T18:24:57.674461Z","iopub.status.idle":"2025-11-09T18:24:57.678804Z","shell.execute_reply.started":"2025-11-09T18:24:57.674439Z","shell.execute_reply":"2025-11-09T18:24:57.677961Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for epoch in range(num_epochs):\n    model.train()\n    runLoss = 0.0\n\n    # ---------- TRAINING ----------\n    for imgs, targets in tqdm(dataLoaderTrain, desc=f\"Epoch {epoch+1}/{num_epochs}\"):\n        img, target = imgs[0].to(device).float(), targets[0]\n        target[\"bbox\"] = [target[\"bbox\"].to(device)]\n        target[\"cls\"] = [target[\"cls\"].long().to(device)]\n\n        optimizer.zero_grad()\n        try:\n            # Forward + Backward\n            loss_dict = model(img.unsqueeze(0), target)\n            loss = loss_dict[\"loss\"]\n            loss.backward()\n            optimizer.step()\n            runLoss += loss.item()\n        except Exception as e:\n            pass\n            continue\n\n    torch.cuda.empty_cache()\n    print(f\"Epoch [{epoch+1}/{num_epochs}] - Train Loss: {runLoss / len(dataLoaderTrain):.4f}\")\n\n    # ---------- VALIDATION ----------\n    model.eval()\n    valLoss = 0.0\n    with torch.no_grad():\n        for imgs, targets in tqdm(dataLoaderVal, desc=f\"Validation {epoch+1}/{num_epochs}\"):\n            img, target = imgs[0].to(device).float(), targets[0]\n            target[\"bbox\"] = [target[\"bbox\"].to(device)]\n            target[\"cls\"] = [target[\"cls\"].long().to(device)]\n            target[\"img_scale\"] = torch.tensor([1.0], device=device)\n            target[\"img_size\"] = torch.tensor([[img.shape[-2], img.shape[-1]]], device=device)\n            loss_dict = model(img.unsqueeze(0), target)\n            valLoss += loss_dict[\"loss\"].item()\n\n            try:\n                loss_dict = model(img.unsqueeze(0), target)\n                valLoss += loss_dict[\"loss\"].item()\n            except Exception as e:\n                pass\n                continue\n\n    print(f\"Epoch [{epoch+1}/{num_epochs}] - Val Loss: {valLoss / len(dataLoaderVal):.4f}\")\n    torch.cuda.empty_cache()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T19:20:55.24576Z","iopub.execute_input":"2025-11-09T19:20:55.246473Z","iopub.status.idle":"2025-11-09T19:23:55.67671Z","shell.execute_reply.started":"2025-11-09T19:20:55.246447Z","shell.execute_reply":"2025-11-09T19:23:55.675627Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for epoch in range(num_epochs):\n  model.train()\n  runLoss=0.0\n  for imgs,targets in tqdm(dataLoaderTrain,desc=f\"Epoch {epoch+1}/{num_epochs}\"):\n    img, target = imgs[0].to(device).float(), targets[0]\n    target[\"bbox\"] = [target[\"bbox\"].to(device)]\n    target[\"cls\"] = [target[\"cls\"].long().to(device)]\n    optimizer.zero_grad()\n    try:\n      loss_dict = model(img.unsqueeze(0), target)\n      loss = loss_dict[\"loss\"]\n      loss.backward()\n      optimizer.step()\n      runLoss += loss.item()\n    except ValueError as er:\n        pass\n  torch.cuda.empty_cache()\n  print(f\"Epoch [{epoch+1}/{num_epochs}] - Loss: {runLoss/len(dataLoaderTrain):.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T19:06:50.741202Z","iopub.execute_input":"2025-11-09T19:06:50.741734Z","iopub.status.idle":"2025-11-09T19:06:55.944366Z","shell.execute_reply.started":"2025-11-09T19:06:50.741707Z","shell.execute_reply":"2025-11-09T19:06:55.943331Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from effdet import get_efficientdet_config, EfficientDet, DetBenchTrain, DetBenchPredict\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:44:47.320002Z","iopub.execute_input":"2025-11-09T18:44:47.320351Z","iopub.status.idle":"2025-11-09T18:44:47.32397Z","shell.execute_reply.started":"2025-11-09T18:44:47.320328Z","shell.execute_reply":"2025-11-09T18:44:47.323305Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_eval = DetBenchPredict(model.model, config).to(device)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-09T18:44:49.340266Z","iopub.execute_input":"2025-11-09T18:44:49.341074Z","iopub.status.idle":"2025-11-09T18:44:49.355031Z","shell.execute_reply.started":"2025-11-09T18:44:49.341051Z","shell.execute_reply":"2025-11-09T18:44:49.354055Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}