test_ops.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from __future__ import print_function
  15. import os, sys
  16. # add python path of PadleDetection to sys.path
  17. parent_path = os.path.abspath(os.path.join(__file__, *(['..'] * 4)))
  18. if parent_path not in sys.path:
  19. sys.path.append(parent_path)
  20. import unittest
  21. import numpy as np
  22. import paddle
  23. import ppdet.modeling.ops as ops
  24. from ppdet.modeling.tests.test_base import LayerTest
  25. def make_rois(h, w, rois_num, output_size):
  26. rois = np.zeros((0, 4)).astype('float32')
  27. for roi_num in rois_num:
  28. roi = np.zeros((roi_num, 4)).astype('float32')
  29. roi[:, 0] = np.random.randint(0, h - output_size[0], size=roi_num)
  30. roi[:, 1] = np.random.randint(0, w - output_size[1], size=roi_num)
  31. roi[:, 2] = np.random.randint(roi[:, 0] + output_size[0], h)
  32. roi[:, 3] = np.random.randint(roi[:, 1] + output_size[1], w)
  33. rois = np.vstack((rois, roi))
  34. return rois
  35. def softmax(x):
  36. # clip to shiftx, otherwise, when calc loss with
  37. # log(exp(shiftx)), may get log(0)=INF
  38. shiftx = (x - np.max(x)).clip(-64.)
  39. exps = np.exp(shiftx)
  40. return exps / np.sum(exps)
  41. class TestROIAlign(LayerTest):
  42. def test_roi_align(self):
  43. b, c, h, w = 2, 12, 20, 20
  44. inputs_np = np.random.rand(b, c, h, w).astype('float32')
  45. rois_num = [4, 6]
  46. output_size = (7, 7)
  47. rois_np = make_rois(h, w, rois_num, output_size)
  48. rois_num_np = np.array(rois_num).astype('int32')
  49. with self.static_graph():
  50. inputs = paddle.static.data(
  51. name='inputs', shape=[b, c, h, w], dtype='float32')
  52. rois = paddle.static.data(
  53. name='rois', shape=[10, 4], dtype='float32')
  54. rois_num = paddle.static.data(
  55. name='rois_num', shape=[None], dtype='int32')
  56. output = paddle.vision.ops.roi_align(
  57. x=inputs,
  58. boxes=rois,
  59. boxes_num=rois_num,
  60. output_size=output_size)
  61. output_np, = self.get_static_graph_result(
  62. feed={
  63. 'inputs': inputs_np,
  64. 'rois': rois_np,
  65. 'rois_num': rois_num_np
  66. },
  67. fetch_list=output,
  68. with_lod=False)
  69. with self.dynamic_graph():
  70. inputs_dy = paddle.to_tensor(inputs_np)
  71. rois_dy = paddle.to_tensor(rois_np)
  72. rois_num_dy = paddle.to_tensor(rois_num_np)
  73. output_dy = paddle.vision.ops.roi_align(
  74. x=inputs_dy,
  75. boxes=rois_dy,
  76. boxes_num=rois_num_dy,
  77. output_size=output_size)
  78. output_dy_np = output_dy.numpy()
  79. self.assertTrue(np.array_equal(output_np, output_dy_np))
  80. def test_roi_align_error(self):
  81. with self.static_graph():
  82. inputs = paddle.static.data(
  83. name='inputs', shape=[2, 12, 20, 20], dtype='float32')
  84. rois = paddle.static.data(
  85. name='data_error', shape=[10, 4], dtype='int32', lod_level=1)
  86. self.assertRaises(
  87. TypeError,
  88. paddle.vision.ops.roi_align,
  89. input=inputs,
  90. rois=rois,
  91. output_size=(7, 7))
  92. paddle.disable_static()
  93. class TestROIPool(LayerTest):
  94. def test_roi_pool(self):
  95. b, c, h, w = 2, 12, 20, 20
  96. inputs_np = np.random.rand(b, c, h, w).astype('float32')
  97. rois_num = [4, 6]
  98. output_size = (7, 7)
  99. rois_np = make_rois(h, w, rois_num, output_size)
  100. rois_num_np = np.array(rois_num).astype('int32')
  101. with self.static_graph():
  102. inputs = paddle.static.data(
  103. name='inputs', shape=[b, c, h, w], dtype='float32')
  104. rois = paddle.static.data(
  105. name='rois', shape=[10, 4], dtype='float32')
  106. rois_num = paddle.static.data(
  107. name='rois_num', shape=[None], dtype='int32')
  108. output = paddle.vision.ops.roi_pool(
  109. x=inputs,
  110. boxes=rois,
  111. boxes_num=rois_num,
  112. output_size=output_size)
  113. output_np, = self.get_static_graph_result(
  114. feed={
  115. 'inputs': inputs_np,
  116. 'rois': rois_np,
  117. 'rois_num': rois_num_np
  118. },
  119. fetch_list=[output],
  120. with_lod=False)
  121. with self.dynamic_graph():
  122. inputs_dy = paddle.to_tensor(inputs_np)
  123. rois_dy = paddle.to_tensor(rois_np)
  124. rois_num_dy = paddle.to_tensor(rois_num_np)
  125. output_dy = paddle.vision.ops.roi_pool(
  126. x=inputs_dy,
  127. boxes=rois_dy,
  128. boxes_num=rois_num_dy,
  129. output_size=output_size)
  130. output_dy_np = output_dy.numpy()
  131. self.assertTrue(np.array_equal(output_np, output_dy_np))
  132. def test_roi_pool_error(self):
  133. with self.static_graph():
  134. inputs = paddle.static.data(
  135. name='inputs', shape=[2, 12, 20, 20], dtype='float32')
  136. rois = paddle.static.data(
  137. name='data_error', shape=[10, 4], dtype='int32', lod_level=1)
  138. self.assertRaises(
  139. TypeError,
  140. paddle.vision.ops.roi_pool,
  141. input=inputs,
  142. rois=rois,
  143. output_size=(7, 7))
  144. paddle.disable_static()
  145. class TestPriorBox(LayerTest):
  146. def test_prior_box(self):
  147. input_np = np.random.rand(2, 10, 32, 32).astype('float32')
  148. image_np = np.random.rand(2, 10, 40, 40).astype('float32')
  149. min_sizes = [2, 4]
  150. with self.static_graph():
  151. input = paddle.static.data(
  152. name='input', shape=[2, 10, 32, 32], dtype='float32')
  153. image = paddle.static.data(
  154. name='image', shape=[2, 10, 40, 40], dtype='float32')
  155. box, var = ops.prior_box(
  156. input=input,
  157. image=image,
  158. min_sizes=min_sizes,
  159. clip=True,
  160. flip=True)
  161. box_np, var_np = self.get_static_graph_result(
  162. feed={
  163. 'input': input_np,
  164. 'image': image_np,
  165. },
  166. fetch_list=[box, var],
  167. with_lod=False)
  168. with self.dynamic_graph():
  169. inputs_dy = paddle.to_tensor(input_np)
  170. image_dy = paddle.to_tensor(image_np)
  171. box_dy, var_dy = ops.prior_box(
  172. input=inputs_dy,
  173. image=image_dy,
  174. min_sizes=min_sizes,
  175. clip=True,
  176. flip=True)
  177. box_dy_np = box_dy.numpy()
  178. var_dy_np = var_dy.numpy()
  179. self.assertTrue(np.array_equal(box_np, box_dy_np))
  180. self.assertTrue(np.array_equal(var_np, var_dy_np))
  181. def test_prior_box_error(self):
  182. with self.static_graph():
  183. input = paddle.static.data(
  184. name='input', shape=[2, 10, 32, 32], dtype='int32')
  185. image = paddle.static.data(
  186. name='image', shape=[2, 10, 40, 40], dtype='int32')
  187. self.assertRaises(
  188. TypeError,
  189. ops.prior_box,
  190. input=input,
  191. image=image,
  192. min_sizes=[2, 4],
  193. clip=True,
  194. flip=True)
  195. paddle.disable_static()
  196. class TestMulticlassNms(LayerTest):
  197. def test_multiclass_nms(self):
  198. boxes_np = np.random.rand(10, 81, 4).astype('float32')
  199. scores_np = np.random.rand(10, 81).astype('float32')
  200. rois_num_np = np.array([2, 8]).astype('int32')
  201. with self.static_graph():
  202. boxes = paddle.static.data(
  203. name='bboxes',
  204. shape=[None, 81, 4],
  205. dtype='float32',
  206. lod_level=1)
  207. scores = paddle.static.data(
  208. name='scores', shape=[None, 81], dtype='float32', lod_level=1)
  209. rois_num = paddle.static.data(
  210. name='rois_num', shape=[None], dtype='int32')
  211. output = ops.multiclass_nms(
  212. bboxes=boxes,
  213. scores=scores,
  214. background_label=0,
  215. score_threshold=0.5,
  216. nms_top_k=400,
  217. nms_threshold=0.3,
  218. keep_top_k=200,
  219. normalized=False,
  220. return_index=True,
  221. rois_num=rois_num)
  222. out_np, index_np, nms_rois_num_np = self.get_static_graph_result(
  223. feed={
  224. 'bboxes': boxes_np,
  225. 'scores': scores_np,
  226. 'rois_num': rois_num_np
  227. },
  228. fetch_list=output,
  229. with_lod=True)
  230. out_np = np.array(out_np)
  231. index_np = np.array(index_np)
  232. nms_rois_num_np = np.array(nms_rois_num_np)
  233. with self.dynamic_graph():
  234. boxes_dy = paddle.to_tensor(boxes_np)
  235. scores_dy = paddle.to_tensor(scores_np)
  236. rois_num_dy = paddle.to_tensor(rois_num_np)
  237. out_dy, index_dy, nms_rois_num_dy = ops.multiclass_nms(
  238. bboxes=boxes_dy,
  239. scores=scores_dy,
  240. background_label=0,
  241. score_threshold=0.5,
  242. nms_top_k=400,
  243. nms_threshold=0.3,
  244. keep_top_k=200,
  245. normalized=False,
  246. return_index=True,
  247. rois_num=rois_num_dy)
  248. out_dy_np = out_dy.numpy()
  249. index_dy_np = index_dy.numpy()
  250. nms_rois_num_dy_np = nms_rois_num_dy.numpy()
  251. self.assertTrue(np.array_equal(out_np, out_dy_np))
  252. self.assertTrue(np.array_equal(index_np, index_dy_np))
  253. self.assertTrue(np.array_equal(nms_rois_num_np, nms_rois_num_dy_np))
  254. def test_multiclass_nms_error(self):
  255. with self.static_graph():
  256. boxes = paddle.static.data(
  257. name='bboxes', shape=[81, 4], dtype='float32', lod_level=1)
  258. scores = paddle.static.data(
  259. name='scores', shape=[81], dtype='float32', lod_level=1)
  260. rois_num = paddle.static.data(
  261. name='rois_num', shape=[40, 41], dtype='int32')
  262. self.assertRaises(
  263. TypeError,
  264. ops.multiclass_nms,
  265. boxes=boxes,
  266. scores=scores,
  267. background_label=0,
  268. score_threshold=0.5,
  269. nms_top_k=400,
  270. nms_threshold=0.3,
  271. keep_top_k=200,
  272. normalized=False,
  273. return_index=True,
  274. rois_num=rois_num)
  275. class TestMatrixNMS(LayerTest):
  276. def test_matrix_nms(self):
  277. N, M, C = 7, 1200, 21
  278. BOX_SIZE = 4
  279. nms_top_k = 400
  280. keep_top_k = 200
  281. score_threshold = 0.01
  282. post_threshold = 0.
  283. scores_np = np.random.random((N * M, C)).astype('float32')
  284. scores_np = np.apply_along_axis(softmax, 1, scores_np)
  285. scores_np = np.reshape(scores_np, (N, M, C))
  286. scores_np = np.transpose(scores_np, (0, 2, 1))
  287. boxes_np = np.random.random((N, M, BOX_SIZE)).astype('float32')
  288. boxes_np[:, :, 0:2] = boxes_np[:, :, 0:2] * 0.5
  289. boxes_np[:, :, 2:4] = boxes_np[:, :, 2:4] * 0.5 + 0.5
  290. with self.static_graph():
  291. boxes = paddle.static.data(
  292. name='boxes', shape=[N, M, BOX_SIZE], dtype='float32')
  293. scores = paddle.static.data(
  294. name='scores', shape=[N, C, M], dtype='float32')
  295. out, index, _ = ops.matrix_nms(
  296. bboxes=boxes,
  297. scores=scores,
  298. score_threshold=score_threshold,
  299. post_threshold=post_threshold,
  300. nms_top_k=nms_top_k,
  301. keep_top_k=keep_top_k,
  302. return_index=True)
  303. out_np, index_np = self.get_static_graph_result(
  304. feed={'boxes': boxes_np,
  305. 'scores': scores_np},
  306. fetch_list=[out, index],
  307. with_lod=True)
  308. with self.dynamic_graph():
  309. boxes_dy = paddle.to_tensor(boxes_np)
  310. scores_dy = paddle.to_tensor(scores_np)
  311. out_dy, index_dy, _ = ops.matrix_nms(
  312. bboxes=boxes_dy,
  313. scores=scores_dy,
  314. score_threshold=score_threshold,
  315. post_threshold=post_threshold,
  316. nms_top_k=nms_top_k,
  317. keep_top_k=keep_top_k,
  318. return_index=True)
  319. out_dy_np = out_dy.numpy()
  320. index_dy_np = index_dy.numpy()
  321. self.assertTrue(np.array_equal(out_np, out_dy_np))
  322. self.assertTrue(np.array_equal(index_np, index_dy_np))
  323. def test_matrix_nms_error(self):
  324. with self.static_graph():
  325. bboxes = paddle.static.data(
  326. name='bboxes', shape=[7, 1200, 4], dtype='float32')
  327. scores = paddle.static.data(
  328. name='data_error', shape=[7, 21, 1200], dtype='int32')
  329. self.assertRaises(
  330. TypeError,
  331. ops.matrix_nms,
  332. bboxes=bboxes,
  333. scores=scores,
  334. score_threshold=0.01,
  335. post_threshold=0.,
  336. nms_top_k=400,
  337. keep_top_k=200,
  338. return_index=True)
  339. paddle.disable_static()
  340. class TestBoxCoder(LayerTest):
  341. def test_box_coder(self):
  342. prior_box_np = np.random.random((81, 4)).astype('float32')
  343. prior_box_var_np = np.random.random((81, 4)).astype('float32')
  344. target_box_np = np.random.random((20, 81, 4)).astype('float32')
  345. # static
  346. with self.static_graph():
  347. prior_box = paddle.static.data(
  348. name='prior_box', shape=[81, 4], dtype='float32')
  349. prior_box_var = paddle.static.data(
  350. name='prior_box_var', shape=[81, 4], dtype='float32')
  351. target_box = paddle.static.data(
  352. name='target_box', shape=[20, 81, 4], dtype='float32')
  353. boxes = ops.box_coder(
  354. prior_box=prior_box,
  355. prior_box_var=prior_box_var,
  356. target_box=target_box,
  357. code_type="decode_center_size",
  358. box_normalized=False)
  359. boxes_np, = self.get_static_graph_result(
  360. feed={
  361. 'prior_box': prior_box_np,
  362. 'prior_box_var': prior_box_var_np,
  363. 'target_box': target_box_np,
  364. },
  365. fetch_list=[boxes],
  366. with_lod=False)
  367. # dygraph
  368. with self.dynamic_graph():
  369. prior_box_dy = paddle.to_tensor(prior_box_np)
  370. prior_box_var_dy = paddle.to_tensor(prior_box_var_np)
  371. target_box_dy = paddle.to_tensor(target_box_np)
  372. boxes_dy = ops.box_coder(
  373. prior_box=prior_box_dy,
  374. prior_box_var=prior_box_var_dy,
  375. target_box=target_box_dy,
  376. code_type="decode_center_size",
  377. box_normalized=False)
  378. boxes_dy_np = boxes_dy.numpy()
  379. self.assertTrue(np.array_equal(boxes_np, boxes_dy_np))
  380. def test_box_coder_error(self):
  381. with self.static_graph():
  382. prior_box = paddle.static.data(
  383. name='prior_box', shape=[81, 4], dtype='int32')
  384. prior_box_var = paddle.static.data(
  385. name='prior_box_var', shape=[81, 4], dtype='float32')
  386. target_box = paddle.static.data(
  387. name='target_box', shape=[20, 81, 4], dtype='float32')
  388. self.assertRaises(TypeError, ops.box_coder, prior_box,
  389. prior_box_var, target_box)
  390. paddle.disable_static()
  391. if __name__ == '__main__':
  392. unittest.main()