[MO][Opset13] NMSRotated-13 support in MO IR Reader (#20354)
* nms_rotated mo ir read init * Fix type infer and clean up * Update tests * Update tests * update package BOM file * Update type_infer * Avoid files collision in tests --------- Co-authored-by: Michal Lukaszewski <michal.lukaszewski@intel.com>
This commit is contained in:
parent
bc463e886b
commit
daa2c9ded0
@ -934,6 +934,7 @@ openvino/tools/mo/ops/mxfft.py
|
|||||||
openvino/tools/mo/ops/mxrepeat.py
|
openvino/tools/mo/ops/mxrepeat.py
|
||||||
openvino/tools/mo/ops/mxreshape.py
|
openvino/tools/mo/ops/mxreshape.py
|
||||||
openvino/tools/mo/ops/NextIteration.py
|
openvino/tools/mo/ops/NextIteration.py
|
||||||
|
openvino/tools/mo/ops/nms_rotated.py
|
||||||
openvino/tools/mo/ops/non_max_suppression.py
|
openvino/tools/mo/ops/non_max_suppression.py
|
||||||
openvino/tools/mo/ops/non_zero.py
|
openvino/tools/mo/ops/non_zero.py
|
||||||
openvino/tools/mo/ops/normalize.py
|
openvino/tools/mo/ops/normalize.py
|
||||||
|
79
tools/mo/openvino/tools/mo/ops/nms_rotated.py
Normal file
79
tools/mo/openvino/tools/mo/ops/nms_rotated.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
# Copyright (C) 2018-2023 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import logging as log
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value
|
||||||
|
from openvino.tools.mo.front.extractor import bool_to_str
|
||||||
|
from openvino.tools.mo.graph.graph import Node, Graph
|
||||||
|
from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
|
||||||
|
from openvino.tools.mo.ops.op import Op
|
||||||
|
from openvino.tools.mo.utils.error import Error
|
||||||
|
|
||||||
|
|
||||||
|
class NMSRotated(Op):
|
||||||
|
op = 'NMSRotated'
|
||||||
|
enabled = False
|
||||||
|
|
||||||
|
def __init__(self, graph: Graph, attrs: dict):
|
||||||
|
mandatory_props = {
|
||||||
|
'type': self.op,
|
||||||
|
'op': self.op,
|
||||||
|
'version': 'opset13',
|
||||||
|
|
||||||
|
'infer': self.infer,
|
||||||
|
'type_infer': self.type_infer,
|
||||||
|
|
||||||
|
'sort_result_descending': True,
|
||||||
|
'output_type': np.int64,
|
||||||
|
'clockwise': True,
|
||||||
|
|
||||||
|
'in_ports_count': 5,
|
||||||
|
'out_ports_count': 3,
|
||||||
|
}
|
||||||
|
super().__init__(graph, mandatory_props, attrs)
|
||||||
|
|
||||||
|
def backend_attrs(self):
|
||||||
|
return [('sort_result_descending', lambda node: bool_to_str(node, 'sort_result_descending')),
|
||||||
|
'output_type',
|
||||||
|
('clockwise', lambda node: bool_to_str(node, 'clockwise'))]
|
||||||
|
|
||||||
|
def supported_attrs(self):
|
||||||
|
return [
|
||||||
|
'sort_result_descending',
|
||||||
|
'output_type',
|
||||||
|
'clockwise',
|
||||||
|
]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def infer(node: Node):
|
||||||
|
num_of_inputs = len(node.in_ports())
|
||||||
|
opset = node.get_opset()
|
||||||
|
required_num_inputs = 5
|
||||||
|
input_msg_fmt = 'NMSRotated node {} from {} must have {} inputs'
|
||||||
|
node_name = node.soft_get('name', node.id)
|
||||||
|
inputs_msg = input_msg_fmt.format(
|
||||||
|
node_name, opset, required_num_inputs)
|
||||||
|
assert num_of_inputs == required_num_inputs, inputs_msg
|
||||||
|
|
||||||
|
node.out_port(0).data.set_shape(
|
||||||
|
shape_array([dynamic_dimension_value, 3]))
|
||||||
|
num_of_outputs = len(
|
||||||
|
[port for port in node.out_ports().values() if not port.disconnected()])
|
||||||
|
if num_of_outputs >= 2 and node.has_port('out', 1):
|
||||||
|
node.out_port(1).data.set_shape(
|
||||||
|
shape_array([dynamic_dimension_value, 3]))
|
||||||
|
if num_of_outputs >= 3 and node.has_port('out', 2):
|
||||||
|
node.out_port(2).data.set_shape(shape_array([1]))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def type_infer(node: Node):
|
||||||
|
node.out_port(1).set_data_type(np.float32)
|
||||||
|
if node.has_valid('output_type') and node['output_type'].lower() == 'i32':
|
||||||
|
node.out_port(0).set_data_type(np.int32)
|
||||||
|
node.out_port(2).set_data_type(np.int32)
|
||||||
|
else:
|
||||||
|
node.out_port(0).set_data_type(np.int64)
|
||||||
|
node.out_port(2).set_data_type(np.int64)
|
@ -357,3 +357,103 @@ class TestOps(unittest.TestCase):
|
|||||||
self.assertEqual(loaded_model.get_output_element_type(0), Type.i64)
|
self.assertEqual(loaded_model.get_output_element_type(0), Type.i64)
|
||||||
self.assertEqual(loaded_model.get_output_partial_shape(
|
self.assertEqual(loaded_model.get_output_partial_shape(
|
||||||
0), PartialShape([2, 3]))
|
0), PartialShape([2, 3]))
|
||||||
|
|
||||||
|
def test_nms_rotated_13_attrs_false_i32(self):
|
||||||
|
boxes_shape = [1, 100, 5]
|
||||||
|
scores_shape = [1, 2, 100]
|
||||||
|
max_output_boxes_val = 5
|
||||||
|
iou_threshold_val = 0.5
|
||||||
|
score_threshold_val = 0.4
|
||||||
|
|
||||||
|
boxes_parameter = opset13.parameter(
|
||||||
|
boxes_shape, name="Boxes", dtype=np.float32)
|
||||||
|
scores_parameter = opset13.parameter(
|
||||||
|
scores_shape, name="Scores", dtype=np.float32)
|
||||||
|
|
||||||
|
max_output_boxes = opset13.constant([max_output_boxes_val], np.int64)
|
||||||
|
iou_threshold = opset13.constant([iou_threshold_val], np.float32)
|
||||||
|
score_threshold = opset13.constant([score_threshold_val], np.float32)
|
||||||
|
|
||||||
|
sort_result_descending = False
|
||||||
|
output_type = "i32"
|
||||||
|
clockwise = False
|
||||||
|
|
||||||
|
node = opset13.nms_rotated(boxes_parameter, scores_parameter, max_output_boxes, iou_threshold,
|
||||||
|
score_threshold, sort_result_descending, output_type, clockwise)
|
||||||
|
|
||||||
|
model = Model(node, [boxes_parameter, scores_parameter])
|
||||||
|
graph, loaded_model = TestOps.check_graph_can_save(
|
||||||
|
model, 'nms_rotated_model_1')
|
||||||
|
ir_node = graph.get_op_nodes(op="NMSRotated")[0]
|
||||||
|
|
||||||
|
self.assertListEqual(ir_node.out_port(
|
||||||
|
0).data.get_shape().tolist(), [None, 3])
|
||||||
|
self.assertListEqual(ir_node.out_port(
|
||||||
|
1).data.get_shape().tolist(), [None, 3])
|
||||||
|
self.assertListEqual(ir_node.out_port(
|
||||||
|
2).data.get_shape().tolist(), [1])
|
||||||
|
|
||||||
|
self.assertEqual(ir_node["version"], "opset13")
|
||||||
|
self.assertEqual(ir_node['sort_result_descending'], False)
|
||||||
|
self.assertEqual(ir_node['output_type'], "i32")
|
||||||
|
self.assertEqual(ir_node['clockwise'], False)
|
||||||
|
self.assertEqual(loaded_model.get_output_element_type(0), Type.i32)
|
||||||
|
self.assertEqual(loaded_model.get_output_element_type(1), Type.f32)
|
||||||
|
self.assertEqual(loaded_model.get_output_element_type(2), Type.i32)
|
||||||
|
|
||||||
|
self.assertEqual(loaded_model.get_output_partial_shape(
|
||||||
|
0), PartialShape([Dimension(-1, 10), 3]))
|
||||||
|
self.assertEqual(loaded_model.get_output_partial_shape(
|
||||||
|
1), PartialShape([Dimension(-1, 10), 3]))
|
||||||
|
self.assertEqual(loaded_model.get_output_partial_shape(
|
||||||
|
2), PartialShape([1]))
|
||||||
|
|
||||||
|
def test_nms_rotated_13_attrs_true_i64(self):
|
||||||
|
boxes_shape = [1, 100, 5]
|
||||||
|
scores_shape = [1, 3, 100]
|
||||||
|
max_output_boxes_val = 5
|
||||||
|
iou_threshold_val = 0.5
|
||||||
|
score_threshold_val = 0.4
|
||||||
|
|
||||||
|
boxes_parameter = opset13.parameter(
|
||||||
|
boxes_shape, name="Boxes", dtype=np.float32)
|
||||||
|
scores_parameter = opset13.parameter(
|
||||||
|
scores_shape, name="Scores", dtype=np.float32)
|
||||||
|
|
||||||
|
max_output_boxes = opset13.constant([max_output_boxes_val], np.int64)
|
||||||
|
iou_threshold = opset13.constant([iou_threshold_val], np.float32)
|
||||||
|
score_threshold = opset13.constant([score_threshold_val], np.float32)
|
||||||
|
|
||||||
|
sort_result_descending = True
|
||||||
|
output_type = "i64"
|
||||||
|
clockwise = True
|
||||||
|
|
||||||
|
node = opset13.nms_rotated(boxes_parameter, scores_parameter, max_output_boxes, iou_threshold,
|
||||||
|
score_threshold, sort_result_descending, output_type, clockwise)
|
||||||
|
|
||||||
|
model = Model(node, [boxes_parameter, scores_parameter])
|
||||||
|
graph, loaded_model = TestOps.check_graph_can_save(
|
||||||
|
model, 'nms_rotated_model_2')
|
||||||
|
ir_node = graph.get_op_nodes(op="NMSRotated")[0]
|
||||||
|
|
||||||
|
self.assertListEqual(ir_node.out_port(
|
||||||
|
0).data.get_shape().tolist(), [None, 3])
|
||||||
|
self.assertListEqual(ir_node.out_port(
|
||||||
|
1).data.get_shape().tolist(), [None, 3])
|
||||||
|
self.assertListEqual(ir_node.out_port(
|
||||||
|
2).data.get_shape().tolist(), [1])
|
||||||
|
|
||||||
|
self.assertEqual(ir_node["version"], "opset13")
|
||||||
|
self.assertEqual(ir_node['sort_result_descending'], True)
|
||||||
|
self.assertEqual(ir_node['output_type'], "i64")
|
||||||
|
self.assertEqual(ir_node['clockwise'], True)
|
||||||
|
self.assertEqual(loaded_model.get_output_element_type(0), Type.i64)
|
||||||
|
self.assertEqual(loaded_model.get_output_element_type(1), Type.f32)
|
||||||
|
self.assertEqual(loaded_model.get_output_element_type(2), Type.i64)
|
||||||
|
|
||||||
|
self.assertEqual(loaded_model.get_output_partial_shape(
|
||||||
|
0), PartialShape([Dimension(-1, 15), 3]))
|
||||||
|
self.assertEqual(loaded_model.get_output_partial_shape(
|
||||||
|
1), PartialShape([Dimension(-1, 15), 3]))
|
||||||
|
self.assertEqual(loaded_model.get_output_partial_shape(
|
||||||
|
2), PartialShape([1]))
|
||||||
|
Loading…
Reference in New Issue
Block a user