blob: 7c0bb0ce48c074f6703ff0edd6c8f500a5bca870 [file] [log] [blame]
Georgios Pinitasdacd3de2018-12-04 17:25:48 +00001/*
Michele Di Giorgiod9eaf612020-07-08 11:12:57 +01002 * Copyright (c) 2018-2020 Arm Limited.
Georgios Pinitasdacd3de2018-12-04 17:25:48 +00003 *
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#include "support/ToolchainSupport.h"
26#include "utils/CommonGraphOptions.h"
27#include "utils/GraphUtils.h"
28#include "utils/Utils.h"
29
30using namespace arm_compute::utils;
31using namespace arm_compute::graph::frontend;
32using namespace arm_compute::graph_utils;
33
34const float batch_norm_epsilon = 0.0010000000474974513f;
35
36/** Example demonstrating how to implement Inception ResNet V1 network using the Compute Library's graph API */
37class InceptionResNetV1Example final : public Example
38{
39public:
40 InceptionResNetV1Example()
41 : cmd_parser(), common_opts(cmd_parser), common_params(), model_input_width(nullptr), model_input_height(nullptr), graph(0, "InceptionResNetV1")
42 {
43 model_input_width = cmd_parser.add_option<SimpleOption<unsigned int>>("image-width", 512);
44 model_input_height = cmd_parser.add_option<SimpleOption<unsigned int>>("image-height", 512);
45
46 // Add model id option
47 model_input_width->set_help("Input image width.");
48 model_input_height->set_help("Input image height.");
49 }
50 InceptionResNetV1Example(const InceptionResNetV1Example &) = delete;
51 InceptionResNetV1Example &operator=(const InceptionResNetV1Example &) = delete;
Matthew Benthamf5f23912020-03-05 22:32:16 +000052 ~InceptionResNetV1Example() override = default;
Georgios Pinitasdacd3de2018-12-04 17:25:48 +000053 bool do_setup(int argc, char **argv) override
54 {
55 // Parse arguments
56 cmd_parser.parse(argc, argv);
Georgios Pinitascd60a5f2019-08-21 17:06:54 +010057 cmd_parser.validate();
Georgios Pinitasdacd3de2018-12-04 17:25:48 +000058
59 // Consume common parameters
60 common_params = consume_common_graph_parameters(common_opts);
61
62 // Return when help menu is requested
63 if(common_params.help)
64 {
65 cmd_parser.print_help(argv[0]);
66 return false;
67 }
68 // Get input image width and height
69 const unsigned int image_width = model_input_width->value();
70 const unsigned int image_height = model_input_height->value();
71
72 // Set default layout if needed
73 if(!common_opts.data_layout->is_set() && common_params.target == Target::NEON)
74 {
75 common_params.data_layout = DataLayout::NCHW;
76 }
77
78 // Checks
79 ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
80
81 // Print parameter values
82 std::cout << common_params << std::endl;
83 std::cout << "Image width: " << image_width << std::endl;
84 std::cout << "Image height: " << image_height << std::endl;
85
86 // Create model path
87 std::string data_path = common_params.data_path;
88 std::string model_path = "/cnn_data/inception_resnet_v1_model/";
89 if(!data_path.empty())
90 {
91 data_path += model_path;
92 }
93
94 // Create a preprocessor object
95 std::unique_ptr<IPreprocessor> preprocessor = arm_compute::support::cpp14::make_unique<TFPreproccessor>(0.f, 1.f);
96
97 // Create input descriptor
Sang-Hoon Park11fedda2020-01-15 14:44:04 +000098 const auto operation_layout = common_params.data_layout;
99 const TensorShape tensor_shape = permute_shape(TensorShape(image_width, image_height, 3U, 1U), DataLayout::NCHW, operation_layout);
100 TensorDescriptor input_descriptor = TensorDescriptor(tensor_shape, common_params.data_type).set_layout(operation_layout);
Georgios Pinitasdacd3de2018-12-04 17:25:48 +0000101
102 // Set weights trained layout
103 const DataLayout weights_layout = DataLayout::NCHW;
104
105 graph << common_params.target
106 << common_params.fast_math_hint
107 << InputLayer(input_descriptor, get_input_accessor(common_params, std::move(preprocessor), false))
108 // Conv2d_1a_3x3
109 << ConvolutionLayer(3U, 3U, 32U,
110 get_weights_accessor(data_path, "Conv2d_1a_3x3_weights.npy", weights_layout),
111 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
112 PadStrideInfo(2, 2, 0, 0))
113 .set_name("Conv2d_1a_3x3/convolution")
114 << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
115 get_weights_accessor(data_path, "Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
116 get_random_accessor(1.f, 1.f),
117 get_weights_accessor(data_path, "Conv2d_1a_3x3_BatchNorm_beta.npy"),
118 batch_norm_epsilon)
119 .set_name("Conv2d_1a_3x3/BatchNorm")
120 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_1a_3x3/Relu")
121 // Conv2d_2a_3x3
122 << ConvolutionLayer(3U, 3U, 32U,
123 get_weights_accessor(data_path, "Conv2d_2a_3x3_weights.npy", weights_layout),
124 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
125 PadStrideInfo(1, 1, 0, 0))
126 .set_name("Conv2d_2a_3x3/convolution")
127 << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_2a_3x3_BatchNorm_moving_mean.npy"),
128 get_weights_accessor(data_path, "Conv2d_2a_3x3_BatchNorm_moving_variance.npy"),
129 get_random_accessor(1.f, 1.f),
130 get_weights_accessor(data_path, "Conv2d_2a_3x3_BatchNorm_beta.npy"),
131 batch_norm_epsilon)
132 .set_name("Conv2d_2a_3x3/BatchNorm")
133 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_2a_3x3/Relu")
134 // Conv2d_2b_3x3
135 << ConvolutionLayer(3U, 3U, 64U,
136 get_weights_accessor(data_path, "Conv2d_2b_3x3_weights.npy", weights_layout),
137 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
138 PadStrideInfo(1, 1, 1, 1))
139 .set_name("Conv2d_2b_3x3/convolution")
140 << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_2b_3x3_BatchNorm_moving_mean.npy"),
141 get_weights_accessor(data_path, "Conv2d_2b_3x3_BatchNorm_moving_variance.npy"),
142 get_random_accessor(1.f, 1.f),
143 get_weights_accessor(data_path, "Conv2d_2b_3x3_BatchNorm_beta.npy"),
144 batch_norm_epsilon)
145 .set_name("Conv2d_2b_3x3/BatchNorm")
146 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_2b_3x3/Relu")
147 // MaxPool_3a_3x3
Sang-Hoon Park11fedda2020-01-15 14:44:04 +0000148 << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, operation_layout, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true)).set_name("MaxPool_3a_3x3/MaxPool")
Georgios Pinitasdacd3de2018-12-04 17:25:48 +0000149 // Conv2d_3b_1x1
150 << ConvolutionLayer(1U, 1U, 80U,
151 get_weights_accessor(data_path, "Conv2d_3b_1x1_weights.npy", weights_layout),
152 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
153 PadStrideInfo(1, 1, 0, 0))
154 .set_name("Conv2d_3b_1x1/convolution")
155 << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_3b_1x1_BatchNorm_moving_mean.npy"),
156 get_weights_accessor(data_path, "Conv2d_3b_1x1_BatchNorm_moving_variance.npy"),
157 get_random_accessor(1.f, 1.f),
158 get_weights_accessor(data_path, "Conv2d_3b_1x1_BatchNorm_beta.npy"),
159 batch_norm_epsilon)
160 .set_name("Conv2d_3b_1x1/BatchNorm")
161 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_3b_1x1/Relu")
162 // Conv2d_4a_3x3
163 << ConvolutionLayer(3U, 3U, 192U,
164 get_weights_accessor(data_path, "Conv2d_4a_3x3_weights.npy", weights_layout),
165 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
166 PadStrideInfo(1, 1, 0, 0))
167 .set_name("Conv2d_4a_3x3/convolution")
168 << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_4a_3x3_BatchNorm_moving_mean.npy"),
169 get_weights_accessor(data_path, "Conv2d_4a_3x3_BatchNorm_moving_variance.npy"),
170 get_random_accessor(1.f, 1.f),
171 get_weights_accessor(data_path, "Conv2d_4a_3x3_BatchNorm_beta.npy"),
172 batch_norm_epsilon)
173 .set_name("Conv2d_4a_3x3/BatchNorm")
174 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_4a_3x3/Relu")
175 // Conv2d_4b_3x3
176 << ConvolutionLayer(3U, 3U, 256U,
177 get_weights_accessor(data_path, "Conv2d_4b_3x3_weights.npy", weights_layout),
178 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
179 PadStrideInfo(2, 2, 0, 0))
180 .set_name("Conv2d_4a_3x3/convolution")
181 << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_4b_3x3_BatchNorm_moving_mean.npy"),
182 get_weights_accessor(data_path, "Conv2d_4b_3x3_BatchNorm_moving_variance.npy"),
183 get_random_accessor(1.f, 1.f),
184 get_weights_accessor(data_path, "Conv2d_4b_3x3_BatchNorm_beta.npy"),
185 batch_norm_epsilon)
186 .set_name("Conv2d_4b_3x3/BatchNorm")
187 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_4b_3x3/Relu");
188
189 // 5 x Inception-resnet-A
190 block35_repeat(data_path, weights_layout, 5);
191 // Reduction-A
192 reduction_a(data_path, weights_layout);
193 // 10 x Inception-Resnet-B
194 block17_repeat(data_path, weights_layout, 10);
195 // Reduction-B
196 reduction_b(data_path, weights_layout);
197 // 5 x Inception-resnet-C
198 block8_repeat(data_path, weights_layout, 5, 0.2f, true);
199
200 block8_repeat(data_path, weights_layout, 1, 1.f, false);
201
202 // Logits tail
Sang-Hoon Park11fedda2020-01-15 14:44:04 +0000203 graph << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, operation_layout)).set_name("Logits/AvgPool_1a_8x8")
Georgios Pinitasdacd3de2018-12-04 17:25:48 +0000204 << FlattenLayer().set_name("Logits/Flatten")
205 << FullyConnectedLayer(
206 128U,
207 get_weights_accessor(data_path, "Logits_Logits_weights.npy", weights_layout),
208 get_weights_accessor(data_path, "Logits_Logits_biases.npy"))
209 .set_name("Logits/Logits")
210 << OutputLayer(arm_compute::support::cpp14::make_unique<DummyAccessor>(0));
211
212 // Finalize graph
213 GraphConfig config;
214 config.num_threads = common_params.threads;
215 config.use_tuner = common_params.enable_tuner;
Vidhya Sudhan Loganathan050471e2019-04-25 09:27:24 +0100216 config.tuner_mode = common_params.tuner_mode;
Georgios Pinitasdacd3de2018-12-04 17:25:48 +0000217 config.tuner_file = common_params.tuner_file;
218
219 graph.finalize(common_params.target, config);
220
221 return true;
222 }
223
224 void do_run() override
225 {
226 graph.run();
227 }
228
229private:
230 CommandLineParser cmd_parser;
231 CommonGraphOptions common_opts;
232 CommonGraphParams common_params;
233 SimpleOption<unsigned int> *model_input_width{ nullptr };
234 SimpleOption<unsigned int> *model_input_height{ nullptr };
235 Stream graph;
236
237private:
238 void block35_repeat(const std::string &data_path, DataLayout weights_layout, unsigned int num_blocks)
239 {
240 for(unsigned int i = 0; i < num_blocks; ++i)
241 {
242 std::stringstream unit_path_ss;
243 unit_path_ss << "Repeat_block35_" << (i + 1) << "_";
244 std::stringstream unit_name_ss;
245 unit_name_ss << "Repeat/block35_" << (i + 1) << "/";
246
247 std::string unit_path = unit_path_ss.str();
248 std::string unit_name = unit_name_ss.str();
249
250 // Create left and write substreams
251 SubStream i_l(graph);
252 SubStream i_r(graph);
253
254 // Branch 0
255 SubStream i_la(i_l);
256 i_la << ConvolutionLayer(1U, 1U, 32U,
257 get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_weights.npy", weights_layout),
258 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
259 PadStrideInfo(1, 1, 0, 0))
260 .set_name(unit_name + "Branch_0/Conv2d_1x1/convolution")
261 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_mean.npy"),
262 get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_variance.npy"),
263 get_random_accessor(1.f, 1.f),
264 get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_beta.npy"),
265 batch_norm_epsilon)
266 .set_name(unit_name + "Branch_0/Conv2d_1x1/BatchNorm")
267 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_0/Conv2d_1x1/Relu");
268
269 // Branch 1
270 SubStream i_lb(i_l);
271 i_lb << ConvolutionLayer(1U, 1U, 32U,
272 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
273 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
274 PadStrideInfo(1, 1, 0, 0))
275 .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/convolution")
276 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
277 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
278 get_random_accessor(1.f, 1.f),
279 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
280 batch_norm_epsilon)
281 .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/BatchNorm")
282 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0a_1x1/Relu")
283 << ConvolutionLayer(3U, 3U, 32U,
284 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_3x3_weights.npy", weights_layout),
285 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
286 PadStrideInfo(1, 1, 1, 1))
287 .set_name(unit_name + "Branch_1/Conv2d_0b_3x3/convolution")
288 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
289 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
290 get_random_accessor(1.f, 1.f),
291 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_beta.npy"),
292 batch_norm_epsilon)
293 .set_name(unit_name + "Branch_1/Conv2d_0b_3x3/BatchNorm")
294 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0b_3x3/Relu");
295
296 // Branch 2
297 SubStream i_lc(i_l);
298 i_lc << ConvolutionLayer(1U, 1U, 32U,
299 get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
300 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
301 PadStrideInfo(1, 1, 0, 0))
302 .set_name(unit_name + "Branch_2/Conv2d_0a_1x1/convolution")
303 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
304 get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
305 get_random_accessor(1.f, 1.f),
306 get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
307 batch_norm_epsilon)
308 .set_name(unit_name + "Branch_2/Conv2d_0a_1x1/BatchNorm")
309 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_2/Conv2d_0a_1x1/Relu")
310 << ConvolutionLayer(3U, 3U, 32U,
311 get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0b_3x3_weights.npy", weights_layout),
312 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
313 PadStrideInfo(1, 1, 1, 1))
314 .set_name(unit_name + "Branch_2/Conv2d_0b_3x3/convolution")
315 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
316 get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
317 get_random_accessor(1.f, 1.f),
318 get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_beta.npy"),
319 batch_norm_epsilon)
320 .set_name(unit_name + "Branch_2/Conv2d_0b_3x3/BatchNorm")
321 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_2/Conv2d_0b_3x3/Relu")
322 << ConvolutionLayer(3U, 3U, 32U,
323 get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0c_3x3_weights.npy", weights_layout),
324 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
325 PadStrideInfo(1, 1, 1, 1))
326 .set_name(unit_name + "Branch_2/Conv2d_0c_3x3/convolution")
327 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_mean.npy"),
328 get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_variance.npy"),
329 get_random_accessor(1.f, 1.f),
330 get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_beta.npy"),
331 batch_norm_epsilon)
332 .set_name(unit_name + "Branch_2/Conv2d_0c_3x3/BatchNorm")
333 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_2/Conv2d_0c_3x3/Relu");
334
335 // Concatenate
336 i_l << ConcatLayer(std::move(i_la), std::move(i_lb), std::move(i_lc)).set_name(unit_name + "concat")
337 << ConvolutionLayer(1U, 1U, 256U,
338 get_weights_accessor(data_path, unit_path + "Conv2d_1x1_weights.npy", weights_layout),
339 get_weights_accessor(data_path, unit_path + "Conv2d_1x1_biases.npy", weights_layout),
340 PadStrideInfo(1, 1, 0, 0))
341 .set_name(unit_name + "Conv2d_1x1/convolution")
342 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, 0.17f, 0.f)).set_name(unit_name + "mul");
343
344 graph << EltwiseLayer(std::move(i_l), std::move(i_r), EltwiseOperation::Add).set_name(unit_name + "add")
345 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Relu");
346 }
347 }
348
349 void block17_repeat(const std::string &data_path, DataLayout weights_layout, unsigned int num_blocks)
350 {
351 for(unsigned int i = 0; i < num_blocks; ++i)
352 {
353 std::stringstream unit_path_ss;
354 unit_path_ss << "Repeat_1_block17_" << (i + 1) << "_";
355 std::stringstream unit_name_ss;
356 unit_name_ss << "Repeat_1/block17_" << (i + 1) << "/";
357
358 std::string unit_path = unit_path_ss.str();
359 std::string unit_name = unit_name_ss.str();
360
361 // Create left and write substreams
362 SubStream i_l(graph);
363 SubStream i_r(graph);
364
365 // Branch 0
366 SubStream i_la(i_l);
367 i_la << ConvolutionLayer(1U, 1U, 128U,
368 get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_weights.npy", weights_layout),
369 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
370 PadStrideInfo(1, 1, 0, 0))
371 .set_name(unit_name + "Branch_0/Conv2d_1x1/convolution")
372 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_mean.npy"),
373 get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_variance.npy"),
374 get_random_accessor(1.f, 1.f),
375 get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_beta.npy"),
376 batch_norm_epsilon)
377 .set_name(unit_name + "Branch_0/Conv2d_1x1/BatchNorm")
378 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_0/Conv2d_1x1/Relu");
379
380 // Branch 1
381 SubStream i_lb(i_l);
382 i_lb << ConvolutionLayer(1U, 1U, 128U,
383 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
384 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
385 PadStrideInfo(1, 1, 0, 0))
386 .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/convolution")
387 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
388 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
389 get_random_accessor(1.f, 1.f),
390 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
391 batch_norm_epsilon)
392 .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/BatchNorm")
393 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0a_1x1/Relu")
394 << ConvolutionLayer(7U, 1U, 128U,
395 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
396 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
397 PadStrideInfo(1, 1, 3, 0))
398 .set_name(unit_name + "Branch_1/Conv2d_0b_1x7/convolution")
399 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"),
400 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
401 get_random_accessor(1.f, 1.f),
402 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"),
403 batch_norm_epsilon)
404 .set_name(unit_name + "Branch_1/Conv2d_0b_1x7/BatchNorm")
405 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0b_1x7/Relu")
406 << ConvolutionLayer(1U, 7U, 128U,
407 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
408 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
409 PadStrideInfo(1, 1, 0, 3))
410 .set_name(unit_name + "Branch_1/Conv2d_0c_7x1/convolution")
411 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"),
412 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
413 get_random_accessor(1.f, 1.f),
414 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"),
415 batch_norm_epsilon)
416 .set_name(unit_name + "Branch_1/Conv2d_0c_7x1/BatchNorm")
417 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0c_7x1/Relu");
418
419 // Concatenate
420 i_l << ConcatLayer(std::move(i_la), std::move(i_lb)).set_name(unit_name + "concat")
421 << ConvolutionLayer(1U, 1U, 896U,
422 get_weights_accessor(data_path, unit_path + "Conv2d_1x1_weights.npy", weights_layout),
423 get_weights_accessor(data_path, unit_path + "Conv2d_1x1_biases.npy", weights_layout),
424 PadStrideInfo(1, 1, 0, 0))
425 .set_name(unit_name + "Conv2d_1x1/convolution")
426 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, 0.10f, 0.f)).set_name(unit_name + "mul");
427
428 graph << EltwiseLayer(std::move(i_l), std::move(i_r), EltwiseOperation::Add).set_name(unit_name + "add")
429 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Relu");
430 }
431 }
432
433 void block8_repeat(const std::string &data_path, DataLayout weights_layout, unsigned int num_blocks, float scale, bool has_activation)
434 {
435 for(unsigned int i = 0; i < num_blocks; ++i)
436 {
437 std::stringstream unit_path_ss;
438 std::stringstream unit_name_ss;
439 if(num_blocks != 1)
440 {
441 unit_path_ss << "Repeat_2_block8_" << (i + 1) << "_";
442 unit_name_ss << "Repeat_2/block8_" << (i + 1) << "/";
443 }
444 else
445 {
446 unit_path_ss << "Block8_";
447 unit_name_ss << "Block8/";
448 }
449
450 std::string unit_path = unit_path_ss.str();
451 std::string unit_name = unit_name_ss.str();
452
453 // Create left and write substreams
454 SubStream i_l(graph);
455 SubStream i_r(graph);
456
457 // Branch 0
458 SubStream i_la(i_l);
459 i_la << ConvolutionLayer(1U, 1U, 192U,
460 get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_weights.npy", weights_layout),
461 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
462 PadStrideInfo(1, 1, 0, 0))
463 .set_name(unit_name + "Branch_0/Conv2d_1x1/convolution")
464 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_mean.npy"),
465 get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_variance.npy"),
466 get_random_accessor(1.f, 1.f),
467 get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_beta.npy"),
468 batch_norm_epsilon)
469 .set_name(unit_name + "Branch_0/Conv2d_1x1/BatchNorm")
470 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_0/Conv2d_1x1/Relu");
471
472 // Branch 1
473 SubStream i_lb(i_l);
474 i_lb << ConvolutionLayer(1U, 1U, 192U,
475 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
476 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
477 PadStrideInfo(1, 1, 0, 0))
478 .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/convolution")
479 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
480 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
481 get_random_accessor(1.f, 1.f),
482 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
483 batch_norm_epsilon)
484 .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/BatchNorm")
485 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0a_1x1/Relu")
486 << ConvolutionLayer(3U, 1U, 192U,
487 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x3_weights.npy", weights_layout),
488 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
489 PadStrideInfo(1, 1, 1, 0))
490 .set_name(unit_name + "Branch_1/Conv2d_0b_1x3/convolution")
491 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_mean.npy"),
492 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_variance.npy"),
493 get_random_accessor(1.f, 1.f),
494 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_beta.npy"),
495 batch_norm_epsilon)
496 .set_name(unit_name + "Branch_1/Conv2d_0b_1x3/BatchNorm")
497 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0b_1x3/Relu")
498 << ConvolutionLayer(1U, 3U, 192U,
499 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_3x1_weights.npy", weights_layout),
500 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
501 PadStrideInfo(1, 1, 0, 1))
502 .set_name(unit_name + "Branch_1/Conv2d_0c_3x1/convolution")
503 << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_moving_mean.npy"),
504 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_moving_variance.npy"),
505 get_random_accessor(1.f, 1.f),
506 get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_beta.npy"),
507 batch_norm_epsilon)
508 .set_name(unit_name + "Branch_1/Conv2d_0c_3x1/BatchNorm")
509 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0c_3x1/Relu");
510
511 // Concatenate
512 i_l << ConcatLayer(std::move(i_la), std::move(i_lb)).set_name(unit_name + "concat")
513 << ConvolutionLayer(1U, 1U, 1792U,
514 get_weights_accessor(data_path, unit_path + "Conv2d_1x1_weights.npy", weights_layout),
515 get_weights_accessor(data_path, unit_path + "Conv2d_1x1_biases.npy", weights_layout),
516 PadStrideInfo(1, 1, 0, 0))
517 .set_name(unit_name + "Conv2d_1x1/convolution");
518
519 // Scale result
520 if(scale != 1.f)
521 {
522 i_l << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, scale, 0.f)).set_name(unit_name + "mul");
523 }
524
525 // Residual add
526 graph << EltwiseLayer(std::move(i_l), std::move(i_r), EltwiseOperation::Add).set_name(unit_name + "add");
527
528 // Apply activation if needed
529 if(has_activation)
530 {
531 graph << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Relu");
532 }
533 }
534 }
535
536 void reduction_a(const std::string &data_path, DataLayout weights_layout)
537 {
538 // Branch 0
539 SubStream i_a(graph);
540 i_a << ConvolutionLayer(3U, 3U, 384U,
541 get_weights_accessor(data_path, "Mixed_6a_Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
542 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
543 PadStrideInfo(2, 2, 0, 0))
544 .set_name("Mixed_6a/Branch_0/Conv2d_1a_3x3/convolution")
545 << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_6a_Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
546 get_weights_accessor(data_path, "Mixed_6a_Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
547 get_random_accessor(1.f, 1.f),
548 get_weights_accessor(data_path, "Mixed_6a_Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
549 batch_norm_epsilon)
550 .set_name("Mixed_6a/Branch_0/Conv2d_1a_3x3/BatchNorm")
551 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_0/Conv2d_1a_3x3/Relu");
552
553 // Branch 1
554 SubStream i_b(graph);
555 i_b << ConvolutionLayer(1U, 1U, 192U,
556 get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
557 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
558 PadStrideInfo(1, 1, 0, 0))
559 .set_name("Mixed_6a/Branch_1/Conv2d_0a_1x1/convolution")
560 << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
561 get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
562 get_random_accessor(1.f, 1.f),
563 get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
564 batch_norm_epsilon)
565 .set_name("Mixed_6a/Branch_1/Conv2d_0a_1x1/BatchNorm")
566 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_1/Conv2d_0a_1x1/Relu")
567 << ConvolutionLayer(3U, 3U, 192U,
568 get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0b_3x3_weights.npy", weights_layout),
569 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
570 PadStrideInfo(1, 1, 1, 1))
571 .set_name("Mixed_6a/Branch_1/Conv2d_0b_3x3/convolution")
572 << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
573 get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
574 get_random_accessor(1.f, 1.f),
575 get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0b_3x3_BatchNorm_beta.npy"),
576 batch_norm_epsilon)
577 .set_name("Mixed_6a/Branch_1/Conv2d_0b_3x3/BatchNorm")
578 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_1/Conv2d_0b_3x3/Relu")
579 << ConvolutionLayer(3U, 3U, 256U,
580 get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
581 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
582 PadStrideInfo(2, 2, 0, 0))
583 .set_name("Mixed_6a/Branch_1/Conv2d_1a_3x3/convolution")
584 << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
585 get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
586 get_random_accessor(1.f, 1.f),
587 get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
588 batch_norm_epsilon)
589 .set_name("Mixed_6a/Branch_1/Conv2d_1a_3x3/BatchNorm")
590 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_1/Conv2d_1a_3x3/Relu");
591
592 // Branch 2
593 SubStream i_c(graph);
Sang-Hoon Park11fedda2020-01-15 14:44:04 +0000594 i_c << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, common_params.data_layout, PadStrideInfo(2, 2, 0, 0), true)).set_name("Mixed_6a/Branch_2/MaxPool_1a_3x3");
Georgios Pinitasdacd3de2018-12-04 17:25:48 +0000595
596 // Concatenate
597 graph << ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c)).set_name("Mixed_6a/concat");
598 }
599
600 void reduction_b(const std::string &data_path, DataLayout weights_layout)
601 {
602 // Branch 0
603 SubStream i_a(graph);
604 i_a << ConvolutionLayer(1U, 1U, 256U,
605 get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
606 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
607 PadStrideInfo(1, 1, 0, 0))
608 .set_name("Mixed_7a/Branch_0/Conv2d_0a_1x1/convolution")
609 << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
610 get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
611 get_random_accessor(1.f, 1.f),
612 get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
613 batch_norm_epsilon)
614 .set_name("Mixed_7a/Branch_0/Conv2d_0a_1x1/BatchNorm")
615 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_0/Conv2d_0a_1x1/Relu")
616 << ConvolutionLayer(3U, 3U, 384U,
617 get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
618 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
619 PadStrideInfo(2, 2, 0, 0))
620 .set_name("Mixed_7a/Branch_0/Conv2d_1a_3x3/convolution")
621 << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
622 get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
623 get_random_accessor(1.f, 1.f),
624 get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
625 batch_norm_epsilon)
626 .set_name("Mixed_7a/Branch_0/Conv2d_1a_3x3/BatchNorm")
627 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_0/Conv2d_1a_3x3/Relu");
628
629 // Branch 1
630 SubStream i_b(graph);
631 i_b << ConvolutionLayer(1U, 1U, 256U,
632 get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
633 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
634 PadStrideInfo(1, 1, 0, 0))
635 .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/convolution")
636 << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
637 get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
638 get_random_accessor(1.f, 1.f),
639 get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
640 batch_norm_epsilon)
641 .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/BatchNorm")
642 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/Relu")
643 << ConvolutionLayer(3U, 3U, 256U,
644 get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
645 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
646 PadStrideInfo(2, 2, 0, 0))
647 .set_name("Mixed_7a/Branch_1/Conv2d_1a_3x3/convolution")
648 << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
649 get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
650 get_random_accessor(1.f, 1.f),
651 get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
652 batch_norm_epsilon)
653 .set_name("Mixed_7a/Branch_1/Conv2d_1a_3x3/BatchNorm")
654 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_1/Conv2d_1a_3x3/Relu");
655
656 // Branch 2
657 SubStream i_c(graph);
658 i_c << ConvolutionLayer(1U, 1U, 256U,
659 get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
660 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
661 PadStrideInfo(1, 1, 0, 0))
662 .set_name("Mixed_7a/Branch_2/Conv2d_0a_1x1/convolution")
663 << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
664 get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
665 get_random_accessor(1.f, 1.f),
666 get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
667 batch_norm_epsilon)
668 .set_name("Mixed_7a/Branch_2/Conv2d_0a_1x1/BatchNorm")
669 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_2/Conv2d_0a_1x1/Relu")
670 << ConvolutionLayer(3U, 3U, 256U,
671 get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0b_3x3_weights.npy", weights_layout),
672 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
673 PadStrideInfo(1, 1, 1, 1))
674 .set_name("Mixed_7a/Branch_2/Conv2d_0b_3x3/convolution")
675 << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
676 get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
677 get_random_accessor(1.f, 1.f),
678 get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0b_3x3_BatchNorm_beta.npy"),
679 batch_norm_epsilon)
680 .set_name("Mixed_7a/Branch_2/Conv2d_0b_3x3/BatchNorm")
681 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_2/Conv2d_0b_3x3/Relu")
682 << ConvolutionLayer(3U, 3U, 256U,
683 get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_1a_3x3_weights.npy", weights_layout),
684 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
685 PadStrideInfo(2, 2, 0, 0))
686 .set_name("Mixed_7a/Branch_2/Conv2d_1a_3x3/convolution")
687 << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
688 get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
689 get_random_accessor(1.f, 1.f),
690 get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_1a_3x3_BatchNorm_beta.npy"),
691 batch_norm_epsilon)
692 .set_name("Mixed_7a/Branch_2/Conv2d_1a_3x3/BatchNorm")
693 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_2/Conv2d_1a_3x3/Relu");
694
695 // Branch 3
696 SubStream i_d(graph);
Sang-Hoon Park11fedda2020-01-15 14:44:04 +0000697 i_d << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, common_params.data_layout, PadStrideInfo(2, 2, 0, 0), true)).set_name("Mixed_7a/Branch_3/MaxPool_1a_3x3");
Georgios Pinitasdacd3de2018-12-04 17:25:48 +0000698
699 // Concatenate
700 graph << ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d)).set_name("Mixed_7a/concat");
701 }
702};
703
704/** Main program for Inception ResNet V1
705 *
706 * Model is based on:
707 * https://arxiv.org/abs/1602.07261
708 * "Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning"
709 * Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi
710 *
711 * @note To list all the possible arguments execute the binary appended with the --help option
712 *
713 * @param[in] argc Number of arguments
714 * @param[in] argv Arguments
715 */
716int main(int argc, char **argv)
717{
718 return arm_compute::utils::run_example<InceptionResNetV1Example>(argc, argv);
719}