Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added check to avoid IR generation in case of wrong input shape #2127

Merged
merged 2 commits into from
Sep 16, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion model-optimizer/mo/ops/convolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

from mo.front.common.partial_infer.utils import int64_array, float_array, mark_input_bins, assign_dims_to_weights, \
tf_window_op_pad_infer
from mo.front.extractor import spatial_getter
from mo.front.onnx.extractors.utils import get_backend_pad
from mo.graph.graph import Node, Graph
from mo.ops.op import Op, PermuteAttrs
Expand Down Expand Up @@ -72,6 +71,11 @@ def calc_convolution(input_spatial_shape, stride_spatial_shape, pad_spatial_shap
Verified to be applicable for both Caffe and ONNX.
'''
spatial_val_wo_stride = input_spatial_shape + pad_spatial_shape - kernel_extent

if np.any(spatial_val_wo_stride < 0):
raise Error("Data after padding has dimension less than window size. " +
"Possible reason of error in incorrect input_shape")
sadolini marked this conversation as resolved.
Show resolved Hide resolved

float_spatial_val_wo_stride = float_array(spatial_val_wo_stride)
return float_spatial_val_wo_stride / stride_spatial_shape + 1

Expand Down
29 changes: 29 additions & 0 deletions model-optimizer/mo/ops/convolution_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from mo.front.common.partial_infer.utils import int64_array
from mo.graph.graph import Node
from mo.ops.convolution import Convolution
from mo.utils.error import Error
from mo.utils.unittest.extractors import FakeValue
from mo.utils.unittest.graph import build_graph

Expand Down Expand Up @@ -378,3 +379,31 @@ def test_conv_infer_3D_convolution(self):
self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0], [0, 0]]), conv_node.pad_spatial_shape))
# Check resulting output shape
self.assertTrue(np.array_equal(int64_array([1, 64, 16, 218, 218]), conv_output.shape))

def test_caffe_conv2d_infer_wrong_input_shape(self):
graph = build_graph(nodes_attributes,
[('conv_input', 'conv_node'),
('conv_weights', 'conv_node'),
('conv_node', 'conv_output'),
('conv_output', 'op_output')
],
{'conv_output': {'shape': None},
'conv_input': {'shape': np.array([1, 3, 1, 1])},
'conv_weights': {'shape': np.array([64, 3, 3, 3]),
'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
'conv_node': {'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
'conv_pad': np.array([[0, 0], [0, 0], [0, 0], [0, 0]]),
'dilation': np.array([1, 1, 1, 1]), 'bias_addable': True, 'bias_term': False,
'output_spatial_shape': None, 'output_shape': None,
'stride': np.array([1, 1, 1, 1]), 'group': 1,
'kernel_spatial_idx': np.array([2, 3]),
'input_feature_channel': 1,
'output_feature_channel': 0,
'output': 64, 'kernel_spatial': np.array([3, 3]),
'spatial_dims': np.array([2, 3]), 'channel_dims': np.array([1]),
'batch_dims': np.array([0])}
})

conv_node = Node(graph, 'conv_node')
with self.assertRaises(Error):
Convolution.infer(conv_node)
21 changes: 12 additions & 9 deletions model-optimizer/mo/ops/pooling.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,21 @@
import numpy as np

from mo.front.common.partial_infer.utils import tf_window_op_pad_infer
from mo.front.extractor import attr_getter
# from mo.front.common.partial_infer.pooling import pool_explicit_padding_infer
from mo.front.extractor import spatial_getter
from mo.front.onnx.extractors.utils import get_backend_pad
from mo.graph.graph import Node, Graph
from mo.ops.op import Op, PermuteAttrs
from mo.utils.error import Error


class Pooling(Op):
op = 'Pooling'

def __init__(self, graph: Graph, attrs: dict):
super().__init__(graph, {
'type': __class__.op,
'op': __class__.op,
'type': self.op,
'op': self.op,
'version': 'opset1',
'infer': __class__.infer,
'infer': self.infer,
'in_ports_count': 1,
'out_ports_count': 1,
}, attrs)
Expand Down Expand Up @@ -96,9 +94,14 @@ def infer(node: Node):
rounding = np.floor
if node.soft_get('pooling_convention') == 'full' or node.soft_get('rounding_type') == 'ceil':
rounding = np.ceil
output_spatial_shape = np.array(rounding(
np.array(input_spatial_shape + pad_spatial_shape - window_spatial_shape,
dtype=np.float) / stride_spatial), dtype=np.int64) + 1

padded_spatial_shape = input_spatial_shape + pad_spatial_shape - window_spatial_shape
if np.any(padded_spatial_shape < 0):
raise Error("Data after padding has dimension less than window size. " +
"Possible reason of error in incorrect input_shape")
sadolini marked this conversation as resolved.
Show resolved Hide resolved

output_spatial_shape = np.array(rounding(np.array(padded_spatial_shape, dtype=np.float) / stride_spatial),
sadolini marked this conversation as resolved.
Show resolved Hide resolved
dtype=np.int64) + 1

original_pads = np.array([i[1] for i in node.pad_spatial_shape])

Expand Down
24 changes: 24 additions & 0 deletions model-optimizer/mo/ops/pooling_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from mo.graph.graph import Node
from mo.ops.pooling import Pooling
from mo.utils.unittest.graph import build_graph
from mo.utils.error import Error

nodes_attributes = {'node_1': {'value': None, 'kind': 'data'},
'pool': {'type': 'Pooling', 'value': None, 'kind': 'op'},
Expand Down Expand Up @@ -129,3 +130,26 @@ def test_pooling_infer_no_shape(self):
Pooling.infer(pool_node)
res_shape = graph.node['node_2']['shape']
self.assertIsNone(res_shape)

def test_pooling_infer_wrong_input_shape(self):
graph = build_graph(nodes_attributes,
[('node_1', 'pool'),
('pool', 'node_2'),
('node_2', 'op_output')
],
{'node_2': {'shape': None},
'node_1': {'shape': np.array([1, 3, 1, 1])},
'pool': {'window': np.array([1, 1, 5, 5]), 'stride': np.array([1, 1, 2, 2]),
'pad': np.array([[0, 0], [0, 0], [1, 1], [1, 1]]),
'pad_spatial_shape': np.array([[1, 1], [1, 1]]),
'pool_method': 'avg', 'exclude_pad': 'false', 'global_pool': 0,
'output_spatial_shape': None, 'output_shape': None,
'kernel_spatial': np.array([3, 3]), 'spatial_dims': np.array([2, 3]),
'channel_dims': np.array([1]), 'batch_dims': np.array([0]),
'pooling_convention': 'full'}
})

pool_node = Node(graph, 'pool')

with self.assertRaises(Error):
Pooling.infer(pool_node)