pytorch Assert错误:结果与当前coco套件不一致-类型和尺寸错误

rbpvctlc  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(238)

我正在努力用我自己的用例来支持torchvision tutorial MaskRCNN。我有图像,每个图像有3个类的[0,N]个示例。我正在尝试识别和分类每个片段。这在pycocotools/coco.py的评估步骤中中断:

  1. assert set(annsImgIds) == (set(annsImgIds) & set(self.getImgIds())), \
  2. 'Results do not correspond to current coco set'

字符串
当我调试它时,我发现这两套不仅大小不同,而且类型也不同。

  1. >>> annsImgIds
  2. [tensor([344])]
  3. >>> self.getImgIds()
  4. {0, 1, 2, 3, 4, 5, 6, ... } # len: 1633, the length of my dataset


我确信这是DataLoader中的一个简单错误,但对于我的生活,我找不到它,可以使用帮助调试类型和大小。在这里和GitHub上关于这个问题的其他帖子经常提到将json权重保存到相同的位置,但我没有这样做(或者我不知道我正在这样做)。
下面是我如何加载数据:

  1. ds_train = MyDataset(
  2. data_dir="train/",
  3. annotations_path="annotations.json",
  4. transforms=get_transform(train=True),
  5. )
  6. ds_test = MyDataset(
  7. data_dir="train/",
  8. annotations_path="annotations.json",
  9. transforms=get_transform(train=False),
  10. )
  11. dataset_size = len(ds_train)
  12. indices = torch.randperm(dataset_size).tolist()
  13. # 80-20 split
  14. dataset = torch.utils.data.Subset(ds_train, indices[: -int(dataset_size * 0.2)])
  15. dataset_test = torch.utils.data.Subset(
  16. ds_test, indices[-int(dataset_size * 0.2) :]
  17. )
  18. data_loader = DataLoader(
  19. dataset,
  20. batch_size=2,
  21. shuffle=True,
  22. num_workers=1,
  23. collate_fn=my_collate,
  24. pin_memory=True,
  25. )
  26. data_loader_test = DataLoader(
  27. dataset_test,
  28. batch_size=1,
  29. shuffle=True,
  30. num_workers=1,
  31. collate_fn=my_collate,
  32. pin_memory=True,
  33. )


下面是我的collate函数:

  1. def my_collate(batch):
  2. data = [item[0] for item in batch]
  3. target = [item[1] for item in batch]
  4. data = torch.stack(data)
  5. # target = torch.LongTensor(target) # threw errors until I removed it
  6. return [data, target]


MyDataset类:

  1. class HubmapDataset(Dataset):
  2. def __init__(self, data_dir: str, annotations_path: str, transforms=None) -> None:
  3. super().__init__()
  4. self.data_dir = data_dir
  5. self.annotations = self._extract_annotations(annotations_path)
  6. self.transforms = transforms
  7. self._labels = {
  8. "cat": 0,
  9. "dog": 1,
  10. "unsure": 2,
  11. }
  12. self.image_list = [
  13. f for f in os.listdir(data_dir) if f[:-4] in self.annotations
  14. ] # might need to filter this down
  15. def _calc_area(self, box):
  16. return (box[2] - box[0]) * (box[3] - box[1])
  17. def _extract_annotations(self, fp) -> Dict[str, Any]:
  18. l = []
  19. with open(fp) as polygon:
  20. j = polygon.read()
  21. l = j.split("\n")
  22. z = {}
  23. for i, row in enumerate(l):
  24. try:
  25. r = json.loads(row)
  26. z[r["id"]] = r["annotations"]
  27. except json.JSONDecodeError as jde:
  28. print(i, jde, row)
  29. return z
  30. def _get_bbox(self, coords: np.ndarray):
  31. xmin = int(np.min(coords[:, 1]))
  32. ymin = int(np.min(coords[:, 0]))
  33. xmax = int(np.max(coords[:, 1]))
  34. ymax = int(np.max(coords[:, 0]))
  35. return [xmin, ymin, xmax, ymax]
  36. def __len__(self):
  37. return len(self.image_list)
  38. def _valid_labels(self, labels):
  39. try:
  40. torch.where(labels > 0)[0]
  41. return True
  42. except Exception:
  43. return False
  44. def _convert_labels(self, labels: np.ndarray):
  45. """Convert labels to be from 0-2"""
  46. labels_ = labels.copy()
  47. if len(np.unique(labels)) == 1:
  48. labels_ = np.zeros(labels.shape)
  49. elif np.min(labels) == 2:
  50. labels_ = labels - 2
  51. elif np.min(labels) == 1:
  52. labels_ = labels - 1
  53. elif np.min(labels) == 0 and len(np.where(labels == 1)[0]) == 0:
  54. labels[np.where(labels == 2)[0]] = 1
  55. labels_ = labels
  56. assert len(np.unique(labels_)) - 1 == np.max(labels_)
  57. return labels_
  58. def __getitem__(self, index) -> Any:
  59. img_name = self.image_list[index]
  60. image_path = os.path.join(self.data_dir, img_name)
  61. image = Image.open(image_path)
  62. annotations = self.annotations[img_name[:-4]]
  63. num_objs = len(annotations)
  64. # create the masks of size (512,512,num_objs)
  65. masks = np.zeros((num_objs, 512, 512), dtype=np.uint8)
  66. boxes = [None] * num_objs
  67. areas = [None] * num_objs
  68. labels = []
  69. # for each mask, add labels, boxes
  70. for i in range(num_objs):
  71. l_type = annotations[i]["type"]
  72. label_color = self._labels[l_type]
  73. coords = np.array(annotations[i]["coordinates"])[0]
  74. # set the mask coordinates equal to the label color
  75. m = np.zeros((512, 512))
  76. m[coords[:, 1], coords[:, 0]] = label_color
  77. cv2.fillPoly(m, pts=[coords], color=label_color)
  78. masks[i, :, :] = m
  79. # update the label
  80. labels.append(label_color)
  81. # create the bounding boxes
  82. bbox = self._get_bbox(coords)
  83. areas[i] = self._calc_area(bbox)
  84. boxes[i] = bbox
  85. labels = self._convert_labels(np.array(labels))
  86. # labels = np.array(list(np.unique(labels)))
  87. target = {}
  88. target["boxes"] = torch.as_tensor(boxes, dtype=torch.float32)
  89. target["area"] = torch.as_tensor(areas, dtype=torch.float32)
  90. target["labels"] = torch.as_tensor(labels, dtype=torch.int64) - 1
  91. target["masks"] = torch.as_tensor(masks, dtype=torch.uint8)
  92. assert target["masks"].shape[0] == num_objs
  93. target["image_id"] = torch.tensor([index])
  94. if self.transforms is not None:
  95. image, target = self.transforms(image, target)
  96. else:
  97. image = PILToTensor()(image)
  98. return image, target


训练循环:

  1. running_loss = 0
  2. num_epochs = 10
  3. for epoch in range(num_epochs):
  4. # train for one epoch, printing every 10 iterations
  5. train_one_epoch(model, optimizer, data_loader, device, epoch, print_freq=10)
  6. # update the learning rate
  7. lr_scheduler.step()
  8. # evaluate on the test dataset
  9. evaluate(model, data_loader_test, device=device)
  10. print("Complete!")

7y4bm7vi

7y4bm7vi1#

是否跳过了原始数据文件中的某些样本?确保样本数量与[“image_id”]的总数一致。我遇到了和你一样的bug,这个修复了我的bug。

相关问题