自定义数据集运行TorchVision MaskRCNN时评估阶段触发AssertionError:结果与当前COCO集不匹配(类型和大小错误)
自定义数据集运行TorchVision MaskRCNN时评估阶段触发AssertionError:结果与当前COCO集不匹配(类型和大小错误)
我帮你定位到问题根源了,这个断言错误主要是两个核心问题导致的:图像ID的类型不匹配,以及图像ID的取值和COCO评估器预期的真实图像ID不对应。咱们一步步来解决:
1. 问题核心分析
从你调试的结果能明显看到:
annsImgIds是包含张量的列表([tensor([344])]),但self.getImgIds()是整数集合,类型直接不匹配触发了断言;- 你用
Subset拆分了数据集,但在Dataset里把image_id设成了Subset的相对索引,而不是图像对应的真实ID,这就导致评估时的图像ID和COCO数据集记录的全量图像ID(1633个)完全不对等,大小自然差很多。
2. 修复步骤
步骤一:在Dataset中保存真实图像ID
你的annotations里用图像文件名的前缀(img_name[:-4])作为key,这就是每个图像的真实ID。咱们先在Dataset初始化时把这些ID存下来:
修改HubmapDataset的__init__方法:
def __init__(self, data_dir: str, annotations_path: str, transforms=None) -> None: super().__init__() self.data_dir = data_dir self.annotations = self._extract_annotations(annotations_path) self.transforms = transforms self._labels = { "cat": 0, "dog": 1, "unsure": 2, } self.image_list = [ f for f in os.listdir(data_dir) if f[:-4] in self.annotations ] # 新增:保存每个图像对应的真实ID(和annotations里的key完全一致) self.image_ids = [f[:-4] for f in self.image_list]
步骤二:修正target中的image_id取值和类型
在__getitem__方法里,把image_id从Subset的相对索引改成真实图像ID,并且确保是整数类型的张量(不需要用列表包裹,单值张量就符合要求):
把原来的:
target["image_id"] = torch.tensor([index])
替换成:
# 用真实图像ID,转成整数张量 target["image_id"] = torch.tensor(int(self.image_ids[index]), dtype=torch.int64)
步骤三:验证Subset拆分后的图像ID一致性
你用同一个indices拆分ds_train和ds_test是没问题的,目前的代码也保证了ds_test的image_list和ds_train对应。修正后,测试集里每个样本的image_id都是annotations中真实存在的ID,会和COCO评估器的getImgIds()集合完全匹配。
步骤四:额外检查点
- 你的
target["labels"] = torch.as_tensor(labels, dtype=torch.int64) - 1处理是对的,MaskRCNN默认背景为0,类别从1开始计数,这个逻辑没问题; - 可以手动核对几个样本的
image_id和annotations.json里的图像ID是否一致,避免出现文件名或索引的匹配错误。
这样修改后,评估阶段的图像ID类型和取值都会和COCO评估器的预期对齐,断言错误应该就能解决了。
备注:内容来源于stack exchange,提问作者Duck Bongos
相关产品推荐
相关产品推荐

