Publishing 2019 R1 content
[platform/upstream/dldt.git] / model-optimizer / mo / middle / passes / fusing / resnet_optimization_test.py
1 """
2  Copyright (c) 2018-2019 Intel Corporation
3
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
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
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.
15 """
16
17 import unittest
18
19 import numpy as np
20
21 from mo.front.common.partial_infer.elemental import copy_shape_infer
22 from mo.front.common.partial_infer.eltwise import eltwise_infer
23 from mo.middle.passes.fusing.resnet_optimization import stride_optimization
24 from mo.ops.convolution import Convolution
25 from mo.ops.pooling import Pooling
26 from mo.utils.unittest.graph import build_graph, compare_graphs
27
28 max_elt_lambda = lambda node: eltwise_infer(node, lambda a, b: np.maximum(a, b))
29
30 nodes_attributes = {
31     # Placeholders
32     'placeholder_1': {'shape': None, 'type': 'Placeholder', 'kind': 'op', 'op': 'Placeholder'},
33     'placeholder_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
34     # Concat1 operation
35     'eltwise_1': {'type': 'Eltwise', 'kind': 'op', 'op': 'Concat', 'infer': max_elt_lambda, 'operation': 'max'},
36     'eltwise_1_data': {'name': 'eltwise_1_data', 'value': None, 'shape': None, 'kind': 'data'},
37     # Convolutions
38     'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NCHW',
39                'output_spatial_shape': None, 'output_shape': None, 'bias_term': True, 'group': 1,
40                'spatial_dims': np.array([2, 3]),
41                'channel_dims': np.array([1]), 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
42                'dilation': np.array([1, 1, 1, 1]),
43                'batch_dims': np.array([0]), 'infer': Convolution.infer,
44                'kernel_spatial_idx': np.array([2, 3], dtype=np.int64), 'input_feature_channel': 1,
45                'output_feature_channel': 0, },
46     'conv_1_w': {'value': None, 'shape': None, 'kind': 'data',
47                  'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
48     'conv_1_b': {'value': None, 'shape': None, 'kind': 'data'},
49     'conv_1_data': {'value': None, 'shape': None, 'kind': 'data'},
50
51     'conv_2': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NCHW',
52                'output_spatial_shape': None, 'output_shape': None, 'bias_term': True, 'group': 1,
53                'spatial_dims': np.array([2, 3]),
54                'channel_dims': np.array([1]), 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
55                'dilation': np.array([1, 1, 1, 1]),
56                'batch_dims': np.array([0]), 'infer': Convolution.infer,
57                'kernel_spatial_idx': np.array([2, 3], dtype=np.int64), 'input_feature_channel': 1,
58                'output_feature_channel': 0, },
59     'conv_2_w': {'value': None, 'shape': None, 'kind': 'data',
60                  'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
61     'conv_2_b': {'value': None, 'shape': None, 'kind': 'data'},
62     'conv_2_data': {'value': None, 'shape': None, 'kind': 'data'},
63
64     'conv_3': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NCHW',
65                'output_spatial_shape': None, 'output_shape': None, 'bias_term': True, 'group': 1,
66                'spatial_dims': np.array([2, 3]),
67                'channel_dims': np.array([1]), 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
68                'dilation': np.array([1, 1, 1, 1]),
69                'batch_dims': np.array([0]), 'infer': Convolution.infer,
70                'kernel_spatial_idx': np.array([2, 3], dtype=np.int64), 'input_feature_channel': 1,
71                'output_feature_channel': 0, },
72     'conv_3_w': {'value': None, 'shape': None, 'kind': 'data',
73                  'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
74     'conv_3_b': {'value': None, 'shape': None, 'kind': 'data'},
75     'conv_3_data': {'value': None, 'shape': None, 'kind': 'data'},
76
77     'conv_4': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NCHW',
78                'output_spatial_shape': None, 'output_shape': None, 'bias_term': True, 'group': 1,
79                'spatial_dims': np.array([2, 3]),
80                'channel_dims': np.array([1]), 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
81                'dilation': np.array([1, 1, 1, 1]),
82                'batch_dims': np.array([0]), 'infer': Convolution.infer,
83                'kernel_spatial_idx': np.array([2, 3], dtype=np.int64), 'input_feature_channel': 1,
84                'output_feature_channel': 0, },
85     'conv_4_w': {'value': None, 'shape': None, 'kind': 'data',
86                  'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
87     'conv_4_b': {'value': None, 'shape': None, 'kind': 'data'},
88     'conv_4_data': {'value': None, 'shape': None, 'kind': 'data'},
89
90     'conv_5': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NCHW',
91                'output_spatial_shape': None, 'output_shape': None, 'bias_term': True, 'group': 1,
92                'spatial_dims': np.array([2, 3]),
93                'channel_dims': np.array([1]), 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
94                'dilation': np.array([1, 1, 1, 1]),
95                'batch_dims': np.array([0]), 'infer': Convolution.infer,
96                'kernel_spatial_idx': np.array([2, 3], dtype=np.int64), 'input_feature_channel': 1,
97                'output_feature_channel': 0, },
98     'conv_5_w': {'value': None, 'shape': None, 'kind': 'data',
99                  'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
100     'conv_5_b': {'value': None, 'shape': None, 'kind': 'data'},
101     'conv_5_data': {'value': None, 'shape': None, 'kind': 'data'},
102     # ReLU
103     'relu_1': {'shape': None, 'type': 'ReLU', 'kind': 'op', 'op': 'ReLU', 'infer': copy_shape_infer},
104     'relu_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
105     'relu_2': {'shape': None, 'type': 'ReLU', 'kind': 'op', 'op': 'ReLU', 'infer': copy_shape_infer},
106     'relu_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
107     'relu_3': {'shape': None, 'type': 'ReLU', 'kind': 'op', 'op': 'ReLU', 'infer': copy_shape_infer},
108     'relu_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
109     # Pooling
110     'pool_1': {'type': 'Pooling', 'kind': 'op', 'op': 'Pooling',
111                'spatial_dims': np.array([2, 3]),
112                'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
113                'infer': Pooling.infer},
114     'pool_1_data': {'value': None, 'shape': None, 'kind': 'data'},
115 }
116
117
118 # In description of unit tests below will be used next syntax: Operation(NxM,XxY), where NxM - kernel size, XxY - stride
119 class ResnetOptimizationTests(unittest.TestCase):
120     # Pl->Conv(1x1,1x1)->Conv(1x1,2x2) => Pl->Conv(1x1,2x2)->Conv(1x1,1x1)
121     def test_resnet_optimization_1(self):
122         graph = build_graph(nodes_attributes,
123                             [('placeholder_1', 'placeholder_1_data'),
124                              ('placeholder_1_data', 'conv_1'),
125                              ('conv_1_w', 'conv_1'),
126                              ('conv_1_b', 'conv_1'),
127                              ('conv_1', 'conv_1_data'),
128                              ('conv_1_data', 'conv_2'),
129                              ('conv_2_w', 'conv_2'),
130                              ('conv_2_b', 'conv_2'),
131                              ('conv_2', 'conv_2_data'),
132                              ],
133                             {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
134
135                              'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
136                              'conv_1': {'kernel_spatial': np.array([1, 1]),
137                                         'stride': np.array([1, 1, 1, 1]),
138                                         'output': np.array([3]), },
139                              'conv_1_data': {'shape': np.array([1, 3, 224, 224])},
140
141                              'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
142                              'conv_2': {'kernel_spatial': np.array([1, 1]),
143                                         'stride': np.array([1, 1, 2, 2]),
144                                         'output': np.array([3]), },
145                              'conv_2_data': {'shape': np.array([1, 3, 112, 112])},
146                              },
147                             nodes_with_edges_only=True)
148
149         graph_ref = build_graph(nodes_attributes,
150                                 [('placeholder_1', 'placeholder_1_data'),
151                                  ('placeholder_1_data', 'conv_1'),
152                                  ('conv_1_w', 'conv_1'),
153                                  ('conv_1_b', 'conv_1'),
154                                  ('conv_1', 'conv_1_data'),
155                                  ('conv_1_data', 'conv_2'),
156                                  ('conv_2_w', 'conv_2'),
157                                  ('conv_2_b', 'conv_2'),
158                                  ('conv_2', 'conv_2_data'),
159                                  ],
160                                 {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
161
162                                  'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
163                                  'conv_1': {'kernel_spatial': np.array([1, 1]),
164                                             'stride': np.array([1, 1, 2, 2]),
165                                             'output': np.array([3]), },
166                                  'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
167
168                                  'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
169                                  'conv_2': {'kernel_spatial': np.array([1, 1]),
170                                             'stride': np.array([1, 1, 1, 1]),
171                                             'output': np.array([3]), },
172                                  'conv_2_data': {'shape': np.array([1, 3, 112, 112])},
173                                  },
174                                 nodes_with_edges_only=True)
175
176         graph.graph['layout'] = 'NCHW'
177         graph_ref.graph['layout'] = 'NCHW'
178
179         stride_optimization(graph)
180
181         (flag, resp) = compare_graphs(graph, graph_ref, 'conv_2_data', check_op_attrs=True)
182         self.assertTrue(flag, resp)
183
184     # Pl->Conv(3x3,2x2)->Conv(1x1,2x2) => Pl->Conv(3x3,4x4)->Conv(1x1,1x1)
185     def test_resnet_optimization_2(self):
186         graph = build_graph(nodes_attributes,
187                             [('placeholder_1', 'placeholder_1_data'),
188                              ('placeholder_1_data', 'conv_1'),
189                              ('conv_1_w', 'conv_1'),
190                              ('conv_1_b', 'conv_1'),
191                              ('conv_1', 'conv_1_data'),
192                              ('conv_1_data', 'conv_2'),
193                              ('conv_2_w', 'conv_2'),
194                              ('conv_2_b', 'conv_2'),
195                              ('conv_2', 'conv_2_data'),
196                              ],
197                             {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
198
199                              'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
200                              'conv_1': {'kernel_spatial': np.array([1, 1]),
201                                         'stride': np.array([1, 1, 2, 2]),
202                                         'output': np.array([3]), },
203                              'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
204
205                              'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
206                              'conv_2': {'kernel_spatial': np.array([1, 1]),
207                                         'stride': np.array([1, 1, 2, 2]),
208                                         'output': np.array([3]), },
209                              'conv_2_data': {'shape': np.array([1, 3, 56, 56])},
210                              },
211                             nodes_with_edges_only=True)
212
213         graph_ref = build_graph(nodes_attributes,
214                                 [('placeholder_1', 'placeholder_1_data'),
215                                  ('placeholder_1_data', 'conv_1'),
216                                  ('conv_1_w', 'conv_1'),
217                                  ('conv_1_b', 'conv_1'),
218                                  ('conv_1', 'conv_1_data'),
219                                  ('conv_1_data', 'conv_2'),
220                                  ('conv_2_w', 'conv_2'),
221                                  ('conv_2_b', 'conv_2'),
222                                  ('conv_2', 'conv_2_data'),
223                                  ],
224                                 {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
225
226                                  'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
227                                  'conv_1': {'kernel_spatial': np.array([1, 1]),
228                                             'stride': np.array([1, 1, 4, 4]),
229                                             'output': np.array([3]), },
230                                  'conv_1_data': {'shape': np.array([1, 3, 56, 56])},
231
232                                  'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
233                                  'conv_2': {'kernel_spatial': np.array([1, 1]),
234                                             'stride': np.array([1, 1, 1, 1]),
235                                             'output': np.array([3]), },
236                                  'conv_2_data': {'shape': np.array([1, 3, 56, 56])},
237                                  },
238                                 nodes_with_edges_only=True)
239
240         graph.graph['layout'] = 'NCHW'
241         graph_ref.graph['layout'] = 'NCHW'
242
243         stride_optimization(graph)
244
245         (flag, resp) = compare_graphs(graph, graph_ref, 'conv_2_data', check_op_attrs=True)
246         self.assertTrue(flag, resp)
247
248     # Pl->Conv(3x3,2x2)->Conv(3x3,2x2) => Same
249     def test_resnet_optimization_3(self):
250         graph = build_graph(nodes_attributes,
251                             [('placeholder_1', 'placeholder_1_data'),
252                              ('placeholder_1_data', 'conv_1'),
253                              ('conv_1_w', 'conv_1'),
254                              ('conv_1_b', 'conv_1'),
255                              ('conv_1', 'conv_1_data'),
256                              ('conv_1_data', 'conv_2'),
257                              ('conv_2_w', 'conv_2'),
258                              ('conv_2_b', 'conv_2'),
259                              ('conv_2', 'conv_2_data'),
260                              ],
261                             {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
262
263                              'conv_1_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
264                              'conv_1': {'kernel_spatial': np.array([3, 3]),
265                                         'stride': np.array([1, 1, 2, 2]),
266                                         'output': np.array([3]), },
267                              'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
268
269                              'conv_2_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
270                              'conv_2': {'kernel_spatial': np.array([3, 3]),
271                                         'stride': np.array([1, 1, 2, 2]),
272                                         'output': np.array([3]), },
273                              'conv_2_data': {'shape': np.array([1, 3, 56, 56])},
274                              },
275                             nodes_with_edges_only=True)
276
277         graph_ref = build_graph(nodes_attributes,
278                                 [('placeholder_1', 'placeholder_1_data'),
279                                  ('placeholder_1_data', 'conv_1'),
280                                  ('conv_1_w', 'conv_1'),
281                                  ('conv_1_b', 'conv_1'),
282                                  ('conv_1', 'conv_1_data'),
283                                  ('conv_1_data', 'conv_2'),
284                                  ('conv_2_w', 'conv_2'),
285                                  ('conv_2_b', 'conv_2'),
286                                  ('conv_2', 'conv_2_data'),
287                                  ],
288                                 {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
289
290                                  'conv_1_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
291                                  'conv_1': {'kernel_spatial': np.array([3, 3]),
292                                             'stride': np.array([1, 1, 2, 2]),
293                                             'output': np.array([3]), },
294                                  'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
295
296                                  'conv_2_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
297                                  'conv_2': {'kernel_spatial': np.array([3, 3]),
298                                             'stride': np.array([1, 1, 2, 2]),
299                                             'output': np.array([3]), },
300                                  'conv_2_data': {'shape': np.array([1, 3, 56, 56])},
301                                  },
302                                 nodes_with_edges_only=True)
303
304         graph.graph['layout'] = 'NCHW'
305         graph_ref.graph['layout'] = 'NCHW'
306
307         stride_optimization(graph)
308
309         (flag, resp) = compare_graphs(graph, graph_ref, 'conv_2_data', check_op_attrs=True)
310         self.assertTrue(flag, resp)
311
312     # Pl--->Conv(3x3,2x2)->ReLU--->Eltwise-->Conv(1x1,2x2) => Pl--->Conv(3x3,4x4)->ReLU--->Eltwise-->Conv(1x1,1x1)
313     #   `-->Conv(3x3,2x2)->ReLU---`                             `-->Conv(3x3,4x4)->ReLU---`
314     def test_resnet_optimization_4(self):
315         graph = build_graph(nodes_attributes,
316                             [('placeholder_1', 'placeholder_1_data'),
317                              ('placeholder_1_data', 'conv_1'),
318                              ('conv_1_w', 'conv_1'),
319                              ('conv_1_b', 'conv_1'),
320                              ('conv_1', 'conv_1_data'),
321                              ('conv_1_data', 'relu_1'),
322                              ('relu_1', 'relu_1_data'),
323
324                              ('placeholder_1_data', 'conv_2'),
325                              ('conv_2_w', 'conv_2'),
326                              ('conv_2_b', 'conv_2'),
327                              ('conv_2', 'conv_2_data'),
328                              ('conv_2_data', 'relu_2'),
329                              ('relu_2', 'relu_2_data'),
330
331                              ('relu_1_data', 'eltwise_1'),
332                              ('relu_2_data', 'eltwise_1'),
333
334                              ('eltwise_1', 'eltwise_1_data'),
335                              ('eltwise_1_data', 'conv_3'),
336                              ('conv_3_w', 'conv_3'),
337                              ('conv_3_b', 'conv_3'),
338                              ('conv_3', 'conv_3_data'),
339
340                              ],
341                             {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
342
343                              'conv_1_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
344                              'conv_1': {'kernel_spatial': np.array([3, 3]),
345                                         'stride': np.array([1, 1, 2, 2]),
346                                         'output': np.array([3]), },
347                              'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
348                              'relu_1_data': {'shape': np.array([1, 3, 112, 112])},
349
350                              'conv_2_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
351                              'conv_2': {'kernel_spatial': np.array([3, 3]),
352                                         'stride': np.array([1, 1, 2, 2]),
353                                         'output': np.array([3]), },
354                              'conv_2_data': {'shape': np.array([1, 3, 112, 112])},
355                              'relu_2_data': {'shape': np.array([1, 3, 112, 112])},
356
357                              'eltwise_1_data': {'shape': np.array([1, 3, 112, 112])},
358
359                              'conv_3_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
360                              'conv_3': {'kernel_spatial': np.array([1, 1]),
361                                         'stride': np.array([1, 1, 2, 2]),
362                                         'output': np.array([3]), },
363                              'conv_3_data': {'shape': np.array([1, 3, 56, 56])},
364                              },
365                             nodes_with_edges_only=True)
366
367         graph_ref = build_graph(nodes_attributes,
368                                 [('placeholder_1', 'placeholder_1_data'),
369                                  ('placeholder_1_data', 'conv_1'),
370                                  ('conv_1_w', 'conv_1'),
371                                  ('conv_1_b', 'conv_1'),
372                                  ('conv_1', 'conv_1_data'),
373                                  ('conv_1_data', 'relu_1'),
374                                  ('relu_1', 'relu_1_data'),
375
376                                  ('placeholder_1_data', 'conv_2'),
377                                  ('conv_2_w', 'conv_2'),
378                                  ('conv_2_b', 'conv_2'),
379                                  ('conv_2', 'conv_2_data'),
380                                  ('conv_2_data', 'relu_2'),
381                                  ('relu_2', 'relu_2_data'),
382
383                                  ('relu_1_data', 'eltwise_1'),
384                                  ('relu_2_data', 'eltwise_1'),
385
386                                  ('eltwise_1', 'eltwise_1_data'),
387                                  ('eltwise_1_data', 'conv_3'),
388                                  ('conv_3_w', 'conv_3'),
389                                  ('conv_3_b', 'conv_3'),
390                                  ('conv_3', 'conv_3_data'),
391
392                                  ],
393                                 {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
394
395                                  'conv_1_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
396                                  'conv_1': {'kernel_spatial': np.array([3, 3]),
397                                             'stride': np.array([1, 1, 4, 4]),
398                                             'output': np.array([3])},
399                                  'conv_1_data': {'shape': np.array([1, 3, 56, 56])},
400                                  'relu_1_data': {'shape': np.array([1, 3, 56, 56])},
401
402                                  'conv_2_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
403                                  'conv_2': {'kernel_spatial': np.array([3, 3]),
404                                             'stride': np.array([1, 1, 4, 4]),
405                                             'output': np.array([3])},
406                                  'conv_2_data': {'shape': np.array([1, 3, 56, 56])},
407                                  'relu_2_data': {'shape': np.array([1, 3, 56, 56])},
408
409                                  'eltwise_1_data': {'shape': np.array([1, 3, 56, 56])},
410
411                                  'conv_3_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
412                                  'conv_3': {'kernel_spatial': np.array([1, 1]),
413                                             'stride': np.array([1, 1, 1, 1]),
414                                             'output': np.array([3])},
415                                  'conv_3_data': {'shape': np.array([1, 3, 56, 56])},
416                                  },
417                                 nodes_with_edges_only=True)
418
419         graph.graph['layout'] = 'NCHW'
420         graph_ref.graph['layout'] = 'NCHW'
421
422         #        dump_graph_for_graphviz(graph)
423         #        dump_graph_for_graphviz(graph_ref)
424
425         stride_optimization(graph)
426
427         (flag, resp) = compare_graphs(graph, graph_ref, 'conv_3_data', check_op_attrs=True)
428         self.assertTrue(flag, resp)
429
430     # Pl--->Conv(1x1,1x1)->ReLU--->Eltwise-->Conv(1x1,2x2) => Pl--->Conv(1x1,2x2)->ReLU--->Eltwise-->Conv(1x1,1x1)
431     #   `----------------->ReLU---`                             `-->Pool(1x1,2x2)->ReLU---`
432     def test_resnet_optimization_5(self):
433         graph = build_graph(nodes_attributes,
434                             [('placeholder_1', 'placeholder_1_data'),
435                              ('placeholder_1_data', 'conv_1'),
436                              ('conv_1_w', 'conv_1'),
437                              ('conv_1_b', 'conv_1'),
438                              ('conv_1', 'conv_1_data'),
439                              ('conv_1_data', 'relu_1'),
440                              ('relu_1', 'relu_1_data'),
441
442                              ('placeholder_1_data', 'relu_2'),
443                              ('relu_2', 'relu_2_data'),
444
445                              ('relu_1_data', 'eltwise_1'),
446                              ('relu_2_data', 'eltwise_1'),
447
448                              ('eltwise_1', 'eltwise_1_data'),
449                              ('eltwise_1_data', 'conv_3'),
450                              ('conv_3_w', 'conv_3'),
451                              ('conv_3_b', 'conv_3'),
452                              ('conv_3', 'conv_3_data'),
453
454                              ],
455                             {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
456
457                              'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
458                              'conv_1': {'kernel_spatial': np.array([1, 1]),
459                                         'stride': np.array([1, 1, 1, 1]),
460                                         'output': np.array([3]), },
461                              'conv_1_data': {'shape': np.array([1, 3, 224, 224])},
462                              'relu_1_data': {'shape': np.array([1, 3, 224, 224])},
463
464                              'relu_2_data': {'shape': np.array([1, 3, 224, 224])},
465
466                              'eltwise_1_data': {'shape': np.array([1, 3, 224, 224])},
467
468                              'conv_3_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
469                              'conv_3': {'kernel_spatial': np.array([1, 1]),
470                                         'stride': np.array([1, 1, 2, 2]),
471                                         'output': np.array([3]), },
472                              'conv_3_data': {'shape': np.array([1, 3, 112, 112])},
473                              },
474                             nodes_with_edges_only=True)
475
476         graph_ref = build_graph(nodes_attributes,
477                                 [('placeholder_1', 'placeholder_1_data'),
478                                  ('placeholder_1_data', 'conv_1'),
479                                  ('conv_1_w', 'conv_1'),
480                                  ('conv_1_b', 'conv_1'),
481                                  ('conv_1', 'conv_1_data'),
482                                  ('conv_1_data', 'relu_1'),
483                                  ('relu_1', 'relu_1_data'),
484
485                                  ('placeholder_1_data', 'pool_1'),
486                                  ('pool_1', 'pool_1_data'),
487                                  ('pool_1_data', 'relu_2'),
488                                  ('relu_2', 'relu_2_data'),
489
490                                  ('relu_1_data', 'eltwise_1'),
491                                  ('relu_2_data', 'eltwise_1'),
492
493                                  ('eltwise_1', 'eltwise_1_data'),
494                                  ('eltwise_1_data', 'conv_3'),
495                                  ('conv_3_w', 'conv_3'),
496                                  ('conv_3_b', 'conv_3'),
497                                  ('conv_3', 'conv_3_data'),
498
499                                  ],
500                                 {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
501
502                                  'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
503                                  'conv_1': {'kernel_spatial': np.array([1, 1]),
504                                             'stride': np.array([1, 1, 2, 2]),
505                                             'output': np.array([3])},
506                                  'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
507                                  'relu_1_data': {'shape': np.array([1, 3, 112, 112])},
508
509                                  'pool_1': {'stride': np.array([1, 1, 2, 2])},
510                                  'pool_1_data': {'shape': np.array([1, 3, 112, 112])},
511                                  'relu_2_data': {'shape': np.array([1, 3, 112, 112])},
512
513                                  'eltwise_1_data': {'shape': np.array([1, 3, 112, 112])},
514
515                                  'conv_3_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
516                                  'conv_3': {'kernel_spatial': np.array([1, 1]),
517                                             'stride': np.array([1, 1, 1, 1]),
518                                             'output': np.array([3])},
519                                  'conv_3_data': {'shape': np.array([1, 3, 112, 112])},
520                                  },
521                                 nodes_with_edges_only=True)
522
523         graph.graph['layout'] = 'NCHW'
524         graph_ref.graph['layout'] = 'NCHW'
525
526         #        dump_graph_for_graphviz(graph)
527         #        dump_graph_for_graphviz(graph_ref)
528
529         stride_optimization(graph)
530
531         (flag, resp) = compare_graphs(graph, graph_ref, 'conv_3_data', check_op_attrs=True)
532         self.assertTrue(flag, resp)
533
534     # Pl->Conv(1x1,1x1)->Conv(1x1,2x2)->Conv(3x3,1x1)->Conv(1x1,2x2)
535     #       =>
536     # Pl->Conv(1x1,2x2)->Conv(1x1,1x1)->Conv(3x3,2x2)->Conv(1x1,1x1)
537     def test_resnet_optimization_6(self):
538         graph = build_graph(nodes_attributes,
539                             [('placeholder_1', 'placeholder_1_data'),
540                              ('placeholder_1_data', 'conv_1'),
541                              ('conv_1_w', 'conv_1'),
542                              ('conv_1_b', 'conv_1'),
543                              ('conv_1', 'conv_1_data'),
544
545                              ('conv_1_data', 'conv_2'),
546                              ('conv_2_w', 'conv_2'),
547                              ('conv_2_b', 'conv_2'),
548                              ('conv_2', 'conv_2_data'),
549
550                              ('conv_2_data', 'conv_3'),
551                              ('conv_3_w', 'conv_3'),
552                              ('conv_3_b', 'conv_3'),
553                              ('conv_3', 'conv_3_data'),
554
555                              ('conv_3_data', 'conv_4'),
556                              ('conv_4_w', 'conv_4'),
557                              ('conv_4_b', 'conv_4'),
558                              ('conv_4', 'conv_4_data'),
559
560                              ],
561                             {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
562
563                              'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
564                              'conv_1': {'kernel_spatial': np.array([1, 1]),
565                                         'stride': np.array([1, 1, 1, 1]),
566                                         'output': np.array([3]), },
567                              'conv_1_data': {'shape': np.array([1, 3, 224, 224])},
568
569                              'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
570                              'conv_2': {'kernel_spatial': np.array([1, 1]),
571                                         'stride': np.array([1, 1, 2, 2]),
572                                         'output': np.array([3]), },
573                              'conv_2_data': {'shape': np.array([1, 3, 112, 112])},
574
575                              'conv_3_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
576                              'conv_3': {'kernel_spatial': np.array([3, 3]),
577                                         'stride': np.array([1, 1, 1, 1]),
578                                         'output': np.array([3]), },
579                              'conv_3_data': {'shape': np.array([1, 3, 110, 110])},
580
581                              'conv_4_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
582                              'conv_4': {'kernel_spatial': np.array([1, 1]),
583                                         'stride': np.array([1, 1, 2, 2]),
584                                         'output': np.array([3]), },
585                              'conv_4_data': {'shape': np.array([1, 3, 55, 55])},
586                              },
587                             nodes_with_edges_only=True)
588
589         graph_ref = build_graph(nodes_attributes,
590                                 [('placeholder_1', 'placeholder_1_data'),
591                                  ('placeholder_1_data', 'conv_1'),
592                                  ('conv_1_w', 'conv_1'),
593                                  ('conv_1_b', 'conv_1'),
594                                  ('conv_1', 'conv_1_data'),
595
596                                  ('conv_1_data', 'conv_2'),
597                                  ('conv_2_w', 'conv_2'),
598                                  ('conv_2_b', 'conv_2'),
599                                  ('conv_2', 'conv_2_data'),
600
601                                  ('conv_2_data', 'conv_3'),
602                                  ('conv_3_w', 'conv_3'),
603                                  ('conv_3_b', 'conv_3'),
604                                  ('conv_3', 'conv_3_data'),
605
606                                  ('conv_3_data', 'conv_4'),
607                                  ('conv_4_w', 'conv_4'),
608                                  ('conv_4_b', 'conv_4'),
609                                  ('conv_4', 'conv_4_data'),
610
611                                  ],
612                                 {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
613
614                                  'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
615                                  'conv_1': {'kernel_spatial': np.array([1, 1]),
616                                             'stride': np.array([1, 1, 2, 2]),
617                                             'output': np.array([3])},
618                                  'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
619
620                                  'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
621                                  'conv_2': {'kernel_spatial': np.array([1, 1]),
622                                             'stride': np.array([1, 1, 1, 1]),
623                                             'output': np.array([3])},
624                                  'conv_2_data': {'shape': np.array([1, 3, 112, 112])},
625
626                                  'conv_3_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
627                                  'conv_3': {'kernel_spatial': np.array([3, 3]),
628                                             'stride': np.array([1, 1, 2, 2]),
629                                             'output': np.array([3])},
630                                  'conv_3_data': {'shape': np.array([1, 3, 55, 55])},
631
632                                  'conv_4_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
633                                  'conv_4': {'kernel_spatial': np.array([1, 1]),
634                                             'stride': np.array([1, 1, 1, 1]),
635                                             'output': np.array([3])},
636                                  'conv_4_data': {'shape': np.array([1, 3, 55, 55])},
637                                  },
638                                 nodes_with_edges_only=True)
639
640         graph.graph['layout'] = 'NCHW'
641         graph_ref.graph['layout'] = 'NCHW'
642
643         stride_optimization(graph)
644
645         (flag, resp) = compare_graphs(graph, graph_ref, 'conv_4_data', check_op_attrs=True)
646         self.assertTrue(flag, resp)