|
|
|
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 |
|
""" |
|
|
|
box = torch.tensor([-1, -1, 1, 1], dtype=torch.float32) |
|
loss = diou_loss(box, box) |
|
self.assertTrue(np.allclose(loss, [0.0])) |
|
|
|
|
|
|
|
box2 = torch.tensor([0, -1, 1, 1], dtype=torch.float32) |
|
loss = diou_loss(box, box2) |
|
self.assertTrue(np.allclose(loss, [0.53125])) |
|
|
|
|
|
|
|
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])) |
|
|
|
|
|
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) |
|
""" |
|
|
|
box = torch.tensor([-1, -1, 1, 1], dtype=torch.float32) |
|
loss = ciou_loss(box, box) |
|
self.assertTrue(np.allclose(loss, [0.0])) |
|
|
|
|
|
|
|
|
|
|
|
box2 = torch.tensor([0, -1, 1, 1], dtype=torch.float32) |
|
loss = ciou_loss(box, box2) |
|
self.assertTrue(np.allclose(loss, [0.5345])) |
|
|
|
|
|
|
|
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])) |
|
|
|
|
|
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])) |
|
|