Compute Library
 21.02
graph_inception_v4.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2021 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #include "arm_compute/graph.h"
25 #ifdef ARM_COMPUTE_CL
27 #endif /* ARM_COMPUTE_CL */
30 #include "utils/GraphUtils.h"
31 #include "utils/Utils.h"
32 
33 using namespace arm_compute;
34 using namespace arm_compute::utils;
35 using namespace arm_compute::graph::frontend;
36 using namespace arm_compute::graph_utils;
37 
38 /** Example demonstrating how to implement InceptionV4's network using the Compute Library's graph API */
39 class InceptionV4Example final : public Example
40 {
41 public:
42  InceptionV4Example()
43  : cmd_parser(), common_opts(cmd_parser), common_params(), graph(0, "InceptionV4")
44  {
45  }
46  bool do_setup(int argc, char **argv) override
47  {
48  // Parse arguments
49  cmd_parser.parse(argc, argv);
50  cmd_parser.validate();
51 
52  // Consume common parameters
53  common_params = consume_common_graph_parameters(common_opts);
54 
55  // Return when help menu is requested
56  if(common_params.help)
57  {
58  cmd_parser.print_help(argv[0]);
59  return false;
60  }
61 
62  // Print parameter values
63  std::cout << common_params << std::endl;
64 
65  // Get trainable parameters data path
66  std::string data_path = common_params.data_path;
67 
68  // Create a preprocessor object
69  std::unique_ptr<IPreprocessor> preprocessor = std::make_unique<TFPreproccessor>();
70 
71  // Create input descriptor
72  const auto operation_layout = common_params.data_layout;
73  const TensorShape tensor_shape = permute_shape(TensorShape(299U, 299U, 3U, 1U), DataLayout::NCHW, operation_layout);
74  TensorDescriptor input_descriptor = TensorDescriptor(tensor_shape, common_params.data_type).set_layout(operation_layout);
75 
76  // Set weights trained layout
77  const DataLayout weights_layout = DataLayout::NCHW;
78 
79  graph << common_params.target
80  << common_params.fast_math_hint
81  << InputLayer(input_descriptor, get_input_accessor(common_params, std::move(preprocessor), false))
82  // Conv2d_1a_3x3
83  << ConvolutionLayer(3U, 3U, 32U,
84  get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_weights.npy", weights_layout),
85  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
86  .set_name("Conv2d_1a_3x3/Conv2D")
87  << BatchNormalizationLayer(get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
88  get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
89  get_random_accessor(1.f, 1.f),
90  get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_BatchNorm_beta.npy"),
91  0.001f)
92  .set_name("Conv2d_1a_3x3/BatchNorm")
94  // Conv2d_2a_3x3
95  << ConvolutionLayer(3U, 3U, 32U,
96  get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_weights.npy", weights_layout),
97  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
98  .set_name("Conv2d_2a_3x3/Conv2D")
99  << BatchNormalizationLayer(get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_BatchNorm_moving_mean.npy"),
100  get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_BatchNorm_moving_variance.npy"),
101  get_random_accessor(1.f, 1.f),
102  get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_BatchNorm_beta.npy"),
103  0.001f)
104  .set_name("Conv2d_2a_3x3/BatchNorm")
106  // Conv2d_2b_3x3
107  << ConvolutionLayer(3U, 3U, 64U,
108  get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_weights.npy", weights_layout),
109  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
110  .set_name("Conv2d_2b_3x3/Conv2D")
111  << BatchNormalizationLayer(get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_BatchNorm_moving_mean.npy"),
112  get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_BatchNorm_moving_variance.npy"),
113  get_random_accessor(1.f, 1.f),
114  get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_BatchNorm_beta.npy"),
115  0.001f)
116  .set_name("Conv2d_2b_3x3/BatchNorm")
118 
119  graph << get_mixed_3a(data_path, weights_layout).set_name("Mixed_3a/concat");
120  graph << get_mixed_4a(data_path, weights_layout).set_name("Mixed_4a/concat");
121  graph << get_mixed_5a(data_path, weights_layout).set_name("Mixed_5a/concat");
122  // 4 inception A blocks
123  graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5b").set_name("Mixed_5b/concat");
124  graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5c").set_name("Mixed_5c/concat");
125  graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5d").set_name("Mixed_5d/concat");
126  graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5e").set_name("Mixed_5e/concat");
127  // reduction A block
128  graph << get_reductionA_block(data_path, weights_layout).set_name("Mixed_6a/concat");
129  // 7 inception B blocks
130  graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6b").set_name("Mixed_6b/concat");
131  graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6c").set_name("Mixed_6c/concat");
132  graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6d").set_name("Mixed_6d/concat");
133  graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6e").set_name("Mixed_6e/concat");
134  graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6f").set_name("Mixed_6f/concat");
135  graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6g").set_name("Mixed_6g/concat");
136  graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6h").set_name("Mixed_6h/concat");
137  // reduction B block
138  graph << get_reductionB_block(data_path, weights_layout).set_name("Mixed_7a/concat");
139  // 3 inception C blocks
140  graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7b").set_name("Mixed_7b/concat");
141  graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7c").set_name("Mixed_7c/concat");
142  graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7d").set_name("Mixed_7d/concat");
143  graph << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, operation_layout)).set_name("Logits/AvgPool_1a/AvgPool")
144  << FlattenLayer().set_name("Logits/Flatten")
146  1001U,
147  get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Logits_Logits_weights.npy", weights_layout),
148  get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Logits_Logits_biases.npy"))
149  .set_name("Logits/MatMul")
150  << SoftmaxLayer().set_name("Logits/Predictions")
151  << OutputLayer(get_output_accessor(common_params, 5));
152 
153  // Finalize graph
154  GraphConfig config;
155  config.num_threads = common_params.threads;
156  config.use_tuner = common_params.enable_tuner;
157  config.tuner_mode = common_params.tuner_mode;
158  config.tuner_file = common_params.tuner_file;
159  config.mlgo_file = common_params.mlgo_file;
160  config.convert_to_uint8 = (common_params.data_type == DataType::QASYMM8);
161 
162  // Load the precompiled kernels from a file into the kernel library, in this way the next time they are needed
163  // compilation won't be required.
164  if(common_params.enable_cl_cache)
165  {
166 #ifdef ARM_COMPUTE_CL
168 #endif /* ARM_COMPUTE_CL */
169  }
170 
171  graph.finalize(common_params.target, config);
172 
173  // Save the opencl kernels to a file
174  if(common_opts.enable_cl_cache)
175  {
176 #ifdef ARM_COMPUTE_CL
178 #endif /* ARM_COMPUTE_CL */
179  }
180 
181  return true;
182  }
183 
184  void do_run() override
185  {
186  graph.run();
187  }
188 
189 private:
190  CommandLineParser cmd_parser;
191  CommonGraphOptions common_opts;
192  CommonGraphParams common_params;
193  Stream graph;
194 
195 private:
196  ConcatLayer get_mixed_3a(const std::string &data_path, DataLayout weights_layout)
197  {
198  std::string total_path = "/cnn_data/inceptionv4_model/Mixed_3a_";
199 
200  SubStream i_a(graph);
202  true))
203  .set_name("Mixed_3a/Branch_0/MaxPool_0a_3x3/MaxPool");
204 
205  SubStream i_b(graph);
206  i_b << ConvolutionLayer(3U, 3U, 96U,
207  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_weights.npy", weights_layout),
208  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
209  .set_name("Mixed_3a/Branch_1/Conv2d_0a_3x3/Conv2D")
210  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_BatchNorm_moving_mean.npy"),
211  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_BatchNorm_moving_variance.npy"),
212  get_random_accessor(1.f, 1.f),
213  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_BatchNorm_beta.npy"),
214  0.001f)
215  .set_name("Mixed_3a/Branch_1/Conv2d_0a_3x3/BatchNorm")
217 
218  return ConcatLayer(std::move(i_a), std::move(i_b));
219  }
220 
221  ConcatLayer get_mixed_4a(const std::string &data_path, DataLayout weights_layout)
222  {
223  std::string total_path = "/cnn_data/inceptionv4_model/Mixed_4a_";
224 
225  SubStream i_a(graph);
226  i_a << ConvolutionLayer(1U, 1U, 64U,
227  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
228  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
229  .set_name("Mixed_4a/Branch_0/Conv2d_0a_1x1/Conv2D")
230  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
231  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
232  get_random_accessor(1.f, 1.f),
233  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
234  0.001f)
235  .set_name("Mixed_4a/Branch_0/Conv2d_0a_1x1/BatchNorm")
237  << ConvolutionLayer(3U, 3U, 96U,
238  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
239  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
240  .set_name("Mixed_4a/Branch_0/Conv2d_1a_3x3/Conv2D")
241  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
242  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
243  get_random_accessor(1.f, 1.f),
244  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
245  0.001f)
246  .set_name("Mixed_4a/Branch_0/Conv2d_1a_3x3/BatchNorm")
248 
249  SubStream i_b(graph);
250  i_b << ConvolutionLayer(1U, 1U, 64U,
251  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
252  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
253  .set_name("Mixed_4a/Branch_1/Conv2d_0a_1x1/Conv2D")
254  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
255  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
256  get_random_accessor(1.f, 1.f),
257  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
258  0.001f)
259  .set_name("Mixed_4a/Branch_1/Conv2d_0a_1x1/BatchNorm")
261  << ConvolutionLayer(7U, 1U, 64U,
262  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
263  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
264  .set_name("Mixed_4a/Branch_1/Conv2d_0b_1x7/Conv2D")
265  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"),
266  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
267  get_random_accessor(1.f, 1.f),
268  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"),
269  0.001f)
270  .set_name("Mixed_4a/Branch_1/Conv2d_0b_1x7/BatchNorm")
272  << ConvolutionLayer(1U, 7U, 64U,
273  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
274  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
275  .set_name("Mixed_4a/Branch_1/Conv2d_0c_7x1/Conv2D")
276  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"),
277  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
278  get_random_accessor(1.f, 1.f),
279  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"),
280  0.001f)
281  .set_name("Mixed_4a/Branch_1/Conv2d_0c_7x1/BatchNorm")
283  << ConvolutionLayer(3U, 3U, 96U,
284  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
285  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
286  .set_name("Mixed_4a/Branch_1/Conv2d_1a_3x3/Conv2D")
287  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
288  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
289  get_random_accessor(1.f, 1.f),
290  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
291  0.001f)
292  .set_name("Mixed_4a/Branch_1/Conv2d_1a_3x3/BatchNorm")
294 
295  return ConcatLayer(std::move(i_a), std::move(i_b));
296  }
297 
298  ConcatLayer get_mixed_5a(const std::string &data_path, DataLayout weights_layout)
299  {
300  std::string total_path = "/cnn_data/inceptionv4_model/Mixed_5a_";
301 
302  SubStream i_a(graph);
303  i_a << ConvolutionLayer(3U, 3U, 192U,
304  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
305  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
306  .set_name("Mixed_5a/Branch_0/Conv2d_1a_3x3/Conv2D")
307  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
308  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
309  get_random_accessor(1.f, 1.f),
310  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
311  0.001f)
312  .set_name("Mixed_5a/Branch_0/Conv2d_1a_3x3/BatchNorm")
314 
315  SubStream i_b(graph);
317  true))
318  .set_name("Mixed_5a/Branch_1/MaxPool_1a_3x3/MaxPool");
319 
320  return ConcatLayer(std::move(i_a), std::move(i_b));
321  }
322 
323  ConcatLayer get_inceptionA_block(const std::string &data_path, DataLayout weights_layout, std::string &&param_path)
324  {
325  std::string total_path = "/cnn_data/inceptionv4_model/" + param_path + "_";
326 
327  SubStream i_a(graph);
328  i_a << ConvolutionLayer(1U, 1U, 96U,
329  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
330  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
331  .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Conv2D")
332  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
333  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
334  get_random_accessor(1.f, 1.f),
335  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
336  0.001f)
337  .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/BatchNorm")
338  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Relu");
339 
340  SubStream i_b(graph);
341  i_b << ConvolutionLayer(1U, 1U, 64U,
342  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
343  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
344  .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Conv2D")
345  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
346  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
347  get_random_accessor(1.f, 1.f),
348  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
349  0.001f)
350  .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/BatchNorm")
351  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Relu")
352  << ConvolutionLayer(3U, 3U, 96U,
353  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_weights.npy", weights_layout),
354  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
355  .set_name(param_path + "/Branch_1/Conv2d_0b_3x3/Conv2D")
356  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
357  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
358  get_random_accessor(1.f, 1.f),
359  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_beta.npy"),
360  0.001f)
361  .set_name(param_path + "/Branch_1/Conv2d_0b_3x3/BatchNorm")
362  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0b_3x3/Relu");
363 
364  SubStream i_c(graph);
365  i_c << ConvolutionLayer(1U, 1U, 64U,
366  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
367  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
368  .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Conv2D")
369  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
370  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
371  get_random_accessor(1.f, 1.f),
372  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
373  0.001f)
374  .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/BatchNorm")
375  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Relu")
376  << ConvolutionLayer(3U, 3U, 96U,
377  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_weights.npy", weights_layout),
378  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
379  .set_name(param_path + "/Branch_2/Conv2d_0b_3x3/Conv2D")
380  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
381  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
382  get_random_accessor(1.f, 1.f),
383  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_beta.npy"),
384  0.001f)
385  .set_name(param_path + "/Branch_2/Conv2d_0b_3x3/BatchNorm")
386  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0b_3x3/Relu")
387  << ConvolutionLayer(3U, 3U, 96U,
388  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_weights.npy", weights_layout),
389  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
390  .set_name(param_path + "/Branch_2/Conv2d_0c_3x3/Conv2D")
391  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_mean.npy"),
392  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_variance.npy"),
393  get_random_accessor(1.f, 1.f),
394  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_beta.npy"),
395  0.001f)
396  .set_name(param_path + "/Branch_2/Conv2d_0c_3x3/BatchNorm")
397  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0c_3x3/Relu");
398 
399  SubStream i_d(graph);
401  true))
402  .set_name(param_path + "/Branch_3/AvgPool_0a_3x3/AvgPool")
403  << ConvolutionLayer(1U, 1U, 96U,
404  get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_weights.npy", weights_layout),
405  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
406  .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Conv2D")
407  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"),
408  get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"),
409  get_random_accessor(1.f, 1.f),
410  get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"),
411  0.001f)
412  .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/BatchNorm")
413  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Relu");
414 
415  return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d));
416  }
417 
418  ConcatLayer get_reductionA_block(const std::string &data_path, DataLayout weights_layout)
419  {
420  std::string total_path = "/cnn_data/inceptionv4_model/Mixed_6a_";
421 
422  SubStream i_a(graph);
423  i_a << ConvolutionLayer(3U, 3U, 384U,
424  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
425  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
426  .set_name("Mixed_6a/Branch_0/Conv2d_1a_3x3/Conv2D")
427  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
428  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
429  get_random_accessor(1.f, 1.f),
430  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
431  0.001f)
432  .set_name("Mixed_6a/Branch_0/Conv2d_1a_3x3/BatchNorm")
434 
435  SubStream i_b(graph);
436  i_b << ConvolutionLayer(1U, 1U, 192U,
437  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
438  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
439  .set_name("Mixed_6a/Branch_1/Conv2d_0a_1x1/Conv2D")
440  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
441  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
442  get_random_accessor(1.f, 1.f),
443  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
444  0.001f)
445  .set_name("Mixed_6a/Branch_1/Conv2d_0a_1x1/BatchNorm")
447  << ConvolutionLayer(3U, 3U, 224U,
448  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_weights.npy", weights_layout),
449  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
450  .set_name("Mixed_6a/Branch_1/Conv2d_0b_3x3/Conv2D")
451  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
452  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
453  get_random_accessor(1.f, 1.f),
454  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_beta.npy"),
455  0.001f)
456  .set_name("Mixed_6a/Branch_1/Conv2d_0b_3x3/BatchNorm")
458  << ConvolutionLayer(3U, 3U, 256U,
459  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
460  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
461  .set_name("Mixed_6a/Branch_1/Conv2d_1a_3x3/Conv2D")
462  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
463  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
464  get_random_accessor(1.f, 1.f),
465  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
466  0.001f)
467  .set_name("Mixed_6a/Branch_1/Conv2d_1a_3x3/BatchNorm")
469 
470  SubStream i_c(graph);
472  true))
473  .set_name("Mixed_6a/Branch_2/MaxPool_1a_3x3/MaxPool");
474 
475  return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c));
476  }
477 
478  ConcatLayer get_inceptionB_block(const std::string &data_path, DataLayout weights_layout, std::string &&param_path)
479  {
480  std::string total_path = "/cnn_data/inceptionv4_model/" + param_path + "_";
481 
482  SubStream i_a(graph);
483  i_a << ConvolutionLayer(1U, 1U, 384U,
484  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
485  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
486  .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Conv2D")
487  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
488  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
489  get_random_accessor(1.f, 1.f),
490  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
491  0.001f)
492  .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/BatchNorm")
493  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Relu");
494 
495  SubStream i_b(graph);
496  i_b << ConvolutionLayer(1U, 1U, 192U,
497  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
498  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
499  .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Conv2D")
500  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
501  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
502  get_random_accessor(1.f, 1.f),
503  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
504  0.001f)
505  .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/BatchNorm")
506  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Relu")
507  << ConvolutionLayer(7U, 1U, 224U,
508  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
509  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
510  .set_name(param_path + "/Branch_1/Conv2d_0b_1x7/Conv2D")
511  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"),
512  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
513  get_random_accessor(1.f, 1.f),
514  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"),
515  0.001f)
516  .set_name(param_path + "/Branch_1/Conv2d_0b_1x7/BatchNorm")
517  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0b_1x7/Relu")
518  << ConvolutionLayer(1U, 7U, 256U,
519  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
520  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
521  .set_name(param_path + "/Branch_1/Conv2d_0c_7x1/Conv2D")
522  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"),
523  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
524  get_random_accessor(1.f, 1.f),
525  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"),
526  0.001f)
527  .set_name(param_path + "/Branch_1/Conv2d_0c_7x1/BatchNorm")
528  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0c_7x1/Relu");
529 
530  SubStream i_c(graph);
531  i_c << ConvolutionLayer(1U, 1U, 192U,
532  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
533  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
534  .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Conv2D")
535  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
536  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
537  get_random_accessor(1.f, 1.f),
538  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
539  0.001f)
540  .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/BatchNorm")
541  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Relu")
542  << ConvolutionLayer(1U, 7U, 192U,
543  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_weights.npy", weights_layout),
544  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
545  .set_name(param_path + "/Branch_2/Conv2d_0b_7x1/Conv2D")
546  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_moving_mean.npy"),
547  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_moving_variance.npy"),
548  get_random_accessor(1.f, 1.f),
549  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_beta.npy"),
550  0.001f)
551  .set_name(param_path + "/Branch_2/Conv2d_0b_7x1/BatchNorm")
552  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0b_7x1/Relu")
553  << ConvolutionLayer(7U, 1U, 224U,
554  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_weights.npy", weights_layout),
555  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
556  .set_name(param_path + "/Branch_2/Conv2d_0c_1x7/Conv2D")
557  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_moving_mean.npy"),
558  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_moving_variance.npy"),
559  get_random_accessor(1.f, 1.f),
560  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_beta.npy"),
561  0.001f)
562  .set_name(param_path + "/Branch_2/Conv2d_0c_1x7/BatchNorm")
563  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0c_1x7/Relu")
564  << ConvolutionLayer(1U, 7U, 224U,
565  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_weights.npy", weights_layout),
566  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
567  .set_name(param_path + "/Branch_2/Conv2d_0d_7x1/Conv2D")
568  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_moving_mean.npy"),
569  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_moving_variance.npy"),
570  get_random_accessor(1.f, 1.f),
571  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_beta.npy"),
572  0.001f)
573  .set_name(param_path + "/Branch_2/Conv2d_0d_7x1/BatchNorm")
574  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0d_7x1/Relu")
575  << ConvolutionLayer(7U, 1U, 256U,
576  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_weights.npy", weights_layout),
577  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
578  .set_name(param_path + "/Branch_2/Conv2d_0e_1x7/Conv2D")
579  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_moving_mean.npy"),
580  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_moving_variance.npy"),
581  get_random_accessor(1.f, 1.f),
582  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_beta.npy"),
583  0.001f)
584  .set_name(param_path + "/Branch_2/Conv2d_0e_1x7/BatchNorm")
585  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0e_1x7/Relu");
586 
587  SubStream i_d(graph);
589  true))
590  .set_name(param_path + "/Branch_3/AvgPool_0a_3x3/AvgPool")
591  << ConvolutionLayer(1U, 1U, 128U,
592  get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_weights.npy", weights_layout),
593  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
594  .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Conv2D")
595  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"),
596  get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"),
597  get_random_accessor(1.f, 1.f),
598  get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"),
599  0.001f)
600  .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/BatchNorm")
601  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Relu");
602 
603  return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d));
604  }
605 
606  ConcatLayer get_reductionB_block(const std::string &data_path, DataLayout weights_layout)
607  {
608  std::string total_path = "/cnn_data/inceptionv4_model/Mixed_7a_";
609 
610  SubStream i_a(graph);
611  i_a << ConvolutionLayer(1U, 1U, 192U,
612  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
613  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
614  .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/Conv2D")
615  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
616  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
617  get_random_accessor(1.f, 1.f),
618  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
619  0.001f)
620  .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/BatchNorm")
622  << ConvolutionLayer(3U, 3U, 192U,
623  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
624  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
625  .set_name("Mixed_7a/Branch_0/Conv2d_1a_3x3/Conv2D")
626  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
627  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
628  get_random_accessor(1.f, 1.f),
629  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
630  0.001f)
631  .set_name("Mixed_7a/Branch_0/Conv2d_1a_3x3/BatchNorm")
633 
634  SubStream i_b(graph);
635  i_b << ConvolutionLayer(1U, 1U, 256U,
636  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
637  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
638  .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/Conv2D")
639  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
640  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
641  get_random_accessor(1.f, 1.f),
642  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
643  0.001f)
644  .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/BatchNorm")
646  << ConvolutionLayer(7U, 1U, 256U,
647  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
648  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
649  .set_name("Mixed_7a/Branch_1/Conv2d_0b_1x7/Conv2D")
650  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"),
651  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
652  get_random_accessor(1.f, 1.f),
653  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"),
654  0.001f)
655  .set_name("Mixed_7a/Branch_1/Conv2d_0b_1x7/BatchNorm")
657  << ConvolutionLayer(1U, 7U, 320U,
658  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
659  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
660  .set_name("Mixed_7a/Branch_1/Conv2d_0c_7x1/Conv2D")
661  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"),
662  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
663  get_random_accessor(1.f, 1.f),
664  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"),
665  0.001f)
666  .set_name("Mixed_7a/Branch_1/Conv2d_0c_7x1/BatchNorm")
668  << ConvolutionLayer(3U, 3U, 320U,
669  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
670  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
671  .set_name("Mixed_7a/Branch_1/Conv2d_1a_3x3/Conv2D")
672  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
673  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
674  get_random_accessor(1.f, 1.f),
675  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
676  0.001f)
677  .set_name("Mixed_7a/Branch_1/Conv2d_1a_3x3/BatchNorm")
679 
680  SubStream i_c(graph);
682  true))
683  .set_name("Mixed_7a/Branch_2/MaxPool_1a_3x3/MaxPool");
684 
685  return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c));
686  }
687 
688  ConcatLayer get_inceptionC_block(const std::string &data_path, DataLayout weights_layout, std::string &&param_path)
689  {
690  std::string total_path = "/cnn_data/inceptionv4_model/" + param_path + "_";
691 
692  SubStream i_a(graph);
693  i_a << ConvolutionLayer(1U, 1U, 256U,
694  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
695  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
696  .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Conv2D")
697  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
698  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
699  get_random_accessor(1.f, 1.f),
700  get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
701  0.001f)
702  .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/BatchNorm")
703  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Relu");
704 
705  SubStream i_b(graph);
706  i_b << ConvolutionLayer(
707  1U, 1U, 384U,
708  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
709  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
710  PadStrideInfo(1, 1, 0, 0))
711  .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Conv2D")
713  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
714  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
715  get_random_accessor(1.f, 1.f),
716  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
717  0.001f)
718  .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/BatchNorm")
719  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Relu");
720 
721  SubStream i_b1(i_b);
722  i_b1 << ConvolutionLayer(
723  3U, 1U, 256U,
724  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_weights.npy", weights_layout),
725  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
726  PadStrideInfo(1, 1, 1, 0))
727  .set_name(param_path + "/Branch_1/Conv2d_0b_1x3/Conv2D")
729  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_mean.npy"),
730  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_variance.npy"),
731  get_random_accessor(1.f, 1.f),
732  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_beta.npy"),
733  0.001f)
734  .set_name(param_path + "/Branch_1/Conv2d_0b_1x3/BatchNorm")
735  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0b_1x3/Relu");
736 
737  SubStream i_b2(i_b);
738  i_b2 << ConvolutionLayer(
739  1U, 3U, 256U,
740  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_weights.npy", weights_layout),
741  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
742  PadStrideInfo(1, 1, 0, 1))
743  .set_name(param_path + "/Branch_1/Conv2d_0c_3x1/Conv2D")
745  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_moving_mean.npy"),
746  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_moving_variance.npy"),
747  get_random_accessor(1.f, 1.f),
748  get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_beta.npy"),
749  0.001f)
750  .set_name(param_path + "/Branch_1/Conv2d_0c_3x1/BatchNorm")
751  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0c_3x1/Relu");
752 
753  // Merge b1 and b2
754  i_b << ConcatLayer(std::move(i_b1), std::move(i_b2)).set_name(param_path + "/Branch_1/concat");
755 
756  SubStream i_c(graph);
757  i_c << ConvolutionLayer(
758  1U, 1U, 384U,
759  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
760  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
761  PadStrideInfo(1, 1, 0, 0))
762  .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Conv2D")
764  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
765  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
766  get_random_accessor(1.f, 1.f),
767  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
768  0.001f)
769  .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/BatchNorm")
770  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Relu")
771  << ConvolutionLayer(
772  1U, 3U, 448U,
773  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_weights.npy", weights_layout),
774  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
775  PadStrideInfo(1, 1, 0, 1))
776  .set_name(param_path + "/Branch_2/Conv2d_0b_3x1/Conv2D")
778  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_BatchNorm_moving_mean.npy"),
779  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_BatchNorm_moving_variance.npy"),
780  get_random_accessor(1.f, 1.f),
781  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_BatchNorm_beta.npy"),
782  0.001f)
783  .set_name(param_path + "/Branch_2/Conv2d_0b_3x1/BatchNorm")
784  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0b_3x1/Relu")
785  << ConvolutionLayer(
786  3U, 1U, 512U,
787  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_weights.npy", weights_layout),
788  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
789  PadStrideInfo(1, 1, 1, 0))
790  .set_name(param_path + "/Branch_2/Conv2d_0c_1x3/Conv2D")
792  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_moving_mean.npy"),
793  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_moving_variance.npy"),
794  get_random_accessor(1.f, 1.f),
795  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_beta.npy"),
796  0.001f)
797  .set_name(param_path + "/Branch_2/Conv2d_0c_1x3/BatchNorm")
798  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0c_1x3/Relu");
799 
800  SubStream i_c1(i_c);
801  i_c1 << ConvolutionLayer(
802  3U, 1U, 256U,
803  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_weights.npy", weights_layout),
804  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
805  PadStrideInfo(1, 1, 1, 0))
806  .set_name(param_path + "/Branch_2/Conv2d_0d_1x3/Conv2D")
808  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_BatchNorm_moving_mean.npy"),
809  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_BatchNorm_moving_variance.npy"),
810  get_random_accessor(1.f, 1.f),
811  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_BatchNorm_beta.npy"),
812  0.001f)
813  .set_name(param_path + "/Branch_2/Conv2d_0d_1x3/BatchNorm")
814  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0d_1x3/Relu");
815 
816  SubStream i_c2(i_c);
817  i_c2 << ConvolutionLayer(
818  1U, 3U, 256U,
819  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_weights.npy", weights_layout),
820  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
821  PadStrideInfo(1, 1, 0, 1))
822  .set_name(param_path + "/Branch_2/Conv2d_0e_3x1/Conv2D")
824  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_BatchNorm_moving_mean.npy"),
825  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_BatchNorm_moving_variance.npy"),
826  get_random_accessor(1.f, 1.f),
827  get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_BatchNorm_beta.npy"),
828  0.001f)
829  .set_name(param_path + "/Branch_2/Conv2d_0e_3x1/BatchNorm")
830  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0e_3x1/Relu");
831 
832  // Merge i_c1 and i_c2
833  i_c << ConcatLayer(std::move(i_c1), std::move(i_c2)).set_name(param_path + "/Branch_2/concat");
834 
835  SubStream i_d(graph);
837  true))
838  .set_name(param_path + "/Branch_3/AvgPool_0a_3x3/AvgPool")
839  << ConvolutionLayer(1U, 1U, 256U,
840  get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_weights.npy", weights_layout),
841  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
842  .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Conv2D")
843  << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"),
844  get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"),
845  get_random_accessor(1.f, 1.f),
846  get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"),
847  0.001f)
848  .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/BatchNorm")
849  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Relu");
850 
851  return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d));
852  }
853 };
854 
855 /** Main program for Inception V4
856  *
857  * Model is based on:
858  * https://arxiv.org/abs/1602.07261
859  * "Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning"
860  * Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi
861  *
862  * Provenance: download.tensorflow.org/models/inception_v4_2016_09_09.tar.gz
863  *
864  * @note To list all the possible arguments execute the binary appended with the --help option
865  *
866  * @param[in] argc Number of arguments
867  * @param[in] argv Arguments
868  */
869 int main(int argc, char **argv)
870 {
871  return arm_compute::utils::run_example<InceptionV4Example>(argc, argv);
872 }
Graph configuration structure Device target types.
Definition: Types.h:80
Shape of a tensor.
Definition: TensorShape.h:39
CLTunerMode tuner_mode
Tuner mode to be used by the CL tuner.
Definition: Types.h:87
void restore_program_cache_from_file(const std::string &filename="cache.bin")
This function loads prebuilt opencl kernels from a file.
Definition: Utils.cpp:35
std::unique_ptr< graph::ITensorAccessor > get_input_accessor(const arm_compute::utils::CommonGraphParams &graph_parameters, std::unique_ptr< IPreprocessor > preprocessor=nullptr, bool bgr=true)
Generates appropriate input accessor according to the specified graph parameters. ...
Definition: GraphUtils.h:497
bool convert_to_uint8
Convert graph to a synthetic uint8 graph.
Definition: Types.h:86
void consume_common_graph_parameters(CommonGraphValidateOptions &options, CommonParams &common_params)
Consumes the consume_common_graph_parameters graph options and creates a structure containing any inf...
Includes all the Graph headers at once.
Common command line options used to configure the graph examples.
Class to parse command line arguments.
Activation Layer Information class.
Definition: Types.h:1550
Copyright (c) 2017-2021 Arm Limited.
std::string mlgo_file
Filename to load MLGO heuristics from.
Definition: Types.h:90
std::unique_ptr< graph::ITensorAccessor > get_random_accessor(PixelValue lower, PixelValue upper, const std::random_device::result_type seed=0)
Generates appropriate random accessor.
Definition: GraphUtils.h:460
std::string tuner_file
File to load/store tuning values from.
Definition: Types.h:89
quantized, asymmetric fixed-point 8-bit number unsigned
int main(int argc, char **argv)
Main program for Inception V4.
Pooling Layer Information struct.
Definition: Types.h:1214
Abstract Example class.
Definition: Utils.h:78
void save_program_cache_to_file(const std::string &filename="cache.bin")
This function saves opencl kernels library to a file.
Definition: Utils.cpp:73
Padding and stride information class.
Definition: Types.h:722
Num samples, channels, height, width.
TensorShape permute_shape(TensorShape tensor_shape, DataLayout in_data_layout, DataLayout out_data_layout)
Permutes a given tensor shape given the input and output data layout.
Definition: GraphUtils.h:664
TensorDescriptor & set_layout(DataLayout data_layout)
Sets tensor descriptor data layout.
Structure holding all the common graph parameters.
std::unique_ptr< graph::ITensorAccessor > get_output_accessor(const arm_compute::utils::CommonGraphParams &graph_parameters, size_t top_n=5, bool is_validation=false, std::ostream &output_stream=std::cout)
Generates appropriate output accessor according to the specified graph parameters.
Definition: GraphUtils.h:543
bool use_tuner
Use a tuner in tunable backends.
Definition: Types.h:85
std::unique_ptr< graph::ITensorAccessor > get_weights_accessor(const std::string &path, const std::string &data_file, DataLayout file_layout=DataLayout::NCHW)
Generates appropriate weights accessor according to the specified path.
Definition: GraphUtils.h:475
int num_threads
Number of threads to use (thread capable backends), if 0 the backend will auto-initialize, if -1 the backend will stay as it is.
Definition: Types.h:88
Stream frontend class to construct simple graphs in a stream fashion.
Definition: Stream.h:45
DataLayout
[DataLayout enum definition]
Definition: Types.h:120
ILayer & set_name(std::string name)
Sets the name of the layer.
Definition: ILayer.h:55