test_base_boxes.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. from unittest import TestCase
  2. import numpy as np
  3. import torch
  4. from mmengine.testing import assert_allclose
  5. from .utils import ToyBaseBoxes
  6. class TestBaseBoxes(TestCase):
  7. def test_init(self):
  8. box_tensor = torch.rand((3, 4, 4))
  9. boxes = ToyBaseBoxes(box_tensor)
  10. boxes = ToyBaseBoxes(box_tensor, dtype=torch.float64)
  11. self.assertEqual(boxes.tensor.dtype, torch.float64)
  12. if torch.cuda.is_available():
  13. boxes = ToyBaseBoxes(box_tensor, device='cuda')
  14. self.assertTrue(boxes.tensor.is_cuda)
  15. with self.assertRaises(AssertionError):
  16. box_tensor = torch.rand((4, ))
  17. boxes = ToyBaseBoxes(box_tensor)
  18. with self.assertRaises(AssertionError):
  19. box_tensor = torch.rand((3, 4, 3))
  20. boxes = ToyBaseBoxes(box_tensor)
  21. def test_getitem(self):
  22. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  23. # test single dimension index
  24. # int
  25. new_boxes = boxes[0]
  26. self.assertIsInstance(new_boxes, ToyBaseBoxes)
  27. self.assertEqual(new_boxes.tensor.shape, (4, 4))
  28. # list
  29. new_boxes = boxes[[0, 2]]
  30. self.assertIsInstance(new_boxes, ToyBaseBoxes)
  31. self.assertEqual(new_boxes.tensor.shape, (2, 4, 4))
  32. # slice
  33. new_boxes = boxes[0:2]
  34. self.assertIsInstance(new_boxes, ToyBaseBoxes)
  35. self.assertEqual(new_boxes.tensor.shape, (2, 4, 4))
  36. # torch.LongTensor
  37. new_boxes = boxes[torch.LongTensor([0, 1])]
  38. self.assertIsInstance(new_boxes, ToyBaseBoxes)
  39. self.assertEqual(new_boxes.tensor.shape, (2, 4, 4))
  40. # torch.BoolTensor
  41. new_boxes = boxes[torch.BoolTensor([True, False, True])]
  42. self.assertIsInstance(new_boxes, ToyBaseBoxes)
  43. self.assertEqual(new_boxes.tensor.shape, (2, 4, 4))
  44. with self.assertRaises(AssertionError):
  45. index = torch.rand((2, 4, 4)) > 0
  46. new_boxes = boxes[index]
  47. # test multiple dimension index
  48. # select single box
  49. new_boxes = boxes[1, 2]
  50. self.assertIsInstance(new_boxes, ToyBaseBoxes)
  51. self.assertEqual(new_boxes.tensor.shape, (1, 4))
  52. # select the last dimension
  53. with self.assertRaises(AssertionError):
  54. new_boxes = boxes[1, 2, 1]
  55. # has Ellipsis
  56. new_boxes = boxes[None, ...]
  57. self.assertIsInstance(new_boxes, ToyBaseBoxes)
  58. self.assertEqual(new_boxes.tensor.shape, (1, 3, 4, 4))
  59. with self.assertRaises(AssertionError):
  60. new_boxes = boxes[..., None]
  61. def test_setitem(self):
  62. values = ToyBaseBoxes(torch.rand(3, 4, 4))
  63. tensor = torch.rand(3, 4, 4)
  64. # only support BaseBoxes type
  65. with self.assertRaises(AssertionError):
  66. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  67. boxes[0:2] = tensor[0:2]
  68. # test single dimension index
  69. # int
  70. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  71. boxes[1] = values[1]
  72. assert_allclose(boxes.tensor[1], values.tensor[1])
  73. # list
  74. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  75. boxes[[1, 2]] = values[[1, 2]]
  76. assert_allclose(boxes.tensor[[1, 2]], values.tensor[[1, 2]])
  77. # slice
  78. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  79. boxes[0:2] = values[0:2]
  80. assert_allclose(boxes.tensor[0:2], values.tensor[0:2])
  81. # torch.BoolTensor
  82. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  83. index = torch.rand(3, 4) > 0.5
  84. boxes[index] = values[index]
  85. assert_allclose(boxes.tensor[index], values.tensor[index])
  86. # multiple dimension index
  87. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  88. boxes[0:2, 0:2] = values[0:2, 0:2]
  89. assert_allclose(boxes.tensor[0:2, 0:2], values.tensor[0:2, 0:2])
  90. # select single box
  91. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  92. boxes[1, 1] = values[1, 1]
  93. assert_allclose(boxes.tensor[1, 1], values.tensor[1, 1])
  94. # select the last dimension
  95. with self.assertRaises(AssertionError):
  96. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  97. boxes[1, 1, 1] = values[1, 1, 1]
  98. # has Ellipsis
  99. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  100. boxes[0:2, ...] = values[0:2, ...]
  101. assert_allclose(boxes.tensor[0:2, ...], values.tensor[0:2, ...])
  102. def test_tensor_like_functions(self):
  103. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  104. # new_tensor
  105. boxes.new_tensor([1, 2, 3])
  106. # new_full
  107. boxes.new_full((3, 4), 0)
  108. # new_empty
  109. boxes.new_empty((3, 4))
  110. # new_ones
  111. boxes.new_ones((3, 4))
  112. # new_zeros
  113. boxes.new_zeros((3, 4))
  114. # size
  115. self.assertEqual(boxes.size(0), 3)
  116. self.assertEqual(tuple(boxes.size()), (3, 4, 4))
  117. # dim
  118. self.assertEqual(boxes.dim(), 3)
  119. # device
  120. self.assertIsInstance(boxes.device, torch.device)
  121. # dtype
  122. self.assertIsInstance(boxes.dtype, torch.dtype)
  123. # numpy
  124. np_boxes = boxes.numpy()
  125. self.assertIsInstance(np_boxes, np.ndarray)
  126. self.assertTrue((np_boxes == np_boxes).all())
  127. # to
  128. new_boxes = boxes.to(torch.uint8)
  129. self.assertEqual(new_boxes.tensor.dtype, torch.uint8)
  130. if torch.cuda.is_available():
  131. new_boxes = boxes.to(device='cuda')
  132. self.assertTrue(new_boxes.tensor.is_cuda)
  133. # cpu
  134. if torch.cuda.is_available():
  135. new_boxes = boxes.to(device='cuda')
  136. new_boxes = new_boxes.cpu()
  137. self.assertFalse(new_boxes.tensor.is_cuda)
  138. # cuda
  139. if torch.cuda.is_available():
  140. new_boxes = boxes.cuda()
  141. self.assertTrue(new_boxes.tensor.is_cuda)
  142. # clone
  143. boxes.clone()
  144. # detach
  145. boxes.detach()
  146. # view
  147. new_boxes = boxes.view(12, 4)
  148. self.assertEqual(tuple(new_boxes.size()), (12, 4))
  149. new_boxes = boxes.view(-1, 4)
  150. self.assertEqual(tuple(new_boxes.size()), (12, 4))
  151. with self.assertRaises(AssertionError):
  152. new_boxes = boxes.view(-1)
  153. # reshape
  154. new_boxes = boxes.reshape(12, 4)
  155. self.assertEqual(tuple(new_boxes.size()), (12, 4))
  156. new_boxes = boxes.reshape(-1, 4)
  157. self.assertEqual(tuple(new_boxes.size()), (12, 4))
  158. with self.assertRaises(AssertionError):
  159. new_boxes = boxes.reshape(-1)
  160. # expand
  161. new_boxes = boxes[None, ...].expand(4, -1, -1, -1)
  162. self.assertEqual(tuple(new_boxes.size()), (4, 3, 4, 4))
  163. # repeat
  164. new_boxes = boxes.repeat(2, 2, 1)
  165. self.assertEqual(tuple(new_boxes.size()), (6, 8, 4))
  166. with self.assertRaises(AssertionError):
  167. new_boxes = boxes.repeat(2, 2, 2)
  168. # transpose
  169. new_boxes = boxes.transpose(0, 1)
  170. self.assertEqual(tuple(new_boxes.size()), (4, 3, 4))
  171. with self.assertRaises(AssertionError):
  172. new_boxes = boxes.transpose(1, 2)
  173. # permute
  174. new_boxes = boxes.permute(1, 0, 2)
  175. self.assertEqual(tuple(new_boxes.size()), (4, 3, 4))
  176. with self.assertRaises(AssertionError):
  177. new_boxes = boxes.permute(2, 1, 0)
  178. # split
  179. boxes_list = boxes.split(1, dim=0)
  180. for box in boxes_list:
  181. self.assertIsInstance(box, ToyBaseBoxes)
  182. self.assertEqual(tuple(box.size()), (1, 4, 4))
  183. boxes_list = boxes.split([1, 2], dim=0)
  184. with self.assertRaises(AssertionError):
  185. boxes_list = boxes.split(1, dim=2)
  186. # chunk
  187. boxes_list = boxes.split(3, dim=1)
  188. self.assertEqual(len(boxes_list), 2)
  189. for box in boxes_list:
  190. self.assertIsInstance(box, ToyBaseBoxes)
  191. with self.assertRaises(AssertionError):
  192. boxes_list = boxes.split(3, dim=2)
  193. # unbind
  194. boxes_list = boxes.unbind(dim=1)
  195. self.assertEqual(len(boxes_list), 4)
  196. for box in boxes_list:
  197. self.assertIsInstance(box, ToyBaseBoxes)
  198. self.assertEqual(tuple(box.size()), (3, 4))
  199. with self.assertRaises(AssertionError):
  200. boxes_list = boxes.unbind(dim=2)
  201. # flatten
  202. new_boxes = boxes.flatten()
  203. self.assertEqual(tuple(new_boxes.size()), (12, 4))
  204. with self.assertRaises(AssertionError):
  205. new_boxes = boxes.flatten(end_dim=2)
  206. # squeeze
  207. boxes = ToyBaseBoxes(torch.rand(1, 3, 1, 4, 4))
  208. new_boxes = boxes.squeeze()
  209. self.assertEqual(tuple(new_boxes.size()), (3, 4, 4))
  210. new_boxes = boxes.squeeze(dim=2)
  211. self.assertEqual(tuple(new_boxes.size()), (1, 3, 4, 4))
  212. # unsqueeze
  213. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  214. new_boxes = boxes.unsqueeze(0)
  215. self.assertEqual(tuple(new_boxes.size()), (1, 3, 4, 4))
  216. with self.assertRaises(AssertionError):
  217. new_boxes = boxes.unsqueeze(3)
  218. # cat
  219. with self.assertRaises(ValueError):
  220. ToyBaseBoxes.cat([])
  221. box_list = []
  222. box_list.append(ToyBaseBoxes(torch.rand(3, 4, 4)))
  223. box_list.append(ToyBaseBoxes(torch.rand(1, 4, 4)))
  224. with self.assertRaises(AssertionError):
  225. ToyBaseBoxes.cat(box_list, dim=2)
  226. cat_boxes = ToyBaseBoxes.cat(box_list, dim=0)
  227. self.assertIsInstance(cat_boxes, ToyBaseBoxes)
  228. self.assertEqual((cat_boxes.size()), (4, 4, 4))
  229. # stack
  230. with self.assertRaises(ValueError):
  231. ToyBaseBoxes.stack([])
  232. box_list = []
  233. box_list.append(ToyBaseBoxes(torch.rand(3, 4, 4)))
  234. box_list.append(ToyBaseBoxes(torch.rand(3, 4, 4)))
  235. with self.assertRaises(AssertionError):
  236. ToyBaseBoxes.stack(box_list, dim=3)
  237. stack_boxes = ToyBaseBoxes.stack(box_list, dim=1)
  238. self.assertIsInstance(stack_boxes, ToyBaseBoxes)
  239. self.assertEqual((stack_boxes.size()), (3, 2, 4, 4))
  240. def test_misc(self):
  241. boxes = ToyBaseBoxes(torch.rand(3, 4, 4))
  242. # __len__
  243. self.assertEqual(len(boxes), 3)
  244. # __repr__
  245. repr(boxes)
  246. # fake_boxes
  247. new_boxes = boxes.fake_boxes((3, 4, 4), 1)
  248. self.assertEqual(tuple(new_boxes.size()), (3, 4, 4))
  249. self.assertEqual(boxes.dtype, new_boxes.dtype)
  250. self.assertEqual(boxes.device, new_boxes.device)
  251. self.assertTrue((new_boxes.tensor == 1).all())
  252. with self.assertRaises(AssertionError):
  253. new_boxes = boxes.fake_boxes((3, 4, 1))
  254. new_boxes = boxes.fake_boxes((3, 4, 4), dtype=torch.uint8)
  255. self.assertEqual(new_boxes.dtype, torch.uint8)
  256. if torch.cuda.is_available():
  257. new_boxes = boxes.fake_boxes((3, 4, 4), device='cuda')
  258. self.assertTrue(new_boxes.tensor.is_cuda)