def testOneClassVsMultiClass(self): # Check running on all 3 classes versus each independently. bboxes_3d, class_scores = self._GetData() num_classes = 3 max_boxes_per_class = 5 with self.session() as sess: bbox_indices, bbox_scores, valid_mask = ops.non_max_suppression_3d( bboxes_3d, class_scores, nms_iou_threshold=[0.1, 0.1, 0.1], score_threshold=[0.3, 0.3, 0.3], max_boxes_per_class=max_boxes_per_class) multiclass_indices, multiclass_scores, multiclass_valid_mask = sess.run( [bbox_indices, bbox_scores, valid_mask]) self.assertEqual(multiclass_indices.shape, (num_classes, max_boxes_per_class)) self.assertEqual(multiclass_scores.shape, (num_classes, max_boxes_per_class)) self.assertEqual(multiclass_valid_mask.shape, (num_classes, max_boxes_per_class)) # For each class, get results for just that class and compare. for cls_idx in range(num_classes): bbox_idx, bbox_scores, valid_mask = ops.non_max_suppression_3d( bboxes_3d, class_scores[:, cls_idx:cls_idx + 1], nms_iou_threshold=[0.1], score_threshold=[0.3], max_boxes_per_class=max_boxes_per_class) per_class_indices, per_class_scores, per_class_valid_mask = sess.run( [bbox_idx, bbox_scores, valid_mask]) self.assertEqual(per_class_indices.shape, (1, max_boxes_per_class)) self.assertEqual(per_class_scores.shape, (1, max_boxes_per_class)) self.assertEqual(per_class_valid_mask.shape, (1, max_boxes_per_class)) per_class_mask = per_class_valid_mask[0, :].astype(np.bool) multiclass_mask = multiclass_valid_mask[cls_idx, :].astype( np.bool) self.assertAllEqual( per_class_indices[0, per_class_mask], multiclass_indices[cls_idx, multiclass_mask]) self.assertAllEqual( per_class_scores[0, per_class_mask], multiclass_scores[cls_idx, multiclass_mask])
def _TestNMSOp(self, bboxes_3d, class_scores, nms_iou_threshold, score_threshold, max_boxes_per_class, expected_indices): with self.session() as sess: bbox_indices, bbox_scores, valid_mask = ops.non_max_suppression_3d( bboxes_3d, class_scores, nms_iou_threshold=nms_iou_threshold, score_threshold=score_threshold, max_boxes_per_class=max_boxes_per_class) bbox_idx, scores, mask = sess.run( [bbox_indices, bbox_scores, valid_mask]) num_classes = len(expected_indices) expected_shape = (num_classes, max_boxes_per_class) self.assertEqual(bbox_idx.shape, expected_shape) self.assertEqual(scores.shape, expected_shape) self.assertEqual(mask.shape, expected_shape) total_expected_valid_boxes = sum( [len(exp) for exp in expected_indices]) self.assertEqual(mask.sum(), total_expected_valid_boxes) for cls_idx in range(num_classes): cls_mask = mask[cls_idx, :].astype(np.bool) self.assertEqual(cls_mask.sum(), len(expected_indices[cls_idx])) self.assertAllEqual(bbox_idx[cls_idx, cls_mask], expected_indices[cls_idx])
def NMSBody(args): per_sample_bboxes, per_sample_scores = args indices, scores, mask = ops.non_max_suppression_3d( per_sample_bboxes, per_sample_scores, nms_iou_threshold=nms_iou_threshold, score_threshold=score_threshold, max_boxes_per_class=max_boxes_per_class) return indices, scores, mask
def testSpeed(self): num_bboxes_list = [500, 1000, 10000] num_classes_list = [3, 10, 25] for num_bboxes in num_bboxes_list: for num_classes in num_classes_list: bboxes_3d = tf.random.uniform((num_bboxes, 7), minval=0.1, maxval=2, dtype=tf.float32) # Make half zero so we can see behavior with very low values that # will get filtered out quickly. class_scores = tf.concat([ tf.random.uniform((num_bboxes // 2, num_classes), minval=0, maxval=1, dtype=tf.float32), tf.zeros((num_bboxes // 2, num_classes), dtype=tf.float32) ], axis=0) with self.session() as sess: outputs = ops.non_max_suppression_3d( bboxes_3d, class_scores, max_boxes_per_class=1000, nms_iou_threshold=[0.1] * num_classes, score_threshold=[0.3] * num_classes) timings = [] for _ in range(10): start = time.time() _ = sess.run(outputs) end = time.time() timings.append(end - start) avg = sum(timings) / len(timings) print('[{},{},{},{},{}]'.format(num_bboxes, num_classes, min(timings), avg, max(timings)))