test_ops.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  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 paddlex.ppdet.modeling.ops as ops
  24. from paddlex.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 TestDistributeFpnProposals(LayerTest):
  42. def test_distribute_fpn_proposals(self):
  43. rois_np = np.random.rand(10, 4).astype('float32')
  44. rois_num_np = np.array([4, 6]).astype('int32')
  45. with self.static_graph():
  46. rois = paddle.static.data(
  47. name='rois', shape=[10, 4], dtype='float32')
  48. rois_num = paddle.static.data(
  49. name='rois_num', shape=[None], dtype='int32')
  50. multi_rois, restore_ind, rois_num_per_level = ops.distribute_fpn_proposals(
  51. fpn_rois=rois,
  52. min_level=2,
  53. max_level=5,
  54. refer_level=4,
  55. refer_scale=224,
  56. rois_num=rois_num)
  57. fetch_list = multi_rois + [restore_ind] + rois_num_per_level
  58. output_stat = self.get_static_graph_result(
  59. feed={'rois': rois_np,
  60. 'rois_num': rois_num_np},
  61. fetch_list=fetch_list,
  62. with_lod=True)
  63. output_stat_np = []
  64. for output in output_stat:
  65. output_np = np.array(output)
  66. if len(output_np) > 0:
  67. output_stat_np.append(output_np)
  68. with self.dynamic_graph():
  69. rois_dy = paddle.to_tensor(rois_np)
  70. rois_num_dy = paddle.to_tensor(rois_num_np)
  71. multi_rois_dy, restore_ind_dy, rois_num_per_level_dy = ops.distribute_fpn_proposals(
  72. fpn_rois=rois_dy,
  73. min_level=2,
  74. max_level=5,
  75. refer_level=4,
  76. refer_scale=224,
  77. rois_num=rois_num_dy)
  78. output_dy = multi_rois_dy + [restore_ind_dy
  79. ] + rois_num_per_level_dy
  80. output_dy_np = []
  81. for output in output_dy:
  82. output_np = output.numpy()
  83. if len(output_np) > 0:
  84. output_dy_np.append(output_np)
  85. for res_stat, res_dy in zip(output_stat_np, output_dy_np):
  86. self.assertTrue(np.array_equal(res_stat, res_dy))
  87. def test_distribute_fpn_proposals_error(self):
  88. with self.static_graph():
  89. fpn_rois = paddle.static.data(
  90. name='data_error', shape=[10, 4], dtype='int32', lod_level=1)
  91. self.assertRaises(
  92. TypeError,
  93. ops.distribute_fpn_proposals,
  94. fpn_rois=fpn_rois,
  95. min_level=2,
  96. max_level=5,
  97. refer_level=4,
  98. refer_scale=224)
  99. paddle.disable_static()
  100. class TestROIAlign(LayerTest):
  101. def test_roi_align(self):
  102. b, c, h, w = 2, 12, 20, 20
  103. inputs_np = np.random.rand(b, c, h, w).astype('float32')
  104. rois_num = [4, 6]
  105. output_size = (7, 7)
  106. rois_np = make_rois(h, w, rois_num, output_size)
  107. rois_num_np = np.array(rois_num).astype('int32')
  108. with self.static_graph():
  109. inputs = paddle.static.data(
  110. name='inputs', shape=[b, c, h, w], dtype='float32')
  111. rois = paddle.static.data(
  112. name='rois', shape=[10, 4], dtype='float32')
  113. rois_num = paddle.static.data(
  114. name='rois_num', shape=[None], dtype='int32')
  115. output = ops.roi_align(
  116. input=inputs,
  117. rois=rois,
  118. output_size=output_size,
  119. rois_num=rois_num)
  120. output_np, = self.get_static_graph_result(
  121. feed={
  122. 'inputs': inputs_np,
  123. 'rois': rois_np,
  124. 'rois_num': rois_num_np
  125. },
  126. fetch_list=output,
  127. with_lod=False)
  128. with self.dynamic_graph():
  129. inputs_dy = paddle.to_tensor(inputs_np)
  130. rois_dy = paddle.to_tensor(rois_np)
  131. rois_num_dy = paddle.to_tensor(rois_num_np)
  132. output_dy = ops.roi_align(
  133. input=inputs_dy,
  134. rois=rois_dy,
  135. output_size=output_size,
  136. rois_num=rois_num_dy)
  137. output_dy_np = output_dy.numpy()
  138. self.assertTrue(np.array_equal(output_np, output_dy_np))
  139. def test_roi_align_error(self):
  140. with self.static_graph():
  141. inputs = paddle.static.data(
  142. name='inputs', shape=[2, 12, 20, 20], dtype='float32')
  143. rois = paddle.static.data(
  144. name='data_error', shape=[10, 4], dtype='int32', lod_level=1)
  145. self.assertRaises(
  146. TypeError,
  147. ops.roi_align,
  148. input=inputs,
  149. rois=rois,
  150. output_size=(7, 7))
  151. paddle.disable_static()
  152. class TestROIPool(LayerTest):
  153. def test_roi_pool(self):
  154. b, c, h, w = 2, 12, 20, 20
  155. inputs_np = np.random.rand(b, c, h, w).astype('float32')
  156. rois_num = [4, 6]
  157. output_size = (7, 7)
  158. rois_np = make_rois(h, w, rois_num, output_size)
  159. rois_num_np = np.array(rois_num).astype('int32')
  160. with self.static_graph():
  161. inputs = paddle.static.data(
  162. name='inputs', shape=[b, c, h, w], dtype='float32')
  163. rois = paddle.static.data(
  164. name='rois', shape=[10, 4], dtype='float32')
  165. rois_num = paddle.static.data(
  166. name='rois_num', shape=[None], dtype='int32')
  167. output, _ = ops.roi_pool(
  168. input=inputs,
  169. rois=rois,
  170. output_size=output_size,
  171. rois_num=rois_num)
  172. output_np, = self.get_static_graph_result(
  173. feed={
  174. 'inputs': inputs_np,
  175. 'rois': rois_np,
  176. 'rois_num': rois_num_np
  177. },
  178. fetch_list=[output],
  179. with_lod=False)
  180. with self.dynamic_graph():
  181. inputs_dy = paddle.to_tensor(inputs_np)
  182. rois_dy = paddle.to_tensor(rois_np)
  183. rois_num_dy = paddle.to_tensor(rois_num_np)
  184. output_dy, _ = ops.roi_pool(
  185. input=inputs_dy,
  186. rois=rois_dy,
  187. output_size=output_size,
  188. rois_num=rois_num_dy)
  189. output_dy_np = output_dy.numpy()
  190. self.assertTrue(np.array_equal(output_np, output_dy_np))
  191. def test_roi_pool_error(self):
  192. with self.static_graph():
  193. inputs = paddle.static.data(
  194. name='inputs', shape=[2, 12, 20, 20], dtype='float32')
  195. rois = paddle.static.data(
  196. name='data_error', shape=[10, 4], dtype='int32', lod_level=1)
  197. self.assertRaises(
  198. TypeError,
  199. ops.roi_pool,
  200. input=inputs,
  201. rois=rois,
  202. output_size=(7, 7))
  203. paddle.disable_static()
  204. class TestPriorBox(LayerTest):
  205. def test_prior_box(self):
  206. input_np = np.random.rand(2, 10, 32, 32).astype('float32')
  207. image_np = np.random.rand(2, 10, 40, 40).astype('float32')
  208. min_sizes = [2, 4]
  209. with self.static_graph():
  210. input = paddle.static.data(
  211. name='input', shape=[2, 10, 32, 32], dtype='float32')
  212. image = paddle.static.data(
  213. name='image', shape=[2, 10, 40, 40], dtype='float32')
  214. box, var = ops.prior_box(
  215. input=input,
  216. image=image,
  217. min_sizes=min_sizes,
  218. clip=True,
  219. flip=True)
  220. box_np, var_np = self.get_static_graph_result(
  221. feed={
  222. 'input': input_np,
  223. 'image': image_np,
  224. },
  225. fetch_list=[box, var],
  226. with_lod=False)
  227. with self.dynamic_graph():
  228. inputs_dy = paddle.to_tensor(input_np)
  229. image_dy = paddle.to_tensor(image_np)
  230. box_dy, var_dy = ops.prior_box(
  231. input=inputs_dy,
  232. image=image_dy,
  233. min_sizes=min_sizes,
  234. clip=True,
  235. flip=True)
  236. box_dy_np = box_dy.numpy()
  237. var_dy_np = var_dy.numpy()
  238. self.assertTrue(np.array_equal(box_np, box_dy_np))
  239. self.assertTrue(np.array_equal(var_np, var_dy_np))
  240. def test_prior_box_error(self):
  241. with self.static_graph():
  242. input = paddle.static.data(
  243. name='input', shape=[2, 10, 32, 32], dtype='int32')
  244. image = paddle.static.data(
  245. name='image', shape=[2, 10, 40, 40], dtype='int32')
  246. self.assertRaises(
  247. TypeError,
  248. ops.prior_box,
  249. input=input,
  250. image=image,
  251. min_sizes=[2, 4],
  252. clip=True,
  253. flip=True)
  254. paddle.disable_static()
  255. class TestMulticlassNms(LayerTest):
  256. def test_multiclass_nms(self):
  257. boxes_np = np.random.rand(10, 81, 4).astype('float32')
  258. scores_np = np.random.rand(10, 81).astype('float32')
  259. rois_num_np = np.array([2, 8]).astype('int32')
  260. with self.static_graph():
  261. boxes = paddle.static.data(
  262. name='bboxes',
  263. shape=[None, 81, 4],
  264. dtype='float32',
  265. lod_level=1)
  266. scores = paddle.static.data(
  267. name='scores', shape=[None, 81], dtype='float32', lod_level=1)
  268. rois_num = paddle.static.data(
  269. name='rois_num', shape=[None], dtype='int32')
  270. output = ops.multiclass_nms(
  271. bboxes=boxes,
  272. scores=scores,
  273. background_label=0,
  274. score_threshold=0.5,
  275. nms_top_k=400,
  276. nms_threshold=0.3,
  277. keep_top_k=200,
  278. normalized=False,
  279. return_index=True,
  280. rois_num=rois_num)
  281. out_np, index_np, nms_rois_num_np = self.get_static_graph_result(
  282. feed={
  283. 'bboxes': boxes_np,
  284. 'scores': scores_np,
  285. 'rois_num': rois_num_np
  286. },
  287. fetch_list=output,
  288. with_lod=True)
  289. out_np = np.array(out_np)
  290. index_np = np.array(index_np)
  291. nms_rois_num_np = np.array(nms_rois_num_np)
  292. with self.dynamic_graph():
  293. boxes_dy = paddle.to_tensor(boxes_np)
  294. scores_dy = paddle.to_tensor(scores_np)
  295. rois_num_dy = paddle.to_tensor(rois_num_np)
  296. out_dy, index_dy, nms_rois_num_dy = ops.multiclass_nms(
  297. bboxes=boxes_dy,
  298. scores=scores_dy,
  299. background_label=0,
  300. score_threshold=0.5,
  301. nms_top_k=400,
  302. nms_threshold=0.3,
  303. keep_top_k=200,
  304. normalized=False,
  305. return_index=True,
  306. rois_num=rois_num_dy)
  307. out_dy_np = out_dy.numpy()
  308. index_dy_np = index_dy.numpy()
  309. nms_rois_num_dy_np = nms_rois_num_dy.numpy()
  310. self.assertTrue(np.array_equal(out_np, out_dy_np))
  311. self.assertTrue(np.array_equal(index_np, index_dy_np))
  312. self.assertTrue(np.array_equal(nms_rois_num_np, nms_rois_num_dy_np))
  313. def test_multiclass_nms_error(self):
  314. with self.static_graph():
  315. boxes = paddle.static.data(
  316. name='bboxes', shape=[81, 4], dtype='float32', lod_level=1)
  317. scores = paddle.static.data(
  318. name='scores', shape=[81], dtype='float32', lod_level=1)
  319. rois_num = paddle.static.data(
  320. name='rois_num', shape=[40, 41], dtype='int32')
  321. self.assertRaises(
  322. TypeError,
  323. ops.multiclass_nms,
  324. boxes=boxes,
  325. scores=scores,
  326. background_label=0,
  327. score_threshold=0.5,
  328. nms_top_k=400,
  329. nms_threshold=0.3,
  330. keep_top_k=200,
  331. normalized=False,
  332. return_index=True,
  333. rois_num=rois_num)
  334. class TestMatrixNMS(LayerTest):
  335. def test_matrix_nms(self):
  336. N, M, C = 7, 1200, 21
  337. BOX_SIZE = 4
  338. nms_top_k = 400
  339. keep_top_k = 200
  340. score_threshold = 0.01
  341. post_threshold = 0.
  342. scores_np = np.random.random((N * M, C)).astype('float32')
  343. scores_np = np.apply_along_axis(softmax, 1, scores_np)
  344. scores_np = np.reshape(scores_np, (N, M, C))
  345. scores_np = np.transpose(scores_np, (0, 2, 1))
  346. boxes_np = np.random.random((N, M, BOX_SIZE)).astype('float32')
  347. boxes_np[:, :, 0:2] = boxes_np[:, :, 0:2] * 0.5
  348. boxes_np[:, :, 2:4] = boxes_np[:, :, 2:4] * 0.5 + 0.5
  349. with self.static_graph():
  350. boxes = paddle.static.data(
  351. name='boxes', shape=[N, M, BOX_SIZE], dtype='float32')
  352. scores = paddle.static.data(
  353. name='scores', shape=[N, C, M], dtype='float32')
  354. out, index, _ = ops.matrix_nms(
  355. bboxes=boxes,
  356. scores=scores,
  357. score_threshold=score_threshold,
  358. post_threshold=post_threshold,
  359. nms_top_k=nms_top_k,
  360. keep_top_k=keep_top_k,
  361. return_index=True)
  362. out_np, index_np = self.get_static_graph_result(
  363. feed={'boxes': boxes_np,
  364. 'scores': scores_np},
  365. fetch_list=[out, index],
  366. with_lod=True)
  367. with self.dynamic_graph():
  368. boxes_dy = paddle.to_tensor(boxes_np)
  369. scores_dy = paddle.to_tensor(scores_np)
  370. out_dy, index_dy, _ = ops.matrix_nms(
  371. bboxes=boxes_dy,
  372. scores=scores_dy,
  373. score_threshold=score_threshold,
  374. post_threshold=post_threshold,
  375. nms_top_k=nms_top_k,
  376. keep_top_k=keep_top_k,
  377. return_index=True)
  378. out_dy_np = out_dy.numpy()
  379. index_dy_np = index_dy.numpy()
  380. self.assertTrue(np.array_equal(out_np, out_dy_np))
  381. self.assertTrue(np.array_equal(index_np, index_dy_np))
  382. def test_matrix_nms_error(self):
  383. with self.static_graph():
  384. bboxes = paddle.static.data(
  385. name='bboxes', shape=[7, 1200, 4], dtype='float32')
  386. scores = paddle.static.data(
  387. name='data_error', shape=[7, 21, 1200], dtype='int32')
  388. self.assertRaises(
  389. TypeError,
  390. ops.matrix_nms,
  391. bboxes=bboxes,
  392. scores=scores,
  393. score_threshold=0.01,
  394. post_threshold=0.,
  395. nms_top_k=400,
  396. keep_top_k=200,
  397. return_index=True)
  398. paddle.disable_static()
  399. class TestBoxCoder(LayerTest):
  400. def test_box_coder(self):
  401. prior_box_np = np.random.random((81, 4)).astype('float32')
  402. prior_box_var_np = np.random.random((81, 4)).astype('float32')
  403. target_box_np = np.random.random((20, 81, 4)).astype('float32')
  404. # static
  405. with self.static_graph():
  406. prior_box = paddle.static.data(
  407. name='prior_box', shape=[81, 4], dtype='float32')
  408. prior_box_var = paddle.static.data(
  409. name='prior_box_var', shape=[81, 4], dtype='float32')
  410. target_box = paddle.static.data(
  411. name='target_box', shape=[20, 81, 4], dtype='float32')
  412. boxes = ops.box_coder(
  413. prior_box=prior_box,
  414. prior_box_var=prior_box_var,
  415. target_box=target_box,
  416. code_type="decode_center_size",
  417. box_normalized=False)
  418. boxes_np, = self.get_static_graph_result(
  419. feed={
  420. 'prior_box': prior_box_np,
  421. 'prior_box_var': prior_box_var_np,
  422. 'target_box': target_box_np,
  423. },
  424. fetch_list=[boxes],
  425. with_lod=False)
  426. # dygraph
  427. with self.dynamic_graph():
  428. prior_box_dy = paddle.to_tensor(prior_box_np)
  429. prior_box_var_dy = paddle.to_tensor(prior_box_var_np)
  430. target_box_dy = paddle.to_tensor(target_box_np)
  431. boxes_dy = ops.box_coder(
  432. prior_box=prior_box_dy,
  433. prior_box_var=prior_box_var_dy,
  434. target_box=target_box_dy,
  435. code_type="decode_center_size",
  436. box_normalized=False)
  437. boxes_dy_np = boxes_dy.numpy()
  438. self.assertTrue(np.array_equal(boxes_np, boxes_dy_np))
  439. def test_box_coder_error(self):
  440. with self.static_graph():
  441. prior_box = paddle.static.data(
  442. name='prior_box', shape=[81, 4], dtype='int32')
  443. prior_box_var = paddle.static.data(
  444. name='prior_box_var', shape=[81, 4], dtype='float32')
  445. target_box = paddle.static.data(
  446. name='target_box', shape=[20, 81, 4], dtype='float32')
  447. self.assertRaises(TypeError, ops.box_coder, prior_box,
  448. prior_box_var, target_box)
  449. paddle.disable_static()
  450. class TestGenerateProposals(LayerTest):
  451. def test_generate_proposals(self):
  452. scores_np = np.random.rand(2, 3, 4, 4).astype('float32')
  453. bbox_deltas_np = np.random.rand(2, 12, 4, 4).astype('float32')
  454. im_shape_np = np.array([[8, 8], [6, 6]]).astype('float32')
  455. anchors_np = np.reshape(np.arange(4 * 4 * 3 * 4),
  456. [4, 4, 3, 4]).astype('float32')
  457. variances_np = np.ones((4, 4, 3, 4)).astype('float32')
  458. with self.static_graph():
  459. scores = paddle.static.data(
  460. name='scores', shape=[2, 3, 4, 4], dtype='float32')
  461. bbox_deltas = paddle.static.data(
  462. name='bbox_deltas', shape=[2, 12, 4, 4], dtype='float32')
  463. im_shape = paddle.static.data(
  464. name='im_shape', shape=[2, 2], dtype='float32')
  465. anchors = paddle.static.data(
  466. name='anchors', shape=[4, 4, 3, 4], dtype='float32')
  467. variances = paddle.static.data(
  468. name='var', shape=[4, 4, 3, 4], dtype='float32')
  469. rois, roi_probs, rois_num = ops.generate_proposals(
  470. scores,
  471. bbox_deltas,
  472. im_shape,
  473. anchors,
  474. variances,
  475. pre_nms_top_n=10,
  476. post_nms_top_n=5,
  477. return_rois_num=True)
  478. rois_stat, roi_probs_stat, rois_num_stat = self.get_static_graph_result(
  479. feed={
  480. 'scores': scores_np,
  481. 'bbox_deltas': bbox_deltas_np,
  482. 'im_shape': im_shape_np,
  483. 'anchors': anchors_np,
  484. 'var': variances_np
  485. },
  486. fetch_list=[rois, roi_probs, rois_num],
  487. with_lod=True)
  488. with self.dynamic_graph():
  489. scores_dy = paddle.to_tensor(scores_np)
  490. bbox_deltas_dy = paddle.to_tensor(bbox_deltas_np)
  491. im_shape_dy = paddle.to_tensor(im_shape_np)
  492. anchors_dy = paddle.to_tensor(anchors_np)
  493. variances_dy = paddle.to_tensor(variances_np)
  494. rois, roi_probs, rois_num = ops.generate_proposals(
  495. scores_dy,
  496. bbox_deltas_dy,
  497. im_shape_dy,
  498. anchors_dy,
  499. variances_dy,
  500. pre_nms_top_n=10,
  501. post_nms_top_n=5,
  502. return_rois_num=True)
  503. rois_dy = rois.numpy()
  504. roi_probs_dy = roi_probs.numpy()
  505. rois_num_dy = rois_num.numpy()
  506. self.assertTrue(np.array_equal(np.array(rois_stat), rois_dy))
  507. self.assertTrue(np.array_equal(np.array(roi_probs_stat), roi_probs_dy))
  508. self.assertTrue(np.array_equal(np.array(rois_num_stat), rois_num_dy))
  509. if __name__ == '__main__':
  510. unittest.main()