Skip to content

Commit

Permalink
[fbsync] Add test for giou_loss (#5792)
Browse files Browse the repository at this point in the history
Summary:
* Add test for giou_loss

* Use standard assert for integer comparison

* Fix ufmt format and add log after assert

Reviewed By: jdsgomes, NicolasHug

Differential Revision: D36095688

fbshipit-source-id: 2dafe815e8cfa749cb71ed2071826835a4218425

Co-authored-by: Philip Meier <github.pmeier@posteo.de>
Co-authored-by: Philip Meier <github.pmeier@posteo.de>
  • Loading branch information
2 people authored and facebook-github-bot committed May 5, 2022
1 parent e7f9510 commit e4d36fd
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions test/test_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -1569,5 +1569,59 @@ def test_jit(self, alpha, gamma, reduction, device, dtype, seed) -> None:
torch.testing.assert_close(focal_loss, scripted_focal_loss, rtol=tol, atol=tol)


class TestGeneralizedBoxIouLoss:
# We refer to original test: https://github.com/facebookresearch/fvcore/blob/main/tests/test_giou_loss.py
@pytest.mark.parametrize("device", cpu_and_gpu())
@pytest.mark.parametrize("dtype", [torch.float32, torch.half])
def test_giou_loss(self, dtype, device) -> None:
box1 = torch.tensor([-1, -1, 1, 1], dtype=dtype, device=device)
box2 = torch.tensor([0, 0, 1, 1], dtype=dtype, device=device)
box3 = torch.tensor([0, 1, 1, 2], dtype=dtype, device=device)
box4 = torch.tensor([1, 1, 2, 2], dtype=dtype, device=device)
box1s = torch.stack([box2, box2], dim=0)
box2s = torch.stack([box3, box4], dim=0)

def assert_giou_loss(box1, box2, expected_loss, reduction="none"):
tol = 1e-3 if dtype is torch.half else 1e-5
computed_loss = ops.generalized_box_iou_loss(box1, box2, reduction=reduction)
expected_loss = torch.tensor(expected_loss, device=device)
torch.testing.assert_close(computed_loss, expected_loss, rtol=tol, atol=tol)

# Identical boxes should have loss of 0
assert_giou_loss(box1, box1, 0.0)

# quarter size box inside other box = IoU of 0.25
assert_giou_loss(box1, box2, 0.75)

# Two side by side boxes, area=union
# IoU=0 and GIoU=0 (loss 1.0)
assert_giou_loss(box2, box3, 1.0)

# Two diagonally adjacent boxes, area=2*union
# IoU=0 and GIoU=-0.5 (loss 1.5)
assert_giou_loss(box2, box4, 1.5)

# Test batched loss and reductions
assert_giou_loss(box1s, box2s, 2.5, reduction="sum")
assert_giou_loss(box1s, box2s, 1.25, reduction="mean")

@pytest.mark.parametrize("device", cpu_and_gpu())
@pytest.mark.parametrize("dtype", [torch.float32, torch.half])
def test_empty_inputs(self, dtype, device) -> None:
box1 = torch.randn([0, 4], dtype=dtype).requires_grad_()
box2 = torch.randn([0, 4], dtype=dtype).requires_grad_()

loss = ops.generalized_box_iou_loss(box1, box2, reduction="mean")
loss.backward()

tol = 1e-3 if dtype is torch.half else 1e-5
torch.testing.assert_close(loss, torch.tensor(0.0), rtol=tol, atol=tol)
assert box1.grad is not None, "box1.grad should not be None after backward is called"
assert box2.grad is not None, "box2.grad should not be None after backward is called"

loss = ops.generalized_box_iou_loss(box1, box2, reduction="none")
assert loss.numel() == 0, "giou_loss for two empty box should be empty"


if __name__ == "__main__":
pytest.main([__file__])

0 comments on commit e4d36fd

Please sign in to comment.