diff --git a/model-optimizer/extensions/middle/AddMeanScaleValues.py b/model-optimizer/extensions/middle/AddMeanScaleValues.py index c458bc43da5..d6b3c637153 100644 --- a/model-optimizer/extensions/middle/AddMeanScaleValues.py +++ b/model-optimizer/extensions/middle/AddMeanScaleValues.py @@ -18,10 +18,11 @@ import logging as log import numpy as np from extensions.ops.elementwise import Add, Mul +from mo.front.common.layout import get_features_dim from mo.front.extractor import split_node_in_port +from mo.front.tf.graph_utils import create_op_with_const_inputs from mo.graph.graph import Graph, Node from mo.middle.replacement import MiddleReplacementPattern -from mo.ops.op import Op from mo.utils.error import Error from mo.utils.utils import refer_to_faq_msg @@ -37,67 +38,59 @@ class AddMeanScaleValues(MiddleReplacementPattern): from extensions.middle.pass_separator import MiddleStart return [MiddleStart] + @staticmethod + def insert_pre_processing(graph: Graph, input_node: Node, node_mean_scale_values: np.array, + preprocessing_name: str): + assert preprocessing_name in ['scale', 'mean'] + if node_mean_scale_values.get(preprocessing_name) is None: + return + user_value = node_mean_scale_values[preprocessing_name] + value = 1 / user_value if preprocessing_name == 'scale' else user_value * (-1) + optimize_value = int(preprocessing_name == 'scale') + op = Mul if preprocessing_name == 'scale' else Add + + if all([x == optimize_value for x in value]): + return + assert input_node.has_valid('shape') + features_dim_idx = get_features_dim(graph.graph['layout'], len(input_node.shape)) + assert value.size == input_node.shape[features_dim_idx] or value.size == 1 + + shape = np.ones(len(input_node.shape), dtype=np.int64) + shape[features_dim_idx] = value.size + value = value.reshape(shape) + + name = input_node.soft_get('name', input_node.id) + '/' + preprocessing_name + preprocessing = create_op_with_const_inputs(graph, op=op, port_value_dict={1: value}, op_attrs={'name': name}) + + for dst in input_node.out_port(0).get_destinations(): + if dst.node.soft_get('type') != 'ShapeOf': + dst.get_connection().set_source(preprocessing.out_port(0)) + + input_node.out_port(0).connect(preprocessing.in_port(0)) + @staticmethod def apply_scale(graph: Graph, input_node: Node, node_mean_scale_values: dict): - if 'scale' in node_mean_scale_values and node_mean_scale_values['scale'] is not None: - if all([x == 1 for x in node_mean_scale_values['scale']]): - return - out_node = input_node.out_node() - if not input_node.has_valid('shape'): - raise Error("Node {} has not valid shape attribute".format(input_node.id)) - input_shape = input_node.shape - - # Create Mul node - value = 1 / np.array(node_mean_scale_values['scale']) - graph.remove_edge(input_node.id, out_node.id) - - mul_node = Mul(graph, dict(name="Mul_")) - mul_data = Op.create_input_data_node(graph, "data_mul_", np.array(value)) - Op.expand_node_shape(mul_data, (len(input_shape) - 2 if graph.graph['layout'] == 'NCHW' else 0)) - mul_input = Op.create_data_node(graph, input_node, {'shape': out_node.shape}) - - mul_node.create_node_with_data(inputs=[mul_input, mul_data], data_nodes=out_node) + AddMeanScaleValues.insert_pre_processing(graph, input_node, node_mean_scale_values, preprocessing_name='scale') @staticmethod def apply_mean_value(graph: Graph, input_node: Node, node_mean_scale_values: dict): - if 'mean' in node_mean_scale_values and node_mean_scale_values['mean'] is not None: - if all([x == 0 for x in node_mean_scale_values['mean']]): - return - out_node = input_node.out_node() - if not input_node.has_valid('shape'): - raise Error("Node {} has not valid shape attribute".format(input_node.id)) - input_shape = input_node.shape - # Create Add node - graph.remove_edge(input_node.id, out_node.id) - - value = np.array(node_mean_scale_values['mean']) * (-1) - - add_node = Add(graph, dict(name="Add_")) - add_data = Op.create_input_data_node(graph, "data_add_", np.array(value)) - Op.expand_node_shape(add_data, (len(input_shape) - 2 if graph.graph['layout'] == 'NCHW' else 0)) - add_input = Op.create_data_node(graph, input_node, {'shape': out_node.shape}) - - add_node.create_node_with_data(inputs=[add_input, add_data], data_nodes=out_node) + AddMeanScaleValues.insert_pre_processing(graph, input_node, node_mean_scale_values, preprocessing_name='mean') def find_and_replace_pattern(self, graph: Graph): - input_nodes = {} values = graph.graph['cmd_params'].mean_scale_values - for node in graph.nodes(): - node = Node(graph, node) - if node.has_valid('op') and node.op == 'Parameter': - input_nodes.update({node.id: node}) + input_nodes = graph.get_op_nodes(op='Parameter') if not isinstance(values, dict): if len(values) != len(input_nodes): - raise Error('Numbers of inputs and mean/scale values do not match. ' + - refer_to_faq_msg(61)) + raise Error('Numbers of inputs and mean/scale values do not match. ' + refer_to_faq_msg(61)) data = np.copy(values) values = {} - for idx, key in enumerate(input_nodes.keys()): + for idx, node in enumerate(input_nodes): + assert node.has_valid('name') values.update( { - input_nodes[key]['name']: { + node['name']: { 'mean': data[idx][0], 'scale': data[idx][1] } @@ -112,12 +105,12 @@ class AddMeanScaleValues(MiddleReplacementPattern): node_id = graph.get_node_id_by_name(node_name) except Error as e: log.warning('node_name {} is not found in graph'.format(node_name)) - if node_id not in input_nodes: + if Node(graph, node_id) not in input_nodes: # if the user cutted-off input of the network then input node name specified in the --scale_values # or --mean_values doesn't correspond to a real input node generated by Model Optimizer. But # the information about initial input node name is stored in Placeholder's attribute 'initial_node_name' new_node_id = None - for placeholder in input_nodes.values(): + for placeholder in input_nodes: try: placeholder_port = int(placeholder.id.split("_")[-1]) except Exception as ex: diff --git a/model-optimizer/extensions/middle/AddMeanScaleValues_test.py b/model-optimizer/extensions/middle/AddMeanScaleValues_test.py index 2ffd0e227ea..7c31a2ef984 100644 --- a/model-optimizer/extensions/middle/AddMeanScaleValues_test.py +++ b/model-optimizer/extensions/middle/AddMeanScaleValues_test.py @@ -13,240 +13,226 @@ See the License for the specific language governing permissions and limitations under the License. """ - import unittest from argparse import Namespace import numpy as np from extensions.middle.AddMeanScaleValues import AddMeanScaleValues -from mo.graph.graph import Node +from extensions.middle.ScaleInput import ScaleInput from mo.utils.cli_parser import get_mean_scale_dictionary, parse_tuple_pairs -from mo.utils.unittest.graph import build_graph +from mo.utils.ir_engine.compare_graphs import compare_graphs +from mo.utils.unittest.graph import build_graph, regular_op_with_shaped_data, result, connect, connect_data, \ + valued_const_with_data -nodes_attributes = {'node_1': {'type': 'Identity', 'value': None, 'kind': 'op'}, - 'node_1_data': {'value': None, 'kind': 'data', 'data_type': None}, - 'node_2': {'type': 'Identity', 'value': None, 'kind': 'op'}, - 'concat': {'type': 'Concat', 'value': None, 'kind': 'op'}, - 'node_3': {'type': 'Identity', 'value': None, 'kind': 'op'}, - 'node_3_data': {'value': None, 'kind': 'data', 'data_type': None}, - # Placeholders - 'placeholder_1': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - 'placeholder_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None}, - 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - 'pl_1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - 'pl_1_data': {'value': None, 'kind': 'data', 'data_type': None}, - 'pl_2': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - 'pl_2_data': {'value': None, 'kind': 'data', 'data_type': None}, - 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None}, - # ScaleShift layer - 'scaleshift_1': {'type': 'ScaleShift', 'kind': 'op', 'op': 'ScaleShift'}, - 'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'}, - 'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'}, - 'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'}, - # Mul op - 'mul_1': {'type': None, 'kind': 'op', 'op': 'Mul'}, - 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data'}, - 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data'}, - 'op_output': {'kind': 'op', 'op': 'Result', 'infer': lambda x: None} - } +nodes = { + **regular_op_with_shaped_data('parameter', [1, 3, 227, 227], + {'type': 'Parameter', 'op': 'Parameter', 'shape': [1, 3, 227, 227]}), + **regular_op_with_shaped_data('parameter_2', [1, 3, 227, 227], + {'type': 'Parameter', 'op': 'Parameter', 'shape': [1, 3, 227, 227]}), + + **regular_op_with_shaped_data('mul_scale', [1, 3, 227, 227], {'type': 'Multiply', 'op': 'Mul'}), + **regular_op_with_shaped_data('add_mean', [1, 3, 227, 227], {'type': 'Add', 'op': 'Add'}), + + **valued_const_with_data('scale', np.array([1. / 1., 1. / 2., 1. / 3.]).reshape((1, 3, 1, 1))), + **valued_const_with_data('mean', np.array([-1., -2., -3.]).reshape((1, 3, 1, 1))), + + **regular_op_with_shaped_data('shape_of', [4], {'type': 'ShapeOf', 'op': 'ShapeOf'}), + **regular_op_with_shaped_data('op', [1, 3, 227, 227], {}), + **result('result'), + **result('result_2'), +} class AddMeanScaleValuesTest(unittest.TestCase): - def test_add_mean_scale_values_with_data_name(self): - graph = build_graph(nodes_attributes, - [('node_1', 'node_2'), - ('node_2', 'op_output') - ], - {'node_2': {'shape': None, 'data_type': None}, - 'node_1': {'shape': np.array([1, 3, 227, 227]), 'op': 'Parameter', 'name': 'data', - 'data_type': None} - }, - nodes_with_edges_only=True) - graph.graph['layout'] = 'NCHW' - mean_values = parse_tuple_pairs('(124,117,104)') - scale_values = parse_tuple_pairs('') + def test_mean_values_with_data_name(self): + graph_ref = build_graph(nodes, [ + *connect('parameter', '0:add_mean'), + *connect('mean', '1:add_mean'), + *connect('add_mean', 'result'), + ]) - # input = 'data' + mean_values = parse_tuple_pairs('(1,2,3)') + scale_values = parse_tuple_pairs('') mean_scale = get_mean_scale_dictionary(mean_values, scale_values, None) argv = Namespace(mean_scale_values=mean_scale) - graph.graph['cmd_params'] = argv - self.assertEqual(len(graph), 3) - AddMeanScaleValues().find_and_replace_pattern(graph) - self.assertEqual(len(graph), 6) - def test_add_mean_scale_values_without_data_name(self): - graph = build_graph(nodes_attributes, - [('node_1', 'node_2'), - ('node_2', 'op_output') - ], - {'node_2': {'shape': None, 'data_type': None}, - 'node_1': {'shape': np.array([1, 3, 227, 227]), 'op': 'Parameter', 'name': 'data', - 'data_type': None} - }, - nodes_with_edges_only=True) + graph = build_graph(nodes, [*connect('parameter', 'result')], nodes_with_edges_only=True, cli=argv) graph.graph['layout'] = 'NCHW' - mean_values = parse_tuple_pairs('(124,117,104)') + + AddMeanScaleValues().find_and_replace_pattern(graph) + (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) + self.assertTrue(flag, resp) + + def test_mean_values_without_data_name(self): + graph_ref = build_graph(nodes, [ + *connect('parameter', '0:add_mean'), + *connect('mean', '1:add_mean'), + *connect('add_mean', 'result'), + ]) + + mean_values = parse_tuple_pairs('(1,2,3)') scale_values = parse_tuple_pairs('') - # input = None mean_scale = get_mean_scale_dictionary(mean_values, scale_values, None) argv = Namespace(mean_scale_values=mean_scale) - graph.graph['cmd_params'] = argv - self.assertEqual(len(graph), 3) - AddMeanScaleValues().find_and_replace_pattern(graph) - self.assertEqual(len(graph), 6) - def test_add_mean_scale_values1(self): - graph = build_graph(nodes_attributes, - [('pl_1', 'pl_1_data'), ('pl_2', 'pl_2_data')], - {'pl_1_data': {'shape': np.array([1, 3, 38, 38]), 'infer': None}, - 'pl_2_data': {'shape': np.array([1, 6]), 'infer': None}, - 'pl_1': {'shape': np.array([1, 3, 38, 38])}, - 'pl_2': {'shape': np.array([1, 6])}, - }, - nodes_with_edges_only=True) + graph = build_graph(nodes, [*connect('parameter', 'result')], {'parameter': {'name': 'None'}}, + nodes_with_edges_only=True, cli=argv) graph.graph['layout'] = 'NCHW' + + AddMeanScaleValues().find_and_replace_pattern(graph) + (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) + self.assertTrue(flag, resp) + + def test_mean_values_explicit_and_optimized(self): + graph_ref = build_graph(nodes, [ + *connect('parameter', '0:add_mean'), + *connect('mean', '1:add_mean'), + *connect('add_mean', 'result'), + *connect('parameter_2', 'result_2'), + ]) + + argv = Namespace(mean_scale_values={'parameter': {'mean': np.array([1., 2., 3.])}, + 'parameter_2': {'mean': np.array([0., 0., 0.])}}) + graph = build_graph(nodes, [*connect('parameter', 'result'), *connect('parameter_2', 'result_2')], + nodes_with_edges_only=True, cli=argv) + graph.graph['layout'] = 'NCHW' + + AddMeanScaleValues().find_and_replace_pattern(graph) + (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) + self.assertTrue(flag, resp) + (flag, resp) = compare_graphs(graph, graph_ref, 'result_2', check_op_attrs=True) + self.assertTrue(flag, resp) + + def test_mean_values_explicit_and_scale_values_optimized(self): + graph_ref = build_graph(nodes, [ + *connect('parameter', '0:add_mean'), + *connect('mean', '1:add_mean'), + *connect('add_mean', 'result'), + ]) + + argv = Namespace(mean_scale_values={'parameter': {'scale': np.array([1.]), 'mean': np.array([1., 2., 3.])}}) + graph = build_graph(nodes, [*connect('parameter', 'result')], nodes_with_edges_only=True, cli=argv) + graph.graph['layout'] = 'NCHW' + + AddMeanScaleValues().find_and_replace_pattern(graph) + (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) + self.assertTrue(flag, resp) + + def test_mean_values_optimized_and_scale_values_explicit(self): + graph_ref = build_graph(nodes, [ + *connect('parameter', '0:mul_scale'), + *connect('scale', '1:mul_scale'), + *connect('mul_scale', 'result'), + ]) + argv = Namespace( - mean_scale_values={'pl_1': {'mean': np.array([1., 2., 3.])}, 'pl_2': {'mean': np.array([0., 0., 0.])}}) - graph.graph['cmd_params'] = argv - graph.graph['cmd_params'] = argv - AddMeanScaleValues().find_and_replace_pattern(graph) - mul_op_cnt = 0 - add_op_cnt = 0 - for node in graph.nodes(): - node = Node(graph, node) - if node.has_valid('op') and node.op == 'Mul': - mul_op_cnt += 1 - if node.has_valid('op') and node.op == 'Add': - add_op_cnt += 1 - - self.assertEqual(add_op_cnt, 1, "Found more than one Add op in graph") - self.assertEqual(mul_op_cnt, 0, "Found Mul op in graph") - - def test_optimize_scale_and_add_mean_values(self): - graph = build_graph( - nodes_attributes, - [ - ('pl_1', 'pl_1_data') - ], - { - 'pl_1_data': { - 'shape': np.array([1, 3, 38, 38]), - 'infer': None - }, - 'pl_1': { - 'shape': np.array([1, 3, 38, 38]) - } - }, - nodes_with_edges_only=True - ) + mean_scale_values={'parameter': {'scale': np.array([1., 2., 3.]), 'mean': np.array([0., 0., 0.])}}) + graph = build_graph(nodes, [*connect('parameter', 'result')], nodes_with_edges_only=True, cli=argv) graph.graph['layout'] = 'NCHW' - argv = Namespace(mean_scale_values={'pl_1': {'scale': np.array([1.]), 'mean': np.array([1., 2., 3.])}}) - graph.graph['cmd_params'] = argv + AddMeanScaleValues().find_and_replace_pattern(graph) - mul_op_cnt = 0 - add_op_cnt = 0 - for node in graph.nodes(): - node = Node(graph, node) - if node.has_valid('op') and node.op == 'Mul': - mul_op_cnt += 1 - if node.has_valid('op') and node.op == 'Add': - add_op_cnt += 1 + (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) + self.assertTrue(flag, resp) - self.assertEqual(add_op_cnt, 1, "Found more than one Add op in graph") - self.assertEqual(mul_op_cnt, 0, "Found Mul op in graph") + def test_mean_values_explicit_and_scale_values_explicit(self): + graph_ref = build_graph(nodes, [ + *connect('parameter', '0:add_mean'), + *connect('mean', '1:add_mean'), + *connect('add_mean', '0:mul_scale'), + *connect('scale', '1:mul_scale'), + *connect('mul_scale', 'result'), + ]) - def test_optimize_mean_and_add_scale_values(self): - graph = build_graph( - nodes_attributes, - [ - ('pl_1', 'pl_1_data') - ], - { - 'pl_1_data': { - 'shape': np.array([1, 3, 38, 38]), - 'infer': None - }, - 'pl_1': { - 'shape': np.array([1, 3, 38, 38]) - } - }, - nodes_with_edges_only=True - ) - graph.graph['layout'] = 'NCHW' - argv = Namespace(mean_scale_values={'pl_1': {'scale': np.array([1.43]), 'mean': np.array([0., 0., 0.])}}) - graph.graph['cmd_params'] = argv - AddMeanScaleValues().find_and_replace_pattern(graph) - mul_op_cnt = 0 - add_op_cnt = 0 - for node in graph.nodes(): - node = Node(graph, node) - if node.has_valid('op') and node.op == 'Mul': - mul_op_cnt += 1 - if node.has_valid('op') and node.op == 'Add': - add_op_cnt += 1 - - self.assertEqual(add_op_cnt, 0, "Found more than one Add op in graph") - self.assertEqual(mul_op_cnt, 1, "Found Mul op in graph") - - def test_add_mean_scale_values3(self): - graph = build_graph(nodes_attributes, - [('pl_1', 'pl_1_data')], - {'pl_1_data': {'shape': np.array([1, 3, 38, 38]), 'infer': None}, - 'pl_1': {'shape': np.array([1, 3, 38, 38])}, - }, - nodes_with_edges_only=True) - graph.graph['layout'] = 'NCHW' argv = Namespace(mean_scale_values=[[np.array([1., 2., 3.]), np.array([1., 2., 3.])]]) - graph.graph['cmd_params'] = argv + graph = build_graph(nodes, [*connect('parameter', 'result')], + nodes_with_edges_only=True, cli=argv) + graph.graph['layout'] = 'NCHW' + AddMeanScaleValues().find_and_replace_pattern(graph) + (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) + self.assertTrue(flag, resp) - mul_op_cnt = 0 - add_op_cnt = 0 - for node in graph.nodes(): - node = Node(graph, node) - if node.has_valid('op') and node.op == 'Mul': - mul_op_cnt += 1 - if node.has_valid('op') and node.op == 'Add': - add_op_cnt += 1 - - self.assertEqual(add_op_cnt, 1, "Found more than one Add op in graph") - self.assertEqual(mul_op_cnt, 1, "Found more than one Nul op in graph") - - def test_add_mean_scale_values_cut_graph(self): + def test_mean_values_explicit_and_scale_values_explicit_on_cutted_graph(self): """ Test case when user cutted start of the network and specified mean/scale value to the new input node 'node_3'. """ - graph = build_graph(nodes_attributes, - [('pl_1', 'pl_1_data'), - ('pl_2', 'pl_2_data'), - ('pl_2_data', 'node_3'), - ('node_3', 'node_3_data'), - ('pl_1_data', 'node_1'), - ('node_3_data', 'node_1'), - ], - {'pl_1_data': {'shape': np.array([1, 3, 38, 38]), 'infer': None}, - 'pl_2_data': {'shape': np.array([1, 3, 38, 38]), 'infer': None}, - 'pl_2': {'initial_node_name': 'node_3', 'shape': np.array([1, 3, 38, 38])}, - 'pl_1': {'shape': np.array([1, 3, 38, 38])}, - }, - nodes_with_edges_only=True) - graph.graph['layout'] = 'NCHW' + graph_ref = build_graph(nodes, [ + *connect('parameter', '0:add_mean'), + *connect('mean', '1:add_mean'), + *connect('add_mean', 'result'), + + *connect('parameter_2', '0:mul_scale'), + *connect('scale', '1:mul_scale'), + *connect('mul_scale', 'op'), + *connect('op', 'result_2'), + ]) + argv = Namespace( - mean_scale_values={'pl_1': {'mean': np.array([1, 2, 3])}, 'node_3': {'scale': np.array([1, 2, 3])}}) - graph.graph['cmd_params'] = argv + mean_scale_values={'parameter': {'mean': np.array([1, 2, 3])}, 'op': {'scale': np.array([1, 2, 3])}}) + graph = build_graph( + nodes, [*connect('parameter', 'result'), *connect('parameter_2', 'op'), *connect('op', 'result_2')], + {'parameter_2': {'initial_node_name': 'op'}}, nodes_with_edges_only=True, cli=argv) + graph.graph['layout'] = 'NCHW' AddMeanScaleValues().find_and_replace_pattern(graph) - mul_op_cnt = 0 - add_op_cnt = 0 - for node in graph.nodes(): - node = Node(graph, node) - if node.has_valid('op') and node.op == 'Mul': - mul_op_cnt += 1 - if node.has_valid('op') and node.op == 'Add': - add_op_cnt += 1 + (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) + self.assertTrue(flag, resp) + (flag, resp) = compare_graphs(graph, graph_ref, 'result_2', check_op_attrs=True) + self.assertTrue(flag, resp) - self.assertEqual(add_op_cnt, 1, "There should be exactly one Add op") - self.assertEqual(mul_op_cnt, 1, "There should be exactly one Mul op") - self.assertEqual(Node(graph, 'pl_2').out_node().out_node().op, 'Mul', "The Mul op should be added after pl_2") - self.assertEqual(Node(graph, 'pl_1').out_node().out_node().op, 'Add', "The Add op should be added after pl_1") + def test_mean_values_explicit_and_scale_values_explicit_with_shape_of(self): + graph_ref = build_graph(nodes, + [ + *connect('parameter', '0:add_mean'), + *connect('mean', '1:add_mean'), + *connect('add_mean', '0:mul_scale'), + *connect('scale', '1:mul_scale'), + *connect('mul_scale', 'result'), + *connect_data('parameter', 'shape_of'), + *connect('shape_of', 'result_2'), + ], + nodes_with_edges_only=True) + + argv = Namespace( + mean_scale_values={'parameter': {'mean': np.array([1, 2, 3]), 'scale': np.array([1, 2, 3])}}) + graph = build_graph(nodes, + [ + *connect('parameter', 'result'), + *connect_data('parameter', 'shape_of'), + *connect('shape_of', 'result_2'), + ], + nodes_with_edges_only=True, cli=argv) + graph.graph['layout'] = 'NCHW' + + AddMeanScaleValues().find_and_replace_pattern(graph) + (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) + self.assertTrue(flag, resp) + (flag, resp) = compare_graphs(graph, graph_ref, 'result_2', check_op_attrs=True) + self.assertTrue(flag, resp) + + +class ScaleInputTests(unittest.TestCase): + def test_scale_input(self): + graph_ref = build_graph(nodes, [ + *connect('parameter', '0:mul_scale'), + *connect('scale', '1:mul_scale'), + *connect('mul_scale', 'result'), + ], {'scale': {'shape': [1, 1, 1, 1], 'value': np.array(1/255)}, + 'scale_d': {'shape': [1, 1, 1, 1], 'value': np.array(1/255)}}) + + graph = build_graph(nodes, connect('parameter', 'result'), nodes_with_edges_only=True, cli=Namespace(scale=255)) + graph.graph['layout'] = 'NCHW' + + ScaleInput().find_and_replace_pattern(graph) + (flag, resp) = compare_graphs(graph, graph_ref, 'result') + self.assertTrue(flag, resp) + + def test_scale_input_2(self): + graph_ref = build_graph(nodes, connect('parameter', 'result'), nodes_with_edges_only=True) + graph = build_graph(nodes, connect('parameter', 'result'), nodes_with_edges_only=True, cli=Namespace(scale=1)) + graph.graph['layout'] = 'NCHW' + + ScaleInput().find_and_replace_pattern(graph) + (flag, resp) = compare_graphs(graph, graph_ref, 'result') + self.assertTrue(flag, resp) \ No newline at end of file diff --git a/model-optimizer/extensions/middle/ScaleInput_test.py b/model-optimizer/extensions/middle/ScaleInput_test.py deleted file mode 100644 index 1148843414e..00000000000 --- a/model-optimizer/extensions/middle/ScaleInput_test.py +++ /dev/null @@ -1,92 +0,0 @@ -""" - Copyright (C) 2018-2020 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" -import unittest -from argparse import Namespace - -import numpy as np - -from extensions.middle.ScaleInput import ScaleInput -from mo.utils.ir_engine.compare_graphs import compare_graphs -from mo.utils.unittest.graph import build_graph - -nodes_attributes = {'node_1': {'type': 'Identity', 'value': None, 'kind': 'op'}, - 'node_1_data': {'value': None, 'kind': 'data', 'data_type': None}, - 'node_2': {'type': 'Identity', 'value': None, 'kind': 'op'}, - 'concat': {'type': 'Concat', 'value': None, 'kind': 'op'}, - 'node_3': {'type': 'Identity', 'value': None, 'kind': 'op'}, - 'node_3_data': {'value': None, 'kind': 'data', 'data_type': None}, - # Placeholders - 'placeholder_1': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - 'placeholder_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None}, - 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - 'pl_1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - 'pl_1_data': {'value': None, 'kind': 'data', 'data_type': None}, - 'pl_2': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - 'pl_2_data': {'value': None, 'kind': 'data', 'data_type': None}, - 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None}, - # ScaleShift layer - 'scaleshift_1': {'type': 'ScaleShift', 'kind': 'op', 'op': 'ScaleShift'}, - 'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'}, - 'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'}, - 'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'}, - # Mul op - 'mul_1': {'type': None, 'kind': 'op', 'op': 'Mul'}, - 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data'}, - 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data'}, - 'op_output': {'kind': 'op', 'op': 'Result', 'infer': lambda x: None} - } - - -class ScaleInputTests(unittest.TestCase): - def test_scale_input_1(self): - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'op_output') - ], - {'placeholder_1': {'shape': np.array([1, 3, 224, 224])}}, - nodes_with_edges_only=True) - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'mul_1_data'), - ('mul_1_data', 'mul_1'), - ('mul_1_w', 'mul_1'), - ('mul_1', 'placeholder_1_data'), - ('placeholder_1_data', 'op_output') - ], - {'mul_1_w': {'shape': np.array([1, 1, 1]), 'value': np.array([1 / 255])}}, - nodes_with_edges_only=True) - graph.graph['layout'] = 'NCHW' - graph.graph['cmd_params'] = Namespace(scale=255) - ScaleInput().find_and_replace_pattern(graph) - (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1_data') - self.assertTrue(flag, resp) - - def test_scale_input_2(self): - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'op_output') - ], - nodes_with_edges_only=True) - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'op_output') - ], - nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(scale=1) - ScaleInput().find_and_replace_pattern(graph) - (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1_data') - self.assertTrue(flag, resp)