2 Copyright (c) 2018-2019 Intel Corporation
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
21 from mo.front.common.partial_infer.utils import int64_array
22 from mo.graph.graph import Node
23 from mo.ops.convolution import Convolution
24 from mo.utils.unittest.extractors import FakeValue
25 from mo.utils.unittest.graph import build_graph
27 nodes_attributes = {'conv_input': {'value': None, 'kind': 'data'},
28 'conv_node': {'type': 'Convolution', 'kind': 'op'},
29 'conv_weights': {'value': FakeValue(None), 'kind': 'data'},
30 'conv_output': {'value': None, 'kind': 'data'},
31 'output_op': { 'kind': 'op', 'op': 'OpOutput'}
35 class TestConvolutionPartialInfer(unittest.TestCase):
36 def test_caffe_conv2d_infer(self):
37 graph = build_graph(nodes_attributes,
38 [('conv_input', 'conv_node'),
39 ('conv_weights', 'conv_node'),
40 ('conv_node', 'conv_output'),
41 ('conv_output', 'op_output')
43 {'conv_output': {'shape': None},
44 'conv_input': {'shape': np.array([1, 3, 227, 227])},
45 'conv_weights': {'shape': np.array([64, 3, 3, 3]),
46 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
47 'conv_node': {'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
48 'conv_pad': np.array([[0, 0], [0, 0], [0, 0], [0, 0]]),
49 'dilation': np.array([1, 1, 1, 1]), 'bias_addable': True, 'bias_term': False,
50 'output_spatial_shape': None, 'output_shape': None,
51 'stride': np.array([1, 1, 1, 1]), 'group': 1,
52 'kernel_spatial_idx': np.array([2, 3]),
53 'input_feature_channel': 1,
54 'output_feature_channel': 0,
55 'output': 64, 'kernel_spatial': np.array([3, 3]),
56 'spatial_dims': np.array([2, 3]), 'channel_dims': np.array([1]),
57 'batch_dims': np.array([0])}
60 conv_node = Node(graph, 'conv_node')
61 Convolution.infer(conv_node)
62 exp_shape = np.array([1, 64, 225, 225])
63 res_shape = graph.node['conv_output']['shape']
64 for i in range(0, len(exp_shape)):
65 self.assertEqual(exp_shape[i], res_shape[i])
67 def test_caffe_conv2d_infer_no_shape(self):
68 graph = build_graph(nodes_attributes,
69 [('conv_input', 'conv_node'),
70 ('conv_weights', 'conv_node'),
71 ('conv_node', 'conv_output'),
72 ('conv_output', 'op_output')
74 {'conv_output': {'shape': None},
75 'conv_input': {'shape': None},
76 'conv_weights': {'shape': None,
77 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
78 'conv_node': {'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
79 'conv_pad': np.array([[0, 0], [0, 0], [0, 0], [0, 0]]),
80 'dilation': np.array([1, 1, 1, 1]), 'bias_addable': True, 'bias_term': False,
81 'output_spatial_shape': None, 'output_shape': None,
82 'stride': np.array([1, 1, 1, 1]), 'group': 1,
83 'output': 64, 'kernel_spatial': np.array([3, 3]),
84 'spatial_dims': np.array([2, 3]), 'channel_dims': np.array([1]),
85 'batch_dims': np.array([0])}
88 conv_node = Node(graph, 'conv_node')
89 Convolution.infer(conv_node)
90 res_shape = graph.node['conv_output']['shape']
91 self.assertIsNone(res_shape)
93 def test_deconv_infer_ideal(self):
94 graph = build_graph(nodes_attributes,
95 [('conv_input', 'conv_node'),
96 ('conv_weights', 'conv_node'),
97 ('conv_node', 'conv_output'),
98 ('conv_output', 'op_output')
100 {'conv_output': {'shape': None},
101 'conv_input': {'shape': np.array([1, 21, 16, 16])},
102 'conv_weights': {'shape': np.array([1, 21, 4, 4]),
103 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
104 'conv_node': {#'spatial_dims': np.array([2, 3]), 'batch_dims': np.array([0]),
105 'channel_dims': np.array([1]), 'bias_addable': True, 'bias_term': False,
106 'batch_dims': np.array([0]),
107 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
108 'kernel_spatial': np.array([4, 4]), 'output_spatial_shape': None,
109 'kernel_spatial_idx': np.array([2, 3]),
110 'input_feature_channel': 1,
111 'output_feature_channel': 0,
112 'output_padding': np.array([0, 0, 1, 1]),
113 'type': 'Deconvolution', 'output': 21, 'dilation': np.array([1, 1, 1, 1]),
114 'group': 1, 'stride': np.array([1, 1, 2, 2]), 'output_shape': None}
117 deconv_node = Node(graph, 'conv_node')
119 Convolution.infer(deconv_node)
120 res_shape = deconv_node['output_shape']
121 exp_shape = np.array([1, 21, 35, 35])
123 for i in range(0, len(exp_shape)):
124 self.assertEqual(exp_shape[i], res_shape[i])
126 # Check that after double infer shape and pad attrs do not changes
127 Convolution.infer(deconv_node)
129 for i in range(0, len(exp_shape)):
130 self.assertEqual(exp_shape[i], res_shape[i])
133 def test_deconv_infer_no_shape(self):
134 graph = build_graph(nodes_attributes,
135 [('conv_input', 'conv_node'),
136 ('conv_weights', 'conv_node'),
137 ('conv_node', 'conv_output'),
138 ('conv_output', 'op_output')
140 {'conv_output': {'shape': None},
141 'conv_input': {'shape': None},
142 'conv_weights': {'shape': np.array([1, 21, 16, 16]),
143 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
144 'conv_node': {'spatial_dims': np.array([2, 3]), 'batch_dims': np.array([0]),
145 'channel_dims': np.array([1]),
146 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
147 'kernel_spatial': np.array([4, 4]), 'output_spatial_shape': None,
148 'kernel_spatial_idx': np.array([2, 3]),
149 'input_feature_channel': 1,
150 'output_feature_channel': 0,
151 'type': 'Deconvolution', 'output': 21, 'dilation': np.array([1, 1, 1, 1]),
152 'group': 1, 'stride': np.array([1, 1, 2, 2]), 'output_shape': None}
155 deconv_node = Node(graph, 'conv_node')
156 Convolution.infer(deconv_node)
157 res_shape = deconv_node['output_shape']
158 self.assertIsNone(res_shape)
160 def test_conv_infer_set_default_attrs_nchw(self):
161 graph = build_graph(nodes_attributes,
163 ('conv_input', 'conv_node'),
164 ('conv_weights', 'conv_node'),
165 ('conv_node', 'conv_output'),
166 ('conv_output', 'op_output')
173 'shape': int64_array([1, 3, 224, 224])
176 'shape': int64_array([3, 64, 7, 7]),
177 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']
180 'type': 'Convolution',
185 'batch_dims': int64_array([0]),
186 'channel_dims': int64_array([1]),
188 'output_spatial_shape': None,
190 'input_feature_channel': 0,
191 'output_feature_channel': 1,
194 'output_shape': None,
199 conv_node = Node(graph, 'conv_node')
200 conv_output = Node(graph, 'conv_output')
202 Convolution.infer(conv_node)
204 # Check bias_term attribute
205 self.assertTrue(conv_node.has_valid('bias_term'))
206 self.assertTrue(not conv_node.bias_term)
207 # Check kernel_spatial_idx attr detection
208 self.assertTrue(conv_node.has_valid('kernel_spatial_idx'))
209 self.assertTrue(np.array_equal(int64_array([2, 3]), conv_node.kernel_spatial_idx))
210 # Check spatial_dims attr detection
211 self.assertTrue(conv_node.has_valid('spatial_dims'))
212 self.assertTrue(np.array_equal(int64_array([2, 3]), conv_node.spatial_dims))
213 # Check kernel_spatial attr detection
214 self.assertTrue(conv_node.has_valid('kernel_spatial'))
215 self.assertTrue(np.array_equal(int64_array([7, 7]), conv_node.kernel_spatial))
216 # Check output attribute
217 self.assertTrue(conv_node.has_valid('output'))
218 self.assertEqual(64, conv_node.output)
219 # Check dilation value. Should be set to default
220 self.assertTrue(conv_node.has_valid('dilation'))
221 self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1]), conv_node.dilation))
222 # Check stride value. Should be set to default
223 self.assertTrue(conv_node.has_valid('stride'))
224 self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1]), conv_node.stride))
225 # Check pad value. Should be set to default
226 self.assertTrue(conv_node.has_valid('pad'))
227 self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0], [0, 0], [0, 0]]), conv_node.pad))
228 # Check pad_spatial_shape
229 self.assertTrue(conv_node.has_valid('pad_spatial_shape'))
230 self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0]]), conv_node.pad_spatial_shape))
231 # Check resulting output shape
232 self.assertTrue(np.array_equal(int64_array([1, 64, 218, 218]), conv_output.shape))
234 def test_conv_infer_set_default_attrs_nhwc(self):
235 graph = build_graph(nodes_attributes,
237 ('conv_input', 'conv_node'),
238 ('conv_weights', 'conv_node'),
239 ('conv_node', 'conv_output'),
240 ('conv_output', 'op_output')
247 'shape': int64_array([1, 224, 224, 3])
250 'shape': int64_array([3, 64, 7, 7]),
251 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']
254 'type': 'Convolution',
259 'batch_dims': int64_array([0]),
260 'channel_dims': int64_array([3]),
262 'output_spatial_shape': None,
264 'input_feature_channel': 0,
265 'output_feature_channel': 1,
268 'output_shape': None,
273 conv_node = Node(graph, 'conv_node')
274 conv_output = Node(graph, 'conv_output')
276 Convolution.infer(conv_node)
278 # Check bias_term attribute
279 self.assertTrue(conv_node.has_valid('bias_term'))
280 self.assertTrue(not conv_node.bias_term)
281 # Check kernel_spatial_idx attr detection
282 self.assertTrue(conv_node.has_valid('kernel_spatial_idx'))
283 self.assertTrue(np.array_equal(int64_array([2, 3]), conv_node.kernel_spatial_idx))
284 # Check spatial_dims attr detection
285 self.assertTrue(conv_node.has_valid('spatial_dims'))
286 self.assertTrue(np.array_equal(int64_array([1, 2]), conv_node.spatial_dims))
287 # Check kernel_spatial attr detection
288 self.assertTrue(conv_node.has_valid('kernel_spatial'))
289 self.assertTrue(np.array_equal(int64_array([7, 7]), conv_node.kernel_spatial))
290 # Check output attribute
291 self.assertTrue(conv_node.has_valid('output'))
292 self.assertEqual(64, conv_node.output)
293 # Check dilation value. Should be set to default
294 self.assertTrue(conv_node.has_valid('dilation'))
295 self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1]), conv_node.dilation))
296 # Check stride value. Should be set to default
297 self.assertTrue(conv_node.has_valid('stride'))
298 self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1]), conv_node.stride))
299 # Check pad value. Should be set to default
300 self.assertTrue(conv_node.has_valid('pad'))
301 self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0], [0, 0], [0, 0]]), conv_node.pad))
302 # Check pad_spatial_shape
303 self.assertTrue(conv_node.has_valid('pad_spatial_shape'))
304 self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0]]), conv_node.pad_spatial_shape))
305 # Check resulting output shape
306 self.assertTrue(np.array_equal(int64_array([1, 218, 218, 64]), conv_output.shape))
308 def test_conv_infer_3D_convolution(self):
309 graph = build_graph(nodes_attributes,
311 ('conv_input', 'conv_node'),
312 ('conv_weights', 'conv_node'),
313 ('conv_node', 'conv_output'),
314 ('conv_output', 'op_output')
321 'shape': int64_array([1, 3, 16, 224, 224])
324 'shape': int64_array([3, 64, 1, 7, 7]),
325 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']
328 'type': 'Convolution',
333 'batch_dims': int64_array([0]),
334 'channel_dims': int64_array([1]),
336 'output_spatial_shape': None,
338 'input_feature_channel': 0,
339 'output_feature_channel': 1,
342 'output_shape': None,
347 conv_node = Node(graph, 'conv_node')
348 conv_output = Node(graph, 'conv_output')
350 Convolution.infer(conv_node)
352 # Check bias_term attribute
353 self.assertTrue(conv_node.has_valid('bias_term'))
354 self.assertTrue(not conv_node.bias_term)
355 # Check kernel_spatial_idx attr detection
356 self.assertTrue(conv_node.has_valid('kernel_spatial_idx'))
357 self.assertTrue(np.array_equal(int64_array([2, 3, 4]), conv_node.kernel_spatial_idx))
358 # Check spatial_dims attr detection
359 self.assertTrue(conv_node.has_valid('spatial_dims'))
360 self.assertTrue(np.array_equal(int64_array([2, 3, 4]), conv_node.spatial_dims))
361 # Check kernel_spatial attr detection
362 self.assertTrue(conv_node.has_valid('kernel_spatial'))
363 self.assertTrue(np.array_equal(int64_array([1, 7, 7]), conv_node.kernel_spatial))
364 # Check output attribute
365 self.assertTrue(conv_node.has_valid('output'))
366 self.assertEqual(64, conv_node.output)
367 # Check dilation value. Should be set to default
368 self.assertTrue(conv_node.has_valid('dilation'))
369 self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1, 1]), conv_node.dilation))
370 # Check stride value. Should be set to default
371 self.assertTrue(conv_node.has_valid('stride'))
372 self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1, 1]), conv_node.stride))
373 # Check pad value. Should be set to default
374 self.assertTrue(conv_node.has_valid('pad'))
375 self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]), conv_node.pad))
376 # Check pad_spatial_shape
377 self.assertTrue(conv_node.has_valid('pad_spatial_shape'))
378 self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0], [0, 0]]), conv_node.pad_spatial_shape))
379 # Check resulting output shape
380 self.assertTrue(np.array_equal(int64_array([1, 64, 16, 218, 218]), conv_output.shape))