blob: d4854cff70fdb48be39308c144829e98c0875f1b [file] [log] [blame]
Georgios Pinitas240cfa62018-02-26 19:58:04 +00001/*
2 * Copyright (c) 2018 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 */
Georgios Pinitasd9eb2752018-04-03 13:44:29 +010024#include "arm_compute/graph.h"
Georgios Pinitas240cfa62018-02-26 19:58:04 +000025#include "support/ToolchainSupport.h"
Georgios Pinitas12be7ab2018-07-03 12:06:23 +010026#include "utils/CommonGraphOptions.h"
Georgios Pinitas240cfa62018-02-26 19:58:04 +000027#include "utils/GraphUtils.h"
28#include "utils/Utils.h"
29
Georgios Pinitas240cfa62018-02-26 19:58:04 +000030using namespace arm_compute::utils;
Georgios Pinitasd9eb2752018-04-03 13:44:29 +010031using namespace arm_compute::graph::frontend;
Georgios Pinitas240cfa62018-02-26 19:58:04 +000032using namespace arm_compute::graph_utils;
33
Georgios Pinitas108ab0b2018-09-14 18:35:11 +010034/** Example demonstrating how to implement InceptionV4's network using the Compute Library's graph API */
Georgios Pinitas240cfa62018-02-26 19:58:04 +000035class InceptionV4Example final : public Example
36{
37public:
Georgios Pinitas12be7ab2018-07-03 12:06:23 +010038 InceptionV4Example()
39 : cmd_parser(), common_opts(cmd_parser), common_params(), graph(0, "InceptionV4")
Georgios Pinitas240cfa62018-02-26 19:58:04 +000040 {
Georgios Pinitas12be7ab2018-07-03 12:06:23 +010041 }
42 bool do_setup(int argc, char **argv) override
43 {
44 // Parse arguments
45 cmd_parser.parse(argc, argv);
46
47 // Consume common parameters
48 common_params = consume_common_graph_parameters(common_opts);
49
50 // Return when help menu is requested
51 if(common_params.help)
52 {
53 cmd_parser.print_help(argv[0]);
54 return false;
55 }
56
57 // Checks
Anthony Barbiercdd68c02018-08-23 15:03:41 +010058 ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
59 ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
Georgios Pinitas12be7ab2018-07-03 12:06:23 +010060
61 // Print parameter values
62 std::cout << common_params << std::endl;
63
64 // Get trainable parameters data path
65 std::string data_path = common_params.data_path;
Georgios Pinitas240cfa62018-02-26 19:58:04 +000066
67 // Create a preprocessor object
68 std::unique_ptr<IPreprocessor> preprocessor = arm_compute::support::cpp14::make_unique<TFPreproccessor>();
69
Georgios Pinitase2220552018-07-20 13:23:44 +010070 // Create input descriptor
71 const TensorShape tensor_shape = permute_shape(TensorShape(299U, 299U, 3U, 1U), DataLayout::NCHW, common_params.data_layout);
72 TensorDescriptor input_descriptor = TensorDescriptor(tensor_shape, common_params.data_type).set_layout(common_params.data_layout);
73
74 // Set weights trained layout
75 const DataLayout weights_layout = DataLayout::NCHW;
76
Georgios Pinitas12be7ab2018-07-03 12:06:23 +010077 graph << common_params.target
78 << common_params.fast_math_hint
Georgios Pinitase2220552018-07-20 13:23:44 +010079 << InputLayer(input_descriptor, get_input_accessor(common_params, std::move(preprocessor), false))
Georgios Pinitas240cfa62018-02-26 19:58:04 +000080 // Conv2d_1a_3x3
81 << ConvolutionLayer(3U, 3U, 32U,
Georgios Pinitase2220552018-07-20 13:23:44 +010082 get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +000083 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
84 << BatchNormalizationLayer(get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
85 get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
86 get_random_accessor(1.f, 1.f),
87 get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_BatchNorm_beta.npy"),
88 0.001f)
89 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
90 // Conv2d_2a_3x3
91 << ConvolutionLayer(3U, 3U, 32U,
Georgios Pinitase2220552018-07-20 13:23:44 +010092 get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +000093 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
94 << BatchNormalizationLayer(get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_BatchNorm_moving_mean.npy"),
95 get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_BatchNorm_moving_variance.npy"),
96 get_random_accessor(1.f, 1.f),
97 get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_BatchNorm_beta.npy"),
98 0.001f)
99 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
100 // Conv2d_2b_3x3
101 << ConvolutionLayer(3U, 3U, 64U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100102 get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000103 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
104 << BatchNormalizationLayer(get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_BatchNorm_moving_mean.npy"),
105 get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_BatchNorm_moving_variance.npy"),
106 get_random_accessor(1.f, 1.f),
107 get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_BatchNorm_beta.npy"),
108 0.001f)
Georgios Pinitas41c482d2018-04-17 13:23:26 +0100109 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000110
Georgios Pinitase2220552018-07-20 13:23:44 +0100111 graph << get_mixed_3a(data_path, weights_layout);
112 graph << get_mixed_4a(data_path, weights_layout);
113 graph << get_mixed_5a(data_path, weights_layout);
Georgios Pinitas41c482d2018-04-17 13:23:26 +0100114 // 4 inception A blocks
Georgios Pinitase2220552018-07-20 13:23:44 +0100115 graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5b");
116 graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5c");
117 graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5d");
118 graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5e");
Georgios Pinitas41c482d2018-04-17 13:23:26 +0100119 // reduction A block
Georgios Pinitase2220552018-07-20 13:23:44 +0100120 graph << get_reductionA_block(data_path, weights_layout);
Georgios Pinitas41c482d2018-04-17 13:23:26 +0100121 // 7 inception B blocks
Georgios Pinitase2220552018-07-20 13:23:44 +0100122 graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6b");
123 graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6c");
124 graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6d");
125 graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6e");
126 graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6f");
127 graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6g");
128 graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6h");
Georgios Pinitas41c482d2018-04-17 13:23:26 +0100129 // reduction B block
Georgios Pinitase2220552018-07-20 13:23:44 +0100130 graph << get_reductionB_block(data_path, weights_layout);
Georgios Pinitas41c482d2018-04-17 13:23:26 +0100131 // 3 inception C blocks
Georgios Pinitase2220552018-07-20 13:23:44 +0100132 graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7b");
133 graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7c");
134 graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7d");
Georgios Pinitas41c482d2018-04-17 13:23:26 +0100135 graph << PoolingLayer(PoolingLayerInfo(PoolingType::AVG))
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000136 << FlattenLayer()
137 << FullyConnectedLayer(
138 1001U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100139 get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Logits_Logits_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000140 get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Logits_Logits_biases.npy"))
141 << SoftmaxLayer()
Georgios Pinitas12be7ab2018-07-03 12:06:23 +0100142 << OutputLayer(get_output_accessor(common_params, 5));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000143
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000144 // Finalize graph
Georgios Pinitas9a8c6722018-03-21 17:52:35 +0000145 GraphConfig config;
Georgios Pinitas12be7ab2018-07-03 12:06:23 +0100146 config.num_threads = common_params.threads;
147 config.use_tuner = common_params.enable_tuner;
Anthony Barbier7b607dc2018-07-13 15:55:24 +0100148 config.tuner_file = common_params.tuner_file;
149
Georgios Pinitas12be7ab2018-07-03 12:06:23 +0100150 graph.finalize(common_params.target, config);
151
152 return true;
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000153 }
154
155 void do_run() override
156 {
157 graph.run();
158 }
159
160private:
Georgios Pinitas12be7ab2018-07-03 12:06:23 +0100161 CommandLineParser cmd_parser;
162 CommonGraphOptions common_opts;
163 CommonGraphParams common_params;
164 Stream graph;
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000165
166private:
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100167 ConcatLayer get_mixed_3a(const std::string &data_path, DataLayout weights_layout)
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000168 {
169 std::string total_path = "/cnn_data/inceptionv4_model/Mixed_3a_";
170
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000171 SubStream i_a(graph);
172 i_a << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000173
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000174 SubStream i_b(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000175 i_b << ConvolutionLayer(3U, 3U, 96U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100176 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000177 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
178 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_BatchNorm_moving_mean.npy"),
179 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_BatchNorm_moving_variance.npy"),
180 get_random_accessor(1.f, 1.f),
181 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_BatchNorm_beta.npy"),
182 0.001f)
183 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
184
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100185 return ConcatLayer(std::move(i_a), std::move(i_b));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000186 }
187
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100188 ConcatLayer get_mixed_4a(const std::string &data_path, DataLayout weights_layout)
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000189 {
190 std::string total_path = "/cnn_data/inceptionv4_model/Mixed_4a_";
191
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000192 SubStream i_a(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000193 i_a << ConvolutionLayer(1U, 1U, 64U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100194 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000195 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
196 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
197 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
198 get_random_accessor(1.f, 1.f),
199 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
200 0.001f)
201 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
202 << ConvolutionLayer(3U, 3U, 96U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100203 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000204 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
205 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
206 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
207 get_random_accessor(1.f, 1.f),
208 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
209 0.001f)
210 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
211
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000212 SubStream i_b(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000213 i_b << ConvolutionLayer(1U, 1U, 64U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100214 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000215 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
216 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
217 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
218 get_random_accessor(1.f, 1.f),
219 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
220 0.001f)
221 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
222 << ConvolutionLayer(7U, 1U, 64U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100223 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000224 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
225 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"),
226 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
227 get_random_accessor(1.f, 1.f),
228 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"),
229 0.001f)
230 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
231 << ConvolutionLayer(1U, 7U, 64U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100232 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000233 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
234 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"),
235 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
236 get_random_accessor(1.f, 1.f),
237 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"),
238 0.001f)
239 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
240 << ConvolutionLayer(3U, 3U, 96U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100241 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000242 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
243 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
244 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
245 get_random_accessor(1.f, 1.f),
246 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
247 0.001f)
248 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
249
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100250 return ConcatLayer(std::move(i_a), std::move(i_b));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000251 }
252
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100253 ConcatLayer get_mixed_5a(const std::string &data_path, DataLayout weights_layout)
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000254 {
255 std::string total_path = "/cnn_data/inceptionv4_model/Mixed_5a_";
256
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000257 SubStream i_a(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000258 i_a << ConvolutionLayer(3U, 3U, 192U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100259 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000260 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
261 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
262 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
263 get_random_accessor(1.f, 1.f),
264 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
265 0.001f)
266 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
267
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000268 SubStream i_b(graph);
269 i_b << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000270
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100271 return ConcatLayer(std::move(i_a), std::move(i_b));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000272 }
273
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100274 ConcatLayer get_inceptionA_block(const std::string &data_path, DataLayout weights_layout, std::string &&param_path)
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000275 {
276 std::string total_path = "/cnn_data/inceptionv4_model/" + param_path + "_";
277
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000278 SubStream i_a(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000279 i_a << ConvolutionLayer(1U, 1U, 96U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100280 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000281 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
282 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
283 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
284 get_random_accessor(1.f, 1.f),
285 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
286 0.001f)
287 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
288
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000289 SubStream i_b(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000290 i_b << ConvolutionLayer(1U, 1U, 64U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100291 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000292 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
293 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
294 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
295 get_random_accessor(1.f, 1.f),
296 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
297 0.001f)
298 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
299 << ConvolutionLayer(3U, 3U, 96U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100300 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000301 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
302 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
303 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
304 get_random_accessor(1.f, 1.f),
305 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_beta.npy"),
306 0.001f)
307 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
308
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000309 SubStream i_c(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000310 i_c << ConvolutionLayer(1U, 1U, 64U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100311 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000312 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
313 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
314 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
315 get_random_accessor(1.f, 1.f),
316 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
317 0.001f)
318 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
319 << ConvolutionLayer(3U, 3U, 96U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100320 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000321 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
322 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
323 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
324 get_random_accessor(1.f, 1.f),
325 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_beta.npy"),
326 0.001f)
327 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
328 << ConvolutionLayer(3U, 3U, 96U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100329 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000330 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
331 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_mean.npy"),
332 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_variance.npy"),
333 get_random_accessor(1.f, 1.f),
334 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_beta.npy"),
335 0.001f)
336 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
337
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000338 SubStream i_d(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000339 i_d << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, 3, PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL), true))
340 << ConvolutionLayer(1U, 1U, 96U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100341 get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000342 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
343 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"),
344 get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"),
345 get_random_accessor(1.f, 1.f),
346 get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"),
347 0.001f)
348 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
349
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100350 return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000351 }
352
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100353 ConcatLayer get_reductionA_block(const std::string &data_path, DataLayout weights_layout)
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000354 {
355 std::string total_path = "/cnn_data/inceptionv4_model/Mixed_6a_";
356
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000357 SubStream i_a(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000358 i_a << ConvolutionLayer(3U, 3U, 384U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100359 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000360 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
361 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
362 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
363 get_random_accessor(1.f, 1.f),
364 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
365 0.001f)
366 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
367
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000368 SubStream i_b(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000369 i_b << ConvolutionLayer(1U, 1U, 192U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100370 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000371 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
372 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
373 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
374 get_random_accessor(1.f, 1.f),
375 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
376 0.001f)
377 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
378 << ConvolutionLayer(3U, 3U, 224U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100379 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000380 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
381 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
382 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
383 get_random_accessor(1.f, 1.f),
384 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_beta.npy"),
385 0.001f)
386 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
387 << ConvolutionLayer(3U, 3U, 256U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100388 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000389 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
390 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
391 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
392 get_random_accessor(1.f, 1.f),
393 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
394 0.001f)
395 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
396
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000397 SubStream i_c(graph);
398 i_c << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true));
399
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100400 return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000401 }
402
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100403 ConcatLayer get_inceptionB_block(const std::string &data_path, DataLayout weights_layout, std::string &&param_path)
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000404 {
405 std::string total_path = "/cnn_data/inceptionv4_model/" + param_path + "_";
406
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000407 SubStream i_a(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000408 i_a << ConvolutionLayer(1U, 1U, 384U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100409 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000410 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
411 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
412 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
413 get_random_accessor(1.f, 1.f),
414 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
415 0.001f)
416 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
417
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000418 SubStream i_b(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000419 i_b << ConvolutionLayer(1U, 1U, 192U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100420 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000421 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
422 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
423 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
424 get_random_accessor(1.f, 1.f),
425 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
426 0.001f)
427 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
428 << ConvolutionLayer(7U, 1U, 224U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100429 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000430 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
431 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"),
432 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
433 get_random_accessor(1.f, 1.f),
434 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"),
435 0.001f)
436 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
437 << ConvolutionLayer(1U, 7U, 256U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100438 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000439 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
440 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"),
441 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
442 get_random_accessor(1.f, 1.f),
443 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"),
444 0.001f)
445 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
446
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000447 SubStream i_c(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000448 i_c << ConvolutionLayer(1U, 1U, 192U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100449 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000450 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
451 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
452 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
453 get_random_accessor(1.f, 1.f),
454 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
455 0.001f)
456 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
457 << ConvolutionLayer(1U, 7U, 192U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100458 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000459 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
460 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_moving_mean.npy"),
461 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_moving_variance.npy"),
462 get_random_accessor(1.f, 1.f),
463 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_beta.npy"),
464 0.001f)
465 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
466 << ConvolutionLayer(7U, 1U, 224U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100467 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000468 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
469 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_moving_mean.npy"),
470 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_moving_variance.npy"),
471 get_random_accessor(1.f, 1.f),
472 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_beta.npy"),
473 0.001f)
474 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
475 << ConvolutionLayer(1U, 7U, 224U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100476 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000477 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
478 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_moving_mean.npy"),
479 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_moving_variance.npy"),
480 get_random_accessor(1.f, 1.f),
481 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_beta.npy"),
482 0.001f)
483 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
484 << ConvolutionLayer(7U, 1U, 256U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100485 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000486 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
487 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_moving_mean.npy"),
488 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_moving_variance.npy"),
489 get_random_accessor(1.f, 1.f),
490 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_beta.npy"),
491 0.001f)
492 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
493
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000494 SubStream i_d(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000495 i_d << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, 3, PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL), true))
496 << ConvolutionLayer(1U, 1U, 128U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100497 get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000498 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
499 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"),
500 get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"),
501 get_random_accessor(1.f, 1.f),
502 get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"),
503 0.001f)
504 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
505
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100506 return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000507 }
508
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100509 ConcatLayer get_reductionB_block(const std::string &data_path, DataLayout weights_layout)
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000510 {
511 std::string total_path = "/cnn_data/inceptionv4_model/Mixed_7a_";
512
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000513 SubStream i_a(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000514 i_a << ConvolutionLayer(1U, 1U, 192U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100515 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000516 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
517 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
518 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
519 get_random_accessor(1.f, 1.f),
520 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
521 0.001f)
522 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
523 << ConvolutionLayer(3U, 3U, 192U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100524 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000525 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
526 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
527 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
528 get_random_accessor(1.f, 1.f),
529 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
530 0.001f)
531 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
532
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000533 SubStream i_b(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000534 i_b << ConvolutionLayer(1U, 1U, 256U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100535 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000536 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
537 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
538 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
539 get_random_accessor(1.f, 1.f),
540 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
541 0.001f)
542 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
543 << ConvolutionLayer(7U, 1U, 256U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100544 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000545 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
546 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"),
547 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
548 get_random_accessor(1.f, 1.f),
549 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"),
550 0.001f)
551 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
552 << ConvolutionLayer(1U, 7U, 320U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100553 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000554 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
555 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"),
556 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
557 get_random_accessor(1.f, 1.f),
558 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"),
559 0.001f)
560 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
561 << ConvolutionLayer(3U, 3U, 320U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100562 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000563 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
564 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
565 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
566 get_random_accessor(1.f, 1.f),
567 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
568 0.001f)
569 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
570
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000571 SubStream i_c(graph);
572 i_c << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true));
573
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100574 return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000575 }
576
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100577 ConcatLayer get_inceptionC_block(const std::string &data_path, DataLayout weights_layout, std::string &&param_path)
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000578 {
579 std::string total_path = "/cnn_data/inceptionv4_model/" + param_path + "_";
580
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000581 SubStream i_a(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000582 i_a << ConvolutionLayer(1U, 1U, 256U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100583 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000584 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
585 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
586 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
587 get_random_accessor(1.f, 1.f),
588 get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
589 0.001f)
590 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
591
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000592 SubStream i_b(graph);
593 i_b << ConvolutionLayer(
594 1U, 1U, 384U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100595 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000596 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
597 PadStrideInfo(1, 1, 0, 0))
598 << BatchNormalizationLayer(
599 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
600 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
601 get_random_accessor(1.f, 1.f),
602 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
603 0.001f)
604 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
605
Georgios Pinitas772e17f2018-07-13 12:25:33 +0100606 SubStream i_b1(i_b);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000607 i_b1 << ConvolutionLayer(
608 3U, 1U, 256U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100609 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000610 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
611 PadStrideInfo(1, 1, 1, 0))
612 << BatchNormalizationLayer(
613 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_mean.npy"),
614 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_variance.npy"),
615 get_random_accessor(1.f, 1.f),
616 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_beta.npy"),
617 0.001f)
618 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
619
Georgios Pinitas772e17f2018-07-13 12:25:33 +0100620 SubStream i_b2(i_b);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000621 i_b2 << ConvolutionLayer(
622 1U, 3U, 256U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100623 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000624 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
625 PadStrideInfo(1, 1, 0, 1))
626 << BatchNormalizationLayer(
627 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_moving_mean.npy"),
628 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_moving_variance.npy"),
629 get_random_accessor(1.f, 1.f),
630 get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_beta.npy"),
631 0.001f)
632 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
633
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000634 // Merge b1 and b2
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100635 i_b << ConcatLayer(std::move(i_b1), std::move(i_b2));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000636
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000637 SubStream i_c(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000638 i_c << ConvolutionLayer(
639 1U, 1U, 384U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100640 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000641 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
642 PadStrideInfo(1, 1, 0, 0))
643 << BatchNormalizationLayer(
644 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
645 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
646 get_random_accessor(1.f, 1.f),
647 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
648 0.001f)
649 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
650 << ConvolutionLayer(
651 1U, 3U, 448U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100652 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000653 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
654 PadStrideInfo(1, 1, 0, 1))
655 << BatchNormalizationLayer(
656 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_BatchNorm_moving_mean.npy"),
657 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_BatchNorm_moving_variance.npy"),
658 get_random_accessor(1.f, 1.f),
659 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_BatchNorm_beta.npy"),
660 0.001f)
661 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
662 << ConvolutionLayer(
663 3U, 1U, 512U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100664 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000665 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
666 PadStrideInfo(1, 1, 1, 0))
667 << BatchNormalizationLayer(
668 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_moving_mean.npy"),
669 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_moving_variance.npy"),
670 get_random_accessor(1.f, 1.f),
671 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_beta.npy"),
672 0.001f)
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000673 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000674
Georgios Pinitas772e17f2018-07-13 12:25:33 +0100675 SubStream i_c1(i_c);
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000676 i_c1 << ConvolutionLayer(
677 3U, 1U, 256U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100678 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_weights.npy", weights_layout),
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000679 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
680 PadStrideInfo(1, 1, 1, 0))
681 << BatchNormalizationLayer(
682 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_BatchNorm_moving_mean.npy"),
683 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_BatchNorm_moving_variance.npy"),
684 get_random_accessor(1.f, 1.f),
685 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_BatchNorm_beta.npy"),
686 0.001f)
687 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
688
Georgios Pinitas772e17f2018-07-13 12:25:33 +0100689 SubStream i_c2(i_c);
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000690 i_c2 << ConvolutionLayer(
691 1U, 3U, 256U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100692 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_weights.npy", weights_layout),
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000693 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
694 PadStrideInfo(1, 1, 0, 1))
695 << BatchNormalizationLayer(
696 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_BatchNorm_moving_mean.npy"),
697 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_BatchNorm_moving_variance.npy"),
698 get_random_accessor(1.f, 1.f),
699 get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_BatchNorm_beta.npy"),
700 0.001f)
701 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
702
703 // Merge i_c1 and i_c2
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100704 i_c << ConcatLayer(std::move(i_c1), std::move(i_c2));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000705
706 SubStream i_d(graph);
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000707 i_d << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, 3, PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL), true))
708 << ConvolutionLayer(1U, 1U, 256U,
Georgios Pinitase2220552018-07-20 13:23:44 +0100709 get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_weights.npy", weights_layout),
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000710 std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
711 << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"),
712 get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"),
713 get_random_accessor(1.f, 1.f),
714 get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"),
715 0.001f)
716 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
717
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100718 return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d));
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000719 }
720};
721
722/** Main program for Inception V4
723 *
Georgios Pinitasbdbbbe82018-11-07 16:06:47 +0000724 * Model is based on:
725 * https://arxiv.org/abs/1602.07261
726 * "Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning"
727 * Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi
728 *
Georgios Pinitas9f28b392018-07-18 20:01:53 +0100729 * @note To list all the possible arguments execute the binary appended with the --help option
730 *
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000731 * @param[in] argc Number of arguments
Georgios Pinitas12be7ab2018-07-03 12:06:23 +0100732 * @param[in] argv Arguments
Georgios Pinitas240cfa62018-02-26 19:58:04 +0000733 */
734int main(int argc, char **argv)
735{
736 return arm_compute::utils::run_example<InceptionV4Example>(argc, argv);
737}