예제 #1
0
    def __call__(
        self, preds: BoxMaps, gt_box_batch: List[YoloBoxes], anchormap: BoxMap
    ) -> Tensor:
        device = preds.device
        _, _, h, w = preds.shape
        box_losses: List[Tensor] = []
        anchors = boxmap_to_boxes(anchormap)
        for diff_map, gt_boxes in zip(preds, gt_box_batch):
            if len(gt_boxes) == 0:
                continue

            pred_boxes = boxmap_to_boxes(BoxMap(diff_map))
            match_indices, positive_indices = self.matcher(anchors, gt_boxes, (w, h))
            num_pos = positive_indices.sum()
            if num_pos == 0:
                continue
            matched_gt_boxes = YoloBoxes(gt_boxes[match_indices][positive_indices])
            matched_pred_boxes = YoloBoxes(pred_boxes[positive_indices])
            if self.use_diff:
                matched_pred_boxes = YoloBoxes(
                    anchors[positive_indices] + matched_pred_boxes
                )

            box_losses.append(
                self.loss(
                    yolo_to_pascal(matched_pred_boxes, (1, 1)),
                    yolo_to_pascal(matched_gt_boxes, (1, 1)),
                )
            )
        if len(box_losses) == 0:
            return torch.tensor(0.0).to(device)
        return torch.stack(box_losses).mean()
def test_nearest_assign() -> None:
    x = YoloBoxes(
        torch.tensor(
            [
                [0.11, 0.12, 0.1, 0.1],
                [0.21, 0.22, 0.1, 0.1],
                [0.25, 0.22, 0.1, 0.1],
                [0.31, 0.32, 0.1, 0.1],
                [0.41, 0.42, 0.1, 0.1],
                [0.61, 0.62, 0.1, 0.1],
            ]
        )
    )

    y = YoloBoxes(
        torch.tensor(
            [[0.1, 0.1, 0.1, 0.1], [0.2, 0.2, 0.1, 0.1], [0.3, 0.3, 0.1, 0.1],]
        )
    )

    fn = NearnestAssign()
    matched_idx, positive_idx = fn(x, y)
    assert (
        F.l1_loss(matched_idx.float(), torch.tensor([0, 1, 1, 2, 2, 2]).float()) < 1e-9
    )
    assert (
        F.l1_loss(positive_idx.float(), torch.tensor([1, 1, 0, 1, 0, 0]).float()) < 1e-9
    )
예제 #3
0
 def __call__(
         self,
         inputs: NetOutput) -> Tuple[List[YoloBoxes], List[Confidences]]:
     anchormap, box_diffs, heatmap = inputs
     device = heatmap.device
     if self.use_peak:
         kpmap = (self.max_pool(heatmap)
                  == heatmap) & (heatmap > self.threshold)
     else:
         kpmap = heatmap > self.threshold
     batch_size, _, height, width = heatmap.shape
     original_wh = torch.tensor([width, height],
                                dtype=torch.float32).to(device)
     rows: List[Tuple[YoloBoxes, Confidences]] = []
     box_batch = []
     conf_batch = []
     for hm, km, box_diff in zip(heatmap.squeeze(1), kpmap.squeeze(1),
                                 box_diffs):
         kp = torch.nonzero(km, as_tuple=False)
         confidences = hm[kp[:, 0], kp[:, 1]]
         anchor = anchormap[:, kp[:, 0], kp[:, 1]].t()
         box_diff = box_diff[:, kp[:, 0], kp[:, 1]].t()
         boxes = anchor + box_diff
         boxes = yolo_clamp(YoloBoxes(boxes))
         sort_idx = nms(yolo_to_pascal(boxes, (1, 1)), confidences,
                        self.nms_thresold)
         box_batch.append(YoloBoxes(boxes[sort_idx]))
         conf_batch.append(Confidences(confidences[sort_idx]))
     return box_batch, conf_batch
예제 #4
0
 def __call__(
         self, net_output: NetOutput
 ) -> t.Tuple[List[YoloBoxes], List[Confidences]]:
     anchor_levels, box_diff_levels, labels_levels = net_output
     box_batch = []
     confidence_batch = []
     anchors = torch.cat(anchor_levels, dim=0)  # type: ignore
     box_diffs = torch.cat(box_diff_levels, dim=1)  # type:ignore
     labels_batch = torch.cat(labels_levels, dim=1)  # type:ignore
     for box_diff, confidences in zip(box_diffs, labels_batch):
         boxes = anchors + box_diff
         confidences, c_index = confidences.max(dim=1)
         filter_idx = confidences > self.confidence_threshold
         confidences = confidences[filter_idx][:self.limit]
         boxes = boxes[filter_idx][:self.limit]
         sort_idx = nms(
             yolo_to_pascal(YoloBoxes(boxes), (1, 1)),
             confidences,
             self.iou_threshold,
         )
         confidences.argsort(descending=True)
         boxes = YoloBoxes(boxes[sort_idx])
         boxes = yolo_clamp(boxes)
         confidences = confidences[sort_idx]
         box_batch.append(boxes)
         confidence_batch.append(Confidences(confidences))
     return box_batch, confidence_batch
예제 #5
0
 def __getitem__(self, idx: int) -> TrainSample:
     image = torch.rand((3, *self.image_size), dtype=torch.float32)
     boxes = torch.rand((random.randint(1, 9), 4),
                        dtype=torch.float32).clamp(0, 1.0)
     labels = torch.zeros((len(boxes), ))
     return (ImageId(""), Image(image), YoloBoxes(boxes.float()),
             Labels(labels))
예제 #6
0
    def __call__(
        self, batch: t.Tuple[ImageBatch, t.List[YoloBoxes]]
    ) -> t.Tuple[ImageBatch, List[YoloBoxes]]:
        image_batch, box_batch = batch
        image_batch = ImageBatch(image_batch.to(self.device))
        box_batch = [YoloBoxes(x.to(self.device)) for x in box_batch]

        return image_batch, box_batch
def test_anchors() -> None:
    fn = Anchors(size=2)
    hm = torch.zeros((1, 1, 8, 8))
    anchors = fn(hm)
    boxes = boxmap_to_boxes(anchors)
    assert len(boxes) == 8 * 8

    plot = DetectionPlot(w=8, h=8)
    plot.with_yolo_boxes(YoloBoxes(boxes[[0, 4, 28, 27]]), color="blue")
    plot.save(f"store/test-anchorv1.png")
def test_mkcornermaps(h: int, w: int, cy: int, cx: int, dy: float, dx: float) -> None:
    in_boxes = YoloBoxes(torch.tensor([[0.201, 0.402, 0.1, 0.3]]))
    to_boxes = ToBoxes(threshold=0.1)
    mkmaps = MkCornerMaps()
    hm = mkmaps([in_boxes], (h, w), (h * 10, w * 10))
    assert hm.shape == (1, 1, h, w)
    mk_anchors = Anchors()
    anchormap = mk_anchors(hm)
    diffmaps = BoxMaps(torch.zeros((1, *anchormap.shape)))
    diffmaps = in_boxes.view(1, 4, 1, 1).expand_as(diffmaps) - anchormap

    out_box_batch, out_conf_batch = to_boxes((anchormap, diffmaps, hm))
    out_boxes = out_box_batch[0]
    for box in out_boxes:
        assert F.l1_loss(box, in_boxes[0]) < 1e-8
    plot = DetectionPlot(w=w, h=h)
    plot.with_image((hm[0, 0] + 1e-4).log())
    plot.with_yolo_boxes(out_boxes, color="red")
    plot.with_yolo_boxes(in_boxes, color="blue")
    plot.save(f"store/test-corner.png")
def test_mkmaps(h: int, w: int, cy: int, cx: int, dy: float, dx: float) -> None:
    in_boxes = YoloBoxes(torch.tensor([[0.201, 0.402, 0.1, 0.3]]))
    to_boxes = ToBoxes(threshold=0.1)
    mkmaps = MkGaussianMaps(sigma=2.0)
    hm = mkmaps([in_boxes], (h, w), (h * 10, w * 10))
    assert (torch.nonzero(hm.eq(1), as_tuple=False)[0, 2:] - torch.tensor([[cy, cx]])).sum() == 0  # type: ignore
    assert hm.shape == (1, 1, h, w)
    mk_anchors = Anchors()
    anchormap = mk_anchors(hm)
    diffmaps = BoxMaps(torch.zeros((1, *anchormap.shape)))
    diffmaps = in_boxes.view(1, 4, 1, 1).expand_as(diffmaps) - anchormap

    out_box_batch, out_conf_batch = to_boxes((anchormap, diffmaps, hm))
    out_boxes = out_box_batch[0]
    for box in out_boxes:
        assert F.l1_loss(box, in_boxes[0]) < 1e-8
    plot = DetectionPlot(w=w, h=h)
    plot.with_image((hm[0, 0] + 1e-4).log())
    plot.with_yolo_boxes(in_boxes, color="blue")
    plot.with_yolo_boxes(out_boxes, color="red")
    plot.save(f"store/test-heatmapv1.png")
예제 #10
0
 def _mkmaps(self, boxes: YoloBoxes, heatmaps: Heatmaps) -> BoxMaps:
     device = boxes.device
     _, _, h, w = heatmaps.shape
     boxmaps = torch.zeros((1, 4, h, w), dtype=torch.float32).to(device)
     box_count = len(boxes)
     if box_count == 0:
         return BoxMaps(boxmaps)
     wh = torch.tensor([w, h]).to(device)
     cxcy = (boxes[:, :2] * wh).long()
     cx = cxcy[:, 0]
     cy = cxcy[:, 1]
     boxmaps[:, :, cy, cx] = boxes.t()
     return BoxMaps(boxmaps)
예제 #11
0
 def __call__(
     self, batch: t.Tuple[ImageBatch, List[YoloBoxes], List[Labels]]
 ) -> t.Tuple[ImageBatch, List[YoloBoxes], List[Labels]]:
     image_batch, boxes_batch, label_batch = batch
     return (
         ImageBatch(
             image_batch.to(self.device, non_blocking=self.non_blocking)),
         [
             YoloBoxes(x.to(self.device, non_blocking=self.non_blocking))
             for x in boxes_batch
         ],
         [
             Labels(x.to(self.device, non_blocking=self.non_blocking))
             for x in label_batch
         ],
     )
예제 #12
0
def test_anchors(fsize: int, size: float, scales: List[float],
                 ratios: List[float]) -> None:
    h = fsize
    w = fsize
    images = ImageBatch(torch.zeros((1, 3, h, w), dtype=torch.float32))
    fn = Anchors(size=size, scales=scales, ratios=ratios)
    res = fn(images)
    num_anchors = len(scales) * len(ratios)
    anchor_count = w * h * num_anchors
    assert res.shape == (anchor_count, 4)
    offset = num_anchors * h * (w // 2) + num_anchors * h // 2
    ids = [offset + x for x in range(num_anchors)]
    plot = DetectionPlot(w=256, h=256)
    plot.with_yolo_boxes(YoloBoxes(res[ids]), color="red")
    plot.save(
        f"store/test-anchors-{fsize}-{size}-{'-'.join([str(x) for x in  scales])}-{num_anchors}.png"
    )
예제 #13
0
 def __call__(self, inputs: NetOutput) -> t.List[t.Tuple[YoloBoxes, Confidences]]:
     heatmaps, boxmaps, anchormap = inputs
     device = heatmaps.device
     kpmap = (self.max_pool(heatmaps) == heatmaps) & (heatmaps > self.threshold)
     batch_size, _, height, width = heatmaps.shape
     original_wh = torch.tensor([width, height], dtype=torch.float32).to(device)
     rows: t.List[t.Tuple[YoloBoxes, Confidences]] = []
     for hm, km, bm in zip(heatmaps.squeeze(1), kpmap.squeeze(1), boxmaps):
         kp = torch.nonzero(km, as_tuple=False)
         confidences = hm[kp[:, 0], kp[:, 1]]
         if self.use_diff:
             boxes = (
                 anchormap[:, kp[:, 0], kp[:, 1]].t() + bm[:, kp[:, 0], kp[:, 1]].t()
             )
         else:
             boxes = bm[:, kp[:, 0], kp[:, 1]].t()
         sort_idx = confidences.argsort(descending=True)[: self.limit]
         rows.append(
             (YoloBoxes(boxes[sort_idx]), Confidences(confidences[sort_idx]))
         )
     return rows