{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"data_dir=\"/kaggle/input/competitions/imaterialist-fashion-2019-FGVC6/train\"\ntrain_path=\"/kaggle/input/notebooks/mariemossamahussien/data-prep-and-remap/train.csv\"\ntest_path=\"/kaggle/input/notebooks/mariemossamahussien/data-prep-and-remap/test.csv\"\nval_path=\"/kaggle/input/notebooks/mariemossamahussien/data-prep-and-remap/val.csv\"\nclass_map_path=\"/kaggle/input/notebooks/mariemossamahussien/data-prep-and-remap/class_map.json\"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-08-09T18:58:52.852335Z","iopub.execute_input":"2026-08-09T18:58:52.852667Z","iopub.status.idle":"2026-08-09T18:58:52.858350Z","shell.execute_reply.started":"2026-08-09T18:58:52.852629Z","shell.execute_reply":"2026-08-09T18:58:52.857129Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!wget --quiet https://raw.githubusercontent.com/pytorch/vision/master/references/detection/engine.py\n!wget --quiet https://raw.githubusercontent.com/pytorch/vision/master/references/detection/utils.py\n!wget --quiet https://raw.githubusercontent.com/pytorch/vision/master/references/detection/transforms.py\n!wget --quiet https://raw.githubusercontent.com/pytorch/vision/master/references/detection/coco_eval.py\n!wget --quiet https://raw.githubusercontent.com/pytorch/vision/master/references/detection/coco_utils.py","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-01T14:01:41.401849Z","iopub.execute_input":"2026-08-01T14:01:41.402121Z","iopub.status.idle":"2026-08-01T14:01:42.787442Z","shell.execute_reply.started":"2026-08-01T14:01:41.402093Z","shell.execute_reply":"2026-08-01T14:01:42.786474Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":" %pip install -q pycocotools","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T18:58:52.859563Z","iopub.execute_input":"2026-08-09T18:58:52.860699Z","iopub.status.idle":"2026-08-09T18:58:57.312659Z","shell.execute_reply.started":"2026-08-09T18:58:52.860667Z","shell.execute_reply":"2026-08-09T18:58:57.311842Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport json\nimport cv2 \nfrom PIL import Image, ImageOps\nimport torch\nfrom torch.utils.data import DataLoader,Dataset\nimport torchvision \nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nfrom torchvision.models.detection.mask_rcnn import MaskRCNNPredictor\n# from torchvision.ops import nms\nimport os\nfrom engine import train_one_epoch, evaluate\nimport utils\nimport transforms as T\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\ndevice2 = torch.device(\"cuda:1\")\nprint(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T19:44:11.305369Z","iopub.execute_input":"2026-08-09T19:44:11.306014Z","iopub.status.idle":"2026-08-09T19:44:11.312659Z","shell.execute_reply.started":"2026-08-09T19:44:11.305985Z","shell.execute_reply":"2026-08-09T19:44:11.311658Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"os.makedirs(\"/kaggle/working/checkpoints\", exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T10:54:34.530764Z","iopub.execute_input":"2026-08-09T10:54:34.531032Z","iopub.status.idle":"2026-08-09T10:54:34.534926Z","shell.execute_reply.started":"2026-08-09T10:54:34.531011Z","shell.execute_reply":"2026-08-09T10:54:34.534166Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = pd.read_csv(train_path)\nval_df = pd.read_csv(val_path)\ntest_df = pd.read_csv(test_path)\n\nwith open(class_map_path) as f:\n    class_map = json.load(f)\n    \nid_to_class = class_map[\"id_to_class\"]\nprint(train_df.shape, val_df.shape, test_df.shape)\nprint(class_map[\"id_to_class\"])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T18:58:57.322315Z","iopub.execute_input":"2026-08-09T18:58:57.322678Z","iopub.status.idle":"2026-08-09T18:59:22.756026Z","shell.execute_reply.started":"2026-08-09T18:58:57.322654Z","shell.execute_reply":"2026-08-09T18:59:22.755304Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.columns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T11:06:21.851905Z","iopub.execute_input":"2026-08-09T11:06:21.852401Z","iopub.status.idle":"2026-08-09T11:06:21.859951Z","shell.execute_reply.started":"2026-08-09T11:06:21.852374Z","shell.execute_reply":"2026-08-09T11:06:21.859239Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Helpers","metadata":{}},{"cell_type":"code","source":"def rle_decode(rle_string, height, width):\n    nums = rle_string.split()\n    nums = [int(n) for n in nums]\n    starts = nums[0::2]   \n    lengths = nums[1::2]  \n    starts = np.array(starts) - 1\n    ends = starts + np.array(lengths)\n    mask = np.zeros(height * width, dtype=np.uint8)\n    for s, e in zip(starts, ends):\n        mask[s:e] = 1\n    mask = mask.reshape((height, width), order='F')\n\n    return mask","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T18:59:22.758454Z","iopub.execute_input":"2026-08-09T18:59:22.758863Z","iopub.status.idle":"2026-08-09T18:59:22.765558Z","shell.execute_reply.started":"2026-08-09T18:59:22.758837Z","shell.execute_reply":"2026-08-09T18:59:22.764872Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def build_maskrcnn_target(image_id, df):\n    rows = df[df['ImageId'] == image_id]\n    height = rows.iloc[0]['Height']\n    width = rows.iloc[0]['Width']\n\n    masks = []\n    boxes = []\n    labels = []\n\n    for _, row in rows.iterrows():\n        # decode this one object's mask (you already have this function)\n        obj_mask = rle_decode(row['EncodedPixels'], height, width)\n        masks.append(obj_mask)\n\n        # find the bounding box from the mask itself:\n        ys, xs = np.where(obj_mask == 1)\n        boxes.append([xs.min(), ys.min(), xs.max(), ys.max()])\n\n        labels.append(row['label_id'])\n\n    return {\n        'masks': np.stack(masks),          # shape becomes [N, H, W]\n        'boxes': np.array(boxes),\n        'labels': np.array(labels),\n    }","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T18:59:22.766393Z","iopub.execute_input":"2026-08-09T18:59:22.766644Z","iopub.status.idle":"2026-08-09T18:59:22.778698Z","shell.execute_reply.started":"2026-08-09T18:59:22.766607Z","shell.execute_reply":"2026-08-09T18:59:22.777824Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Data Augmentation","metadata":{}},{"cell_type":"code","source":"def get_transform(train):\n    tfs = []\n    if train:\n        tfs.append(T.RandomPhotometricDistort(p=0.5))\n    tfs.append(T.PILToTensor())\n    if train:\n        tfs.append(T.RandomHorizontalFlip(0.5))\n    return T.Compose(tfs)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T19:07:55.593769Z","iopub.execute_input":"2026-08-09T19:07:55.594768Z","iopub.status.idle":"2026-08-09T19:07:55.599444Z","shell.execute_reply.started":"2026-08-09T19:07:55.594728Z","shell.execute_reply":"2026-08-09T19:07:55.598627Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img_path = f\"{data_dir}/{train_df.iloc[0][\"ImageId\"]}\"   \nimage = Image.open(img_path).convert(\"RGB\")\nfig, axes = plt.subplots(2, 3, figsize=(12, 8))\n\naxes[0,0].imshow(image)\naxes[0,0].set_title(\"Original\")\naxes[0,0].axis(\"off\")\n\nfor i, ax in enumerate(axes.flat[1:]):\n    train_transform = get_transform(train=True)\n    aug, _ = train_transform(image, None)\n    aug = aug.permute(1, 2, 0)\n    ax.imshow(aug)\n    ax.set_title(f\"Aug {i+1}\")\n    ax.axis(\"off\")\n\nplt.tight_layout()\nplt.savefig(\"/kaggle/working/data_augmentation.png\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-03T12:32:37.773098Z","iopub.execute_input":"2026-08-03T12:32:37.773461Z","iopub.status.idle":"2026-08-03T12:33:03.265651Z","shell.execute_reply.started":"2026-08-03T12:32:37.773426Z","shell.execute_reply":"2026-08-03T12:33:03.264719Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Dataset Class","metadata":{}},{"cell_type":"code","source":"class ClothingDataset(Dataset):\n    def __init__(self, df, image_dir, transforms=None, max_dim=512):\n        self.df = df\n        self.image_dir = image_dir\n        self.transforms = transforms\n        self.image_ids = df[\"ImageId\"].unique()\n        self.max_dim = max_dim\n\n    def __len__(self):\n        return len(self.image_ids)\n\n    def __getitem__(self, idx):\n        image_id = self.image_ids[idx]\n        img_path = f\"{self.image_dir}/{image_id}\"\n        img = Image.open(img_path).convert(\"RGB\")\n        orig_w, orig_h = img.size\n\n        raw = build_maskrcnn_target(image_id, self.df)\n\n        boxes = raw[\"boxes\"].astype(float)\n        masks = raw[\"masks\"]\n        labels = raw[\"labels\"]\n\n        # --- RESIZE  ---\n        scale = self.max_dim / max(orig_w, orig_h)\n        new_w, new_h = int(orig_w * scale), int(orig_h * scale)\n\n        img = img.resize((new_w, new_h))\n\n        boxes[:, [0, 2]] *= scale\n        boxes[:, [1, 3]] *= scale\n\n        masks = np.stack([\n            cv2.resize(m, (new_w, new_h), interpolation=cv2.INTER_NEAREST)\n            for m in masks\n        ])\n\n        for i in range(len(boxes)):\n            if (boxes[i][2] - boxes[i][0] <= 10) or (boxes[i][3] - boxes[i][1] <= 10):\n                boxes[i][2] = boxes[i][0] + 10\n                boxes[i][3] = boxes[i][1] + 10\n\n        boxes = torch.as_tensor(boxes, dtype=torch.float32)\n        labels = torch.as_tensor(labels, dtype=torch.int64)\n        masks = torch.as_tensor(masks, dtype=torch.uint8)\n        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])\n        iscrowd = torch.zeros((len(boxes),), dtype=torch.int64)\n\n        target = {\n            \"boxes\": boxes,\n            \"labels\": labels,\n            \"masks\": masks,\n            \"image_id\": idx,\n            \"area\": area,\n            \"iscrowd\": iscrowd,\n        }\n\n        if self.transforms is not None:\n            img, target = self.transforms(img, target)\n\n        if img.dtype == torch.uint8:\n            img = img / 255.\n\n        return img, target","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T18:59:22.779771Z","iopub.execute_input":"2026-08-09T18:59:22.780126Z","iopub.status.idle":"2026-08-09T18:59:22.794064Z","shell.execute_reply.started":"2026-08-09T18:59:22.780092Z","shell.execute_reply":"2026-08-09T18:59:22.793281Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dataset = ClothingDataset(train_df, data_dir, transforms=get_transform(train=True))\nval_dataset = ClothingDataset(val_df, data_dir, transforms=get_transform(train=False))\n\nimg, target = train_dataset[0]\nprint(img.shape, img.dtype)\nprint(target[\"boxes\"].shape, target[\"labels\"], target[\"masks\"].shape)\nprint(img.min().item(), img.max().item())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T11:06:21.924409Z","iopub.execute_input":"2026-08-09T11:06:21.924996Z","iopub.status.idle":"2026-08-09T11:06:22.935442Z","shell.execute_reply.started":"2026-08-09T11:06:21.924948Z","shell.execute_reply":"2026-08-09T11:06:22.934640Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Dataloaders","metadata":{}},{"cell_type":"code","source":"train_loader = DataLoader(\n    train_dataset,\n    batch_size=4,\n    shuffle=True,\n    collate_fn=utils.collate_fn,\n    num_workers=4\n)\n\nval_loader = DataLoader(\n    val_dataset,\n    batch_size=4,\n    shuffle=False,\n    collate_fn=utils.collate_fn,\n    num_workers=4\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T11:06:22.936563Z","iopub.execute_input":"2026-08-09T11:06:22.936973Z","iopub.status.idle":"2026-08-09T11:06:22.941992Z","shell.execute_reply.started":"2026-08-09T11:06:22.936946Z","shell.execute_reply":"2026-08-09T11:06:22.941313Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"images, targets = next(iter(train_loader))\nprint(len(images), len(targets))\nprint(images[0].shape)\nprint(targets[0][\"boxes\"].shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T11:06:22.942950Z","iopub.execute_input":"2026-08-09T11:06:22.943552Z","iopub.status.idle":"2026-08-09T11:06:28.092692Z","shell.execute_reply.started":"2026-08-09T11:06:22.943479Z","shell.execute_reply":"2026-08-09T11:06:28.091742Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Model","metadata":{}},{"cell_type":"code","source":"def get_model_instance_segmentation(num_classes):\n    # load an instance segmentation model pre-trained pre-trained on COCO\n    model = torchvision.models.detection.maskrcnn_resnet50_fpn(weights=\"DEFAULT\", min_size=512, max_size=800)\n    for param in model.backbone.parameters():\n            param.requires_grad = False\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    #  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,num_classes)\n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T18:59:22.795114Z","iopub.execute_input":"2026-08-09T18:59:22.795456Z","iopub.status.idle":"2026-08-09T18:59:22.809629Z","shell.execute_reply.started":"2026-08-09T18:59:22.795425Z","shell.execute_reply":"2026-08-09T18:59:22.808985Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = get_model_instance_segmentation(24)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T18:59:22.810493Z","iopub.execute_input":"2026-08-09T18:59:22.810809Z","iopub.status.idle":"2026-08-09T18:59:24.694226Z","shell.execute_reply.started":"2026-08-09T18:59:22.810778Z","shell.execute_reply":"2026-08-09T18:59:24.693559Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# unfreeze last 2  backbone block for more adaptive fine-tuning\nfor name, param in model.backbone.named_parameters():\n    if \"layer4\" in name or \"layer3\" in name:\n        param.requires_grad = True\n    else:\n        param.requires_grad = False\n        \nparams = [p for p in model.parameters() if p.requires_grad]\noptimizer = torch.optim.SGD(params, lr=0.005,\n                            momentum=0.9, weight_decay=0.0005)\nlr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer,\n                                                step_size=3,\n                                                gamma=0.1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T18:59:24.695099Z","iopub.execute_input":"2026-08-09T18:59:24.695498Z","iopub.status.idle":"2026-08-09T18:59:24.701750Z","shell.execute_reply.started":"2026-08-09T18:59:24.695456Z","shell.execute_reply":"2026-08-09T18:59:24.700896Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"trainable = sum(p.numel() for p in model.parameters() if p.requires_grad)\ntotal = sum(p.numel() for p in model.parameters())\nprint(f\"Trainable: {trainable:,} / Total: {total:,}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T11:06:29.798371Z","iopub.execute_input":"2026-08-09T11:06:29.798745Z","iopub.status.idle":"2026-08-09T11:06:29.815662Z","shell.execute_reply.started":"2026-08-09T11:06:29.798721Z","shell.execute_reply":"2026-08-09T11:06:29.814906Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T11:01:10.560571Z","iopub.execute_input":"2026-08-09T11:01:10.560972Z","iopub.status.idle":"2026-08-09T11:01:10.566878Z","shell.execute_reply.started":"2026-08-09T11:01:10.560943Z","shell.execute_reply":"2026-08-09T11:01:10.566088Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"checkpoint = torch.load(\"/kaggle/working/checkpoints/maskrcnn_epoch_9.pth\", map_location=device2)\nmodel.load_state_dict(checkpoint[\"model_state_dict\"])\nmodel.to(device2)  \nprint(next(model.parameters()).device)  ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T18:59:24.702533Z","iopub.execute_input":"2026-08-09T18:59:24.702950Z","iopub.status.idle":"2026-08-09T18:59:25.091556Z","shell.execute_reply.started":"2026-08-09T18:59:24.702915Z","shell.execute_reply":"2026-08-09T18:59:25.090887Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"trn_history = []\nstart_epoch = 7\nnum_epochs = 3  \n\nfor epoch in range(start_epoch, start_epoch + num_epochs):\n    res = train_one_epoch(model, optimizer, train_loader, device2, epoch, print_freq=10)\n    trn_history.append(res)\n\n    lr_scheduler.step()\n    \n    checkpoint_path = f\"/kaggle/working/checkpoints/maskrcnn_epoch_{epoch}.pth\"\n    torch.save({\n        \"epoch\": epoch,\n        \"model_state_dict\": model.state_dict(),\n        \"optimizer_state_dict\": optimizer.state_dict(),\n        \"lr_scheduler_state_dict\": lr_scheduler.state_dict(),\n    }, checkpoint_path)\n    print(f\"Saved checkpoint: {checkpoint_path}\")\n\n    res = evaluate(model, val_loader, device=device2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T11:07:23.909398Z","iopub.execute_input":"2026-08-09T11:07:23.909726Z","iopub.status.idle":"2026-08-09T18:03:21.165583Z","shell.execute_reply.started":"2026-08-09T11:07:23.909695Z","shell.execute_reply":"2026-08-09T18:03:21.164594Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.title('Training Loss')\nlosses = [np.mean(list(trn_history[i].meters['loss'].deque)) for i in range(len(trn_history))]\nplt.savefig(\"/kaggle/working/Training_Loss_epoch_786.png\")\nplt.plot(losses)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T18:05:36.295238Z","iopub.execute_input":"2026-08-09T18:05:36.296185Z","iopub.status.idle":"2026-08-09T18:05:36.579214Z","shell.execute_reply.started":"2026-08-09T18:05:36.296152Z","shell.execute_reply":"2026-08-09T18:05:36.578433Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import gc\ngc.collect()\ntorch.cuda.empty_cache()\n\nprint(torch.cuda.memory_allocated() / 1e9, \"GB allocated\")\nprint(torch.cuda.memory_reserved() / 1e9, \"GB reserved\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-01T19:16:59.143801Z","iopub.execute_input":"2026-08-01T19:16:59.144245Z","iopub.status.idle":"2026-08-01T19:16:59.964695Z","shell.execute_reply.started":"2026-08-01T19:16:59.144214Z","shell.execute_reply":"2026-08-01T19:16:59.963872Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Evaluation","metadata":{}},{"cell_type":"code","source":"test_dataset = ClothingDataset(test_df, data_dir, transforms=get_transform(train=False))\ntest_loader = DataLoader(test_dataset, batch_size=1, shuffle=False, collate_fn=utils.collate_fn, num_workers=2)\nimg, target = test_dataset[0]\nprint(img.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T19:08:04.026665Z","iopub.execute_input":"2026-08-09T19:08:04.026934Z","iopub.status.idle":"2026-08-09T19:08:04.135471Z","shell.execute_reply.started":"2026-08-09T19:08:04.026911Z","shell.execute_reply":"2026-08-09T19:08:04.134656Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"res_test = evaluate(model, test_loader, device=device2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T19:08:06.119214Z","iopub.execute_input":"2026-08-09T19:08:06.119969Z","iopub.status.idle":"2026-08-09T19:39:33.805767Z","shell.execute_reply.started":"2026-08-09T19:08:06.119937Z","shell.execute_reply":"2026-08-09T19:39:33.804744Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.eval()\nidx = 16\nimg, target = test_dataset[idx]\n\nwith torch.no_grad():\n    pred = model([img.to(device2)])\n\npred = pred[0]\nscores = pred['scores'].cpu().numpy()\nboxes = pred['boxes'].cpu().numpy()\nlabels = pred['labels'].cpu().numpy()\nmasks = pred['masks'].cpu().numpy()\nkeep = scores > 0.5\nprint(f\"Detections above 0.5: {keep.sum()} / {len(scores)}\")\n\nimg_np = img.permute(1, 2, 0).cpu().numpy()\n\nfig, ax = plt.subplots(1, 2, figsize=(14, 7))\nax[0].imshow(img_np)\nax[0].set_title(\"Original\")\nax[0].axis('off')\n\nax[1].imshow(img_np)\nfor i in np.where(keep)[0]:\n    box = boxes[i]\n    mask = masks[i, 0] > 0.5\n    ax[1].imshow(np.ma.masked_where(~mask, mask), alpha=0.5, cmap='autumn')\n    x0, y0, x1, y1 = box\n    ax[1].add_patch(plt.Rectangle((x0, y0), x1-x0, y1-y0, fill=False, color='lime', linewidth=2))\n    class_name = id_to_class[str(labels[i])] if isinstance(list(id_to_class.keys())[0], str) else id_to_class[labels[i]]\n    ax[1].text(x0, y0-5, f\"{class_name} {scores[i]:.2f}\", color='white', backgroundcolor='black', fontsize=8)\nax[1].set_title(\"Predictions\")\nax[1].axis('off')\n\nplt.tight_layout()\nplt.savefig(\"/kaggle/working/maskrcnn_inference_testsample_epoch9.png\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T19:39:33.807427Z","iopub.execute_input":"2026-08-09T19:39:33.807803Z","iopub.status.idle":"2026-08-09T19:39:35.392733Z","shell.execute_reply.started":"2026-08-09T19:39:33.807776Z","shell.execute_reply":"2026-08-09T19:39:35.391792Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls \"/kaggle/working/checkpoints\"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for file in os.listdir(\"/kaggle/working\"):\n    if file.lower().endswith(\".png\"):\n        os.remove(os.path.join(\"/kaggle/working\", file))\n# shutil.make_archive(\"/kaggle/working/checkpoint\", \"zip\", \"/kaggle/working/checkpoints\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-09T20:06:06.791391Z","iopub.execute_input":"2026-08-09T20:06:06.791731Z","iopub.status.idle":"2026-08-09T20:06:06.796469Z","shell.execute_reply.started":"2026-08-09T20:06:06.791703Z","shell.execute_reply":"2026-08-09T20:06:06.795852Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls -lh \"/kaggle/working/checkpoints.zip\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-02T18:40:35.610988Z","iopub.execute_input":"2026-08-02T18:40:35.611835Z","iopub.status.idle":"2026-08-02T18:40:35.873917Z","shell.execute_reply.started":"2026-08-02T18:40:35.611802Z","shell.execute_reply":"2026-08-02T18:40:35.873136Z"}},"outputs":[],"execution_count":null}]}