Fixed L2NormFusing transformation (#4526)
* Fixed L2NormFusing transformastion * Refactor L2NormFusing transformation
This commit is contained in:
1 parent
62fb80aa43
commit
e065cf554a
3 files changed
+86
-315
No files matched your search
@@ -19,13 +19,19 @@ import logging as log
|
||||
import numpy as np
|
||||
|
||||
from extensions.ops.normalize_l2 import NormalizeL2Op
|
||||
from mo.front.common.layout import get_features_dim
|
||||
from mo.front.common.partial_infer.utils import int64_array
|
||||
from mo.front.tf.graph_utils import create_op_node_with_second_input
|
||||
from mo.graph.graph import Graph, rename_node
|
||||
from mo.graph.graph import Graph, rename_nodes
|
||||
from mo.middle.replacement import MiddleReplacementPattern
|
||||
|
||||
|
||||
class L2NormToNorm(MiddleReplacementPattern):
|
||||
"""
|
||||
Transformation fuses sub-graph performing l2 normalization into the NormalizeL2 operation. IE plugins do not support
|
||||
NormalizeL2 operation and there is a nGraph transformation which converts NormalizeL2 to NormalizeIE. The latter one
|
||||
allows to normalize over just channel dimension or "channel + all spatial" dimensions for 2D, 3D or 4D cases.
|
||||
"""
|
||||
enabled = True
|
||||
force_clean_up = True
|
||||
|
||||
@@ -86,29 +92,33 @@ class L2NormToNorm(MiddleReplacementPattern):
|
||||
# reduction only along spatial and channel dimensions.
|
||||
input_rank = len(match['sum'].in_port(0).data.get_shape())
|
||||
if input_rank not in [2, 3, 4]:
|
||||
log.debug('IE supports L2 normalization only for 2D, 3D and 4D tensors, skip fusing transformation.')
|
||||
log.debug('IE supports L2 normalization only for 2D, 3D and 4D tensors.')
|
||||
return
|
||||
|
||||
axes = match['sum'].in_port(1).data.get_value()
|
||||
axes = int64_array(axes)
|
||||
if axes.shape == ():
|
||||
axes = int64_array([axes])
|
||||
axes = int64_array([axis if axis >= 0 else axis + input_rank for axis in axes])
|
||||
axes.sort()
|
||||
|
||||
if not np.array_equal(axes, int64_array(np.arange(start=1, stop=input_rank))):
|
||||
log.debug('IE doesn\'t support l2 normalization with reduction along axes {}, skip fusing transformation.'
|
||||
''.format(axes))
|
||||
transformation_applicable = False
|
||||
# check for case C + all spatial dims. Works for 2D (NC), 3D (NCH) and 4D (NCHW and NHWC)
|
||||
if len(axes) + 1 == input_rank and np.array_equal(axes, int64_array(np.arange(start=1, stop=input_rank))):
|
||||
transformation_applicable = True
|
||||
|
||||
# check for pure C channel normalization
|
||||
if len(axes) == 1 and ((input_rank == 4 and get_features_dim(graph.graph['layout'], input_rank) == axes[0]) or
|
||||
(input_rank != 4 and axes[0] == 1)):
|
||||
transformation_applicable = True
|
||||
|
||||
if not transformation_applicable:
|
||||
log.debug('IE doesn\'t support l2 normalization with reduction along axes {}.'.format(axes))
|
||||
return
|
||||
|
||||
# rename l2_normalize node since it will be no longer output after the transformation
|
||||
output_name = match['l2_normalize'].soft_get('name', match['l2_normalize'].id)
|
||||
normalizel2_name = output_name + '/normalizel2'
|
||||
rename_node(match['l2_normalize'], normalizel2_name)
|
||||
|
||||
normalize_node = create_op_node_with_second_input(graph, NormalizeL2Op, axes, {'name': output_name,
|
||||
'eps_mode': 'max', 'eps': y})
|
||||
rename_node(normalize_node, output_name)
|
||||
|
||||
match['square'].in_port(0).get_source().connect(normalize_node.in_port(0))
|
||||
|
||||
match['square'].in_port(0).disconnect()
|
||||
@@ -118,3 +128,4 @@ class L2NormToNorm(MiddleReplacementPattern):
|
||||
match['l2_normalize'].in_port(0).disconnect()
|
||||
|
||||
match['l2_normalize'].out_port(0).get_connection().set_source(normalize_node.out_port(0))
|
||||
rename_nodes([(match['l2_normalize'], output_name + "/TBR"), (normalize_node, output_name)])
|
||||
@@ -17,6 +17,7 @@
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
from generator import generator, generate
|
||||
|
||||
from extensions.middle.L2NormFusing import L2NormToNorm
|
||||
from mo.front.common.partial_infer.utils import int64_array
|
||||
@@ -79,18 +80,31 @@ edges_after_replacement = [
|
||||
]
|
||||
|
||||
|
||||
@generator
|
||||
class L2NormToNormTest(unittest.TestCase):
|
||||
def test_2D(self):
|
||||
input_shape = int64_array([1, 300])
|
||||
axes = int64_array([1])
|
||||
|
||||
@generate(*[(int64_array([2, 3]), int64_array([1]), 'NCHW'), # NC layout, normalize C dimension
|
||||
(int64_array([2, 3]), int64_array([1]), 'NHWC'), # NC layout, normalize C dimension
|
||||
(int64_array([2, 3, 5]), int64_array([1]), 'NCHW'), # NCH layout, normalize C dimension
|
||||
(int64_array([2, 3, 5]), int64_array([1]), 'NHWC'), # NCH layout, normalize C dimension
|
||||
(int64_array([2, 3, 5]), int64_array([-1, -2]), 'NHWC'), # NCH layout, normalize CH dimensions
|
||||
(int64_array([2, 3, 5]), int64_array([-1, -2]), 'NCHW'), # NCH layout, normalize CH dimensions
|
||||
(int64_array([2, 3, 5]), int64_array([1, 2]), 'NCHW'), # NCH layout, normalize CH dimensions
|
||||
(int64_array([2, 3, 5]), int64_array([1, 2]), 'NHWC'), # NCH layout, normalize CH dimensions
|
||||
(int64_array([2, 3, 5, 7]), int64_array([1]), 'NCHW'), # NCHW layout, normalize C dimension
|
||||
(int64_array([2, 3, 5, 7]), int64_array([-1]), 'NHWC'), # NHWC layout, normalize C dimension
|
||||
(int64_array([2, 3, 5, 7]), int64_array([3]), 'NHWC'), # NCHW layout, normalize C dimension
|
||||
(int64_array([2, 3, 5, 7]), int64_array([-1, 1, 2]), 'NCHW'), # NCHW layout, normalize CHW dimensions
|
||||
(int64_array([2, 3, 5, 7]), int64_array([-3, -2, -1]), 'NHWC'), # NCHW layout, normalize HWC dimensions
|
||||
])
|
||||
def test_positive(self, input_shape, axes, layout):
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=axes.shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
graph.graph['layout'] = layout
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
@@ -104,301 +118,43 @@ class L2NormToNormTest(unittest.TestCase):
|
||||
self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='NormalizeL2')[0]]['name'] == 'l2_norm_name')
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_2D_scalar_axis(self):
|
||||
input_shape = int64_array([1, 300])
|
||||
axes = int64_array(1)
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('weights_node_data', dict(kind='data', value=int64_array([axes]).sort())),
|
||||
], edges_after_replacement, nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='NormalizeL2')[0]]['name'] == 'l2_norm_name')
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_3D(self):
|
||||
input_shape = int64_array([1, 300, 300])
|
||||
axes = int64_array([1, 2])
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('weights_node_data', dict(kind='data', value=axes.sort())),
|
||||
], edges_after_replacement, nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='NormalizeL2')[0]]['name'] == 'l2_norm_name')
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_4D(self):
|
||||
input_shape = int64_array([1, 300, 300, 3])
|
||||
axes = int64_array([1, 2, 3])
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('weights_node_data', dict(kind='data', value=axes.sort())),
|
||||
], edges_after_replacement, nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='NormalizeL2')[0]]['name'] == 'l2_norm_name')
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_4D_mixed_axes(self):
|
||||
input_shape = int64_array([1, 300, 300, 3])
|
||||
axes = int64_array([3, 1, 2])
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('weights_node_data', dict(kind='data', value=axes.sort())),
|
||||
], edges_after_replacement, nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='NormalizeL2')[0]]['name'] == 'l2_norm_name')
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_4D_multiple_consumers(self):
|
||||
input_shape = int64_array([1, 300, 300, 3])
|
||||
axes = int64_array([1, 2, 3])
|
||||
weights_value = np.ones(shape=int64_array([input_shape[-1]]), dtype=np.float32)
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
('result_2', dict(kind='op', op='Result'))
|
||||
], edges + [('input_data', 'result_2')], nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('weights_node_data', dict(kind='data', value=axes.sort())),
|
||||
('result_2', dict(kind='op', op='Result'))
|
||||
], edges_after_replacement + [('input_data', 'result_2')], nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='NormalizeL2')[0]]['name'] == 'l2_norm_name')
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_1D_negative(self):
|
||||
input_shape = int64_array([300])
|
||||
axes = int64_array([0])
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_2D_negative(self):
|
||||
input_shape = int64_array([1, 300])
|
||||
axes = int64_array([0])
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_3D_negative(self):
|
||||
input_shape = int64_array([1, 300, 300])
|
||||
axes = int64_array([2])
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_4D_negative_1(self):
|
||||
input_shape = int64_array([1, 300, 300, 3])
|
||||
axes = int64_array([0, 1, 2])
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_4D_negative_2(self):
|
||||
input_shape = int64_array([1, 300, 300, 3])
|
||||
axes = int64_array([2])
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_4D_negative_3(self):
|
||||
input_shape = int64_array([1, 300, 300, 3])
|
||||
axes = int64_array([2, 1])
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_4D_negative_4(self):
|
||||
input_shape = int64_array([1, 300, 300, 3])
|
||||
axes = int64_array([2, 0])
|
||||
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
graph_ref = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
('square_data', dict(kind='data', shape=input_shape)),
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
|
||||
(flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
|
||||
self.assertTrue(flag, resp)
|
||||
|
||||
def test_5D_negative(self):
|
||||
input_shape = int64_array([1, 300, 300, 300, 3])
|
||||
axes = int64_array([1, 2, 3, 4])
|
||||
|
||||
@generate(*[(int64_array([2]), int64_array([0]), 'NCHW'),
|
||||
(int64_array([2, 3]), int64_array([0]), 'NCHW'),
|
||||
(int64_array([2, 3]), int64_array([0]), 'NHWC'),
|
||||
(int64_array([2, 3]), int64_array([0, 1]), 'NCHW'),
|
||||
(int64_array([2, 3]), int64_array([0, 1]), 'NHWC'),
|
||||
(int64_array([2, 3, 5]), int64_array([0]), 'NCHW'),
|
||||
(int64_array([2, 3, 5]), int64_array([0]), 'NHWC'),
|
||||
(int64_array([2, 3, 5]), int64_array([-1]), 'NCHW'),
|
||||
(int64_array([2, 3, 5]), int64_array([-1]), 'NHWC'),
|
||||
(int64_array([2, 3, 5]), int64_array([0, 1]), 'NCHW'),
|
||||
(int64_array([2, 3, 5]), int64_array([0, 1]), 'NHWC'),
|
||||
(int64_array([2, 3, 5]), int64_array([0, 2]), 'NCHW'),
|
||||
(int64_array([2, 3, 5]), int64_array([0, 2]), 'NHWC'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([0]), 'NCHW'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([0]), 'NHWC'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([2]), 'NCHW'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([2]), 'NHWC'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([3]), 'NCHW'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([1]), 'NHWC'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([1, 2]), 'NCHW'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([1, -1]), 'NHWC'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([1, -1]), 'NCHW'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([-2, -1]), 'NHWC'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([1, 3]), 'NCHW'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([2, 3]), 'NHWC'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([0, 1, 2]), 'NCHW'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([0, 1, 2]), 'NHWC'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([0, 2, 3]), 'NCHW'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([0, 2, 3]), 'NHWC'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([0, 1, 2, 3]), 'NCHW'),
|
||||
(int64_array([2, 3, 5, 7]), int64_array([0, 1, 2, 3]), 'NHWC'),
|
||||
(int64_array([2, 3, 5, 7, 9]), int64_array([1]), 'NCHW'),
|
||||
(int64_array([2, 3, 5, 7, 9]), int64_array([-1]), 'NHWC'),
|
||||
(int64_array([2, 3, 5, 7, 9]), int64_array([1, 2, 3, 4]), 'NCHW'),
|
||||
(int64_array([2, 3, 5, 7, 9]), int64_array([-1, -2, -3, -4]), 'NHWC'),
|
||||
])
|
||||
def test_negative(self, input_shape, axes, layout):
|
||||
graph = build_graph_with_attrs(nodes + [
|
||||
('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
|
||||
('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
|
||||
@@ -406,6 +162,7 @@ class L2NormToNormTest(unittest.TestCase):
|
||||
('sum_axes_data', dict(kind='data', value=axes, shape=None)),
|
||||
], edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
graph.graph['layout'] = layout
|
||||
|
||||
L2NormToNorm().find_and_replace_pattern(graph)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Copyright (C) 2018-2020 Intel Corporation
|
||||
Copyright (C) 2018-2021 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
import numpy as np
|
||||
|
||||
from mo.graph.graph import Graph, Node
|
||||
from mo.graph.perm_inputs import PermuteInputs
|
||||
from mo.ops.op import Op
|
||||
|
||||
|
||||
@@ -25,15 +26,15 @@ class NormalizeL2Op(Op):
|
||||
|
||||
def __init__(self, graph: Graph, attrs: dict):
|
||||
super().__init__(graph, {
|
||||
'type': __class__.op,
|
||||
'op': __class__.op,
|
||||
'type': self.op,
|
||||
'op': self.op,
|
||||
'version': 'opset1',
|
||||
'eps': None,
|
||||
'p': None,
|
||||
'eps_mode': None,
|
||||
'in_ports_count': 2,
|
||||
'out_ports_count': 1,
|
||||
'infer': __class__.infer
|
||||
'infer': self.infer
|
||||
}, attrs)
|
||||
|
||||
def supported_attrs(self):
|
||||
@@ -58,3 +59,5 @@ class NormalizeL2Op(Op):
|
||||
node.out_port(0).data.set_value(input_value / norm_value)
|
||||
else:
|
||||
node.out_port(0).data.set_shape(input_shape)
|
||||
|
||||
PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'axis')
|
||||
Reference in new issue
Block a user