Skip to content

Commit 9cae156

Browse files
YosuaMichaelpmeier
andauthored
Add test for giou_loss (#5792)
* Add test for giou_loss * Use standard assert for integer comparison Co-authored-by: Philip Meier <[email protected]> * Fix ufmt format and add log after assert Co-authored-by: Philip Meier <[email protected]>
1 parent 467b841 commit 9cae156

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

test/test_ops.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,5 +1569,59 @@ def test_jit(self, alpha, gamma, reduction, device, dtype, seed) -> None:
15691569
torch.testing.assert_close(focal_loss, scripted_focal_loss, rtol=tol, atol=tol)
15701570

15711571

1572+
class TestGeneralizedBoxIouLoss:
1573+
# We refer to original test: https://github.com/facebookresearch/fvcore/blob/main/tests/test_giou_loss.py
1574+
@pytest.mark.parametrize("device", cpu_and_gpu())
1575+
@pytest.mark.parametrize("dtype", [torch.float32, torch.half])
1576+
def test_giou_loss(self, dtype, device) -> None:
1577+
box1 = torch.tensor([-1, -1, 1, 1], dtype=dtype, device=device)
1578+
box2 = torch.tensor([0, 0, 1, 1], dtype=dtype, device=device)
1579+
box3 = torch.tensor([0, 1, 1, 2], dtype=dtype, device=device)
1580+
box4 = torch.tensor([1, 1, 2, 2], dtype=dtype, device=device)
1581+
box1s = torch.stack([box2, box2], dim=0)
1582+
box2s = torch.stack([box3, box4], dim=0)
1583+
1584+
def assert_giou_loss(box1, box2, expected_loss, reduction="none"):
1585+
tol = 1e-3 if dtype is torch.half else 1e-5
1586+
computed_loss = ops.generalized_box_iou_loss(box1, box2, reduction=reduction)
1587+
expected_loss = torch.tensor(expected_loss, device=device)
1588+
torch.testing.assert_close(computed_loss, expected_loss, rtol=tol, atol=tol)
1589+
1590+
# Identical boxes should have loss of 0
1591+
assert_giou_loss(box1, box1, 0.0)
1592+
1593+
# quarter size box inside other box = IoU of 0.25
1594+
assert_giou_loss(box1, box2, 0.75)
1595+
1596+
# Two side by side boxes, area=union
1597+
# IoU=0 and GIoU=0 (loss 1.0)
1598+
assert_giou_loss(box2, box3, 1.0)
1599+
1600+
# Two diagonally adjacent boxes, area=2*union
1601+
# IoU=0 and GIoU=-0.5 (loss 1.5)
1602+
assert_giou_loss(box2, box4, 1.5)
1603+
1604+
# Test batched loss and reductions
1605+
assert_giou_loss(box1s, box2s, 2.5, reduction="sum")
1606+
assert_giou_loss(box1s, box2s, 1.25, reduction="mean")
1607+
1608+
@pytest.mark.parametrize("device", cpu_and_gpu())
1609+
@pytest.mark.parametrize("dtype", [torch.float32, torch.half])
1610+
def test_empty_inputs(self, dtype, device) -> None:
1611+
box1 = torch.randn([0, 4], dtype=dtype).requires_grad_()
1612+
box2 = torch.randn([0, 4], dtype=dtype).requires_grad_()
1613+
1614+
loss = ops.generalized_box_iou_loss(box1, box2, reduction="mean")
1615+
loss.backward()
1616+
1617+
tol = 1e-3 if dtype is torch.half else 1e-5
1618+
torch.testing.assert_close(loss, torch.tensor(0.0), rtol=tol, atol=tol)
1619+
assert box1.grad is not None, "box1.grad should not be None after backward is called"
1620+
assert box2.grad is not None, "box2.grad should not be None after backward is called"
1621+
1622+
loss = ops.generalized_box_iou_loss(box1, box2, reduction="none")
1623+
assert loss.numel() == 0, "giou_loss for two empty box should be empty"
1624+
1625+
15721626
if __name__ == "__main__":
15731627
pytest.main([__file__])

0 commit comments

Comments
 (0)