[ MO ] Fix for preprocessing insertion on ShapeOf paths (#3243)
* [ MO ] Fix for preprocessing insertion on ShapeOf paths * ScaleInput tests * refactoring * comments
This commit is contained in:
1 parent
ebcef6a2ad
commit
5ce8946864
3 files changed
+228
-341
No files matched your search
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
Reference in new issue
Block a user