Spaces:
Runtime error
Runtime error
| # Copyright (c) Facebook, Inc. and its affiliates. | |
| import numpy as np | |
| import unittest | |
| import torch | |
| from detectron2.layers import ciou_loss, diou_loss | |
| class TestLosses(unittest.TestCase): | |
| def test_diou_loss(self): | |
| """ | |
| loss = 1 - iou + d/c | |
| where, | |
| d = (distance between centers of the 2 boxes)^2 | |
| c = (diagonal length of the smallest enclosing box covering the 2 boxes)^2 | |
| """ | |
| # Identical boxes should have loss of 0 | |
| box = torch.tensor([-1, -1, 1, 1], dtype=torch.float32) | |
| loss = diou_loss(box, box) | |
| self.assertTrue(np.allclose(loss, [0.0])) | |
| # Half size box inside other box | |
| # iou = 0.5, d = 0.25, c = 8 | |
| box2 = torch.tensor([0, -1, 1, 1], dtype=torch.float32) | |
| loss = diou_loss(box, box2) | |
| self.assertTrue(np.allclose(loss, [0.53125])) | |
| # Two diagonally adjacent boxes | |
| # iou = 0, d = 2, c = 8 | |
| box3 = torch.tensor([0, 0, 1, 1], dtype=torch.float32) | |
| box4 = torch.tensor([1, 1, 2, 2], dtype=torch.float32) | |
| loss = diou_loss(box3, box4) | |
| self.assertTrue(np.allclose(loss, [1.25])) | |
| # Test batched loss and reductions | |
| box1s = torch.stack([box, box3], dim=0) | |
| box2s = torch.stack([box2, box4], dim=0) | |
| loss = diou_loss(box1s, box2s, reduction="sum") | |
| self.assertTrue(np.allclose(loss, [1.78125])) | |
| loss = diou_loss(box1s, box2s, reduction="mean") | |
| self.assertTrue(np.allclose(loss, [0.890625])) | |
| def test_ciou_loss(self): | |
| """ | |
| loss = 1 - iou + d/c + alpha*v | |
| where, | |
| d = (distance between centers of the 2 boxes)^2 | |
| c = (diagonal length of the smallest enclosing box covering the 2 boxes)^2 | |
| v = (4/pi^2) * (arctan(box1_w/box1_h) - arctan(box2_w/box2_h))^2 | |
| alpha = v/(1 - iou + v) | |
| """ | |
| # Identical boxes should have loss of 0 | |
| box = torch.tensor([-1, -1, 1, 1], dtype=torch.float32) | |
| loss = ciou_loss(box, box) | |
| self.assertTrue(np.allclose(loss, [0.0])) | |
| # Half size box inside other box | |
| # iou = 0.5, d = 0.25, c = 8 | |
| # v = (4/pi^2) * (arctan(1) - arctan(0.5))^2 = 0.042 | |
| # alpha = 0.0775 | |
| box2 = torch.tensor([0, -1, 1, 1], dtype=torch.float32) | |
| loss = ciou_loss(box, box2) | |
| self.assertTrue(np.allclose(loss, [0.5345])) | |
| # Two diagonally adjacent boxes | |
| # iou = 0, d = 2, c = 8, v = 0, alpha = 0 | |
| box3 = torch.tensor([0, 0, 1, 1], dtype=torch.float32) | |
| box4 = torch.tensor([1, 1, 2, 2], dtype=torch.float32) | |
| loss = ciou_loss(box3, box4) | |
| self.assertTrue(np.allclose(loss, [1.25])) | |
| # Test batched loss and reductions | |
| box1s = torch.stack([box, box3], dim=0) | |
| box2s = torch.stack([box2, box4], dim=0) | |
| loss = ciou_loss(box1s, box2s, reduction="sum") | |
| self.assertTrue(np.allclose(loss, [1.7845])) | |
| loss = ciou_loss(box1s, box2s, reduction="mean") | |
| self.assertTrue(np.allclose(loss, [0.89225])) | |