37 class InceptionResNetV1Example final :
public Example 40 InceptionResNetV1Example()
41 : cmd_parser(), common_opts(cmd_parser), common_params(), model_input_width(
nullptr), model_input_height(
nullptr), graph(0,
"InceptionResNetV1")
47 model_input_width->
set_help(
"Input image width.");
48 model_input_height->
set_help(
"Input image height.");
50 InceptionResNetV1Example(
const InceptionResNetV1Example &) =
delete;
51 InceptionResNetV1Example &operator=(
const InceptionResNetV1Example &) =
delete;
52 ~InceptionResNetV1Example()
override =
default;
53 bool do_setup(
int argc,
char **argv)
override 56 cmd_parser.parse(argc, argv);
57 cmd_parser.validate();
63 if(common_params.help)
65 cmd_parser.print_help(argv[0]);
69 const unsigned int image_width = model_input_width->value();
70 const unsigned int image_height = model_input_height->value();
73 if(!common_opts.data_layout->is_set() && common_params.target ==
Target::NEON)
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;
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())
91 data_path += model_path;
95 std::unique_ptr<IPreprocessor> preprocessor = std::make_unique<TFPreproccessor>(0.f, 1.f);
98 const auto operation_layout = common_params.data_layout;
105 graph << common_params.target
106 << common_params.fast_math_hint
111 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
112 PadStrideInfo(2, 2, 0, 0))
113 .
set_name(
"Conv2d_1a_3x3/convolution")
119 .
set_name(
"Conv2d_1a_3x3/BatchNorm")
124 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
125 PadStrideInfo(1, 1, 0, 0))
126 .
set_name(
"Conv2d_2a_3x3/convolution")
132 .
set_name(
"Conv2d_2a_3x3/BatchNorm")
137 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
138 PadStrideInfo(1, 1, 1, 1))
139 .
set_name(
"Conv2d_2b_3x3/convolution")
145 .
set_name(
"Conv2d_2b_3x3/BatchNorm")
152 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
153 PadStrideInfo(1, 1, 0, 0))
154 .
set_name(
"Conv2d_3b_1x1/convolution")
160 .
set_name(
"Conv2d_3b_1x1/BatchNorm")
165 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
166 PadStrideInfo(1, 1, 0, 0))
167 .
set_name(
"Conv2d_4a_3x3/convolution")
173 .
set_name(
"Conv2d_4a_3x3/BatchNorm")
178 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
179 PadStrideInfo(2, 2, 0, 0))
180 .
set_name(
"Conv2d_4a_3x3/convolution")
186 .
set_name(
"Conv2d_4b_3x3/BatchNorm")
190 block35_repeat(data_path, weights_layout, 5);
192 reduction_a(data_path, weights_layout);
194 block17_repeat(data_path, weights_layout, 10);
196 reduction_b(data_path, weights_layout);
198 block8_repeat(data_path, weights_layout, 5, 0.2f,
true);
200 block8_repeat(data_path, weights_layout, 1, 1.f,
false);
210 <<
OutputLayer(std::make_unique<DummyAccessor>(0));
215 config.
use_tuner = common_params.enable_tuner;
218 config.
mlgo_file = common_params.mlgo_file;
220 graph.finalize(common_params.target, config);
225 void do_run()
override 239 void block35_repeat(
const std::string &data_path,
DataLayout weights_layout,
unsigned int num_blocks)
241 for(
unsigned int i = 0; i < num_blocks; ++i)
243 std::stringstream unit_path_ss;
244 unit_path_ss <<
"Repeat_block35_" << (i + 1) <<
"_";
245 std::stringstream unit_name_ss;
246 unit_name_ss <<
"Repeat/block35_" << (i + 1) <<
"/";
248 std::string unit_path = unit_path_ss.str();
249 std::string unit_name = unit_name_ss.str();
259 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
260 PadStrideInfo(1, 1, 0, 0))
261 .
set_name(unit_name +
"Branch_0/Conv2d_1x1/convolution")
263 get_weights_accessor(data_path, unit_path +
"Branch_0_Conv2d_1x1_BatchNorm_moving_variance.npy"),
267 .
set_name(unit_name +
"Branch_0/Conv2d_1x1/BatchNorm")
273 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
274 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
275 PadStrideInfo(1, 1, 0, 0))
276 .
set_name(unit_name +
"Branch_1/Conv2d_0a_1x1/convolution")
278 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
282 .
set_name(unit_name +
"Branch_1/Conv2d_0a_1x1/BatchNorm")
285 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0b_3x3_weights.npy", weights_layout),
286 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
287 PadStrideInfo(1, 1, 1, 1))
288 .
set_name(unit_name +
"Branch_1/Conv2d_0b_3x3/convolution")
290 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
294 .
set_name(unit_name +
"Branch_1/Conv2d_0b_3x3/BatchNorm")
300 get_weights_accessor(data_path, unit_path +
"Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
301 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
302 PadStrideInfo(1, 1, 0, 0))
303 .
set_name(unit_name +
"Branch_2/Conv2d_0a_1x1/convolution")
305 get_weights_accessor(data_path, unit_path +
"Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
309 .
set_name(unit_name +
"Branch_2/Conv2d_0a_1x1/BatchNorm")
312 get_weights_accessor(data_path, unit_path +
"Branch_2_Conv2d_0b_3x3_weights.npy", weights_layout),
313 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
314 PadStrideInfo(1, 1, 1, 1))
315 .
set_name(unit_name +
"Branch_2/Conv2d_0b_3x3/convolution")
317 get_weights_accessor(data_path, unit_path +
"Branch_2_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
321 .
set_name(unit_name +
"Branch_2/Conv2d_0b_3x3/BatchNorm")
324 get_weights_accessor(data_path, unit_path +
"Branch_2_Conv2d_0c_3x3_weights.npy", weights_layout),
325 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
326 PadStrideInfo(1, 1, 1, 1))
327 .
set_name(unit_name +
"Branch_2/Conv2d_0c_3x3/convolution")
329 get_weights_accessor(data_path, unit_path +
"Branch_2_Conv2d_0c_3x3_BatchNorm_moving_variance.npy"),
333 .
set_name(unit_name +
"Branch_2/Conv2d_0c_3x3/BatchNorm")
337 i_l <<
ConcatLayer(std::move(i_la), std::move(i_lb), std::move(i_lc)).
set_name(unit_name +
"concat")
341 PadStrideInfo(1, 1, 0, 0))
342 .
set_name(unit_name +
"Conv2d_1x1/convolution")
345 graph <<
EltwiseLayer(std::move(i_l), std::move(i_r), EltwiseOperation::Add).
set_name(unit_name +
"add")
350 void block17_repeat(
const std::string &data_path,
DataLayout weights_layout,
unsigned int num_blocks)
352 for(
unsigned int i = 0; i < num_blocks; ++i)
354 std::stringstream unit_path_ss;
355 unit_path_ss <<
"Repeat_1_block17_" << (i + 1) <<
"_";
356 std::stringstream unit_name_ss;
357 unit_name_ss <<
"Repeat_1/block17_" << (i + 1) <<
"/";
359 std::string unit_path = unit_path_ss.str();
360 std::string unit_name = unit_name_ss.str();
370 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
371 PadStrideInfo(1, 1, 0, 0))
372 .
set_name(unit_name +
"Branch_0/Conv2d_1x1/convolution")
374 get_weights_accessor(data_path, unit_path +
"Branch_0_Conv2d_1x1_BatchNorm_moving_variance.npy"),
378 .
set_name(unit_name +
"Branch_0/Conv2d_1x1/BatchNorm")
384 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
385 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
386 PadStrideInfo(1, 1, 0, 0))
387 .
set_name(unit_name +
"Branch_1/Conv2d_0a_1x1/convolution")
389 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
393 .
set_name(unit_name +
"Branch_1/Conv2d_0a_1x1/BatchNorm")
396 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
397 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
398 PadStrideInfo(1, 1, 3, 0))
399 .
set_name(unit_name +
"Branch_1/Conv2d_0b_1x7/convolution")
401 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
405 .
set_name(unit_name +
"Branch_1/Conv2d_0b_1x7/BatchNorm")
408 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
409 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
410 PadStrideInfo(1, 1, 0, 3))
411 .
set_name(unit_name +
"Branch_1/Conv2d_0c_7x1/convolution")
413 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
417 .
set_name(unit_name +
"Branch_1/Conv2d_0c_7x1/BatchNorm")
425 PadStrideInfo(1, 1, 0, 0))
426 .
set_name(unit_name +
"Conv2d_1x1/convolution")
429 graph <<
EltwiseLayer(std::move(i_l), std::move(i_r), EltwiseOperation::Add).
set_name(unit_name +
"add")
434 void block8_repeat(
const std::string &data_path,
DataLayout weights_layout,
unsigned int num_blocks,
float scale,
bool has_activation)
436 for(
unsigned int i = 0; i < num_blocks; ++i)
438 std::stringstream unit_path_ss;
439 std::stringstream unit_name_ss;
442 unit_path_ss <<
"Repeat_2_block8_" << (i + 1) <<
"_";
443 unit_name_ss <<
"Repeat_2/block8_" << (i + 1) <<
"/";
447 unit_path_ss <<
"Block8_";
448 unit_name_ss <<
"Block8/";
451 std::string unit_path = unit_path_ss.str();
452 std::string unit_name = unit_name_ss.str();
462 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
463 PadStrideInfo(1, 1, 0, 0))
464 .
set_name(unit_name +
"Branch_0/Conv2d_1x1/convolution")
466 get_weights_accessor(data_path, unit_path +
"Branch_0_Conv2d_1x1_BatchNorm_moving_variance.npy"),
470 .
set_name(unit_name +
"Branch_0/Conv2d_1x1/BatchNorm")
476 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
477 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
478 PadStrideInfo(1, 1, 0, 0))
479 .
set_name(unit_name +
"Branch_1/Conv2d_0a_1x1/convolution")
481 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
485 .
set_name(unit_name +
"Branch_1/Conv2d_0a_1x1/BatchNorm")
488 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0b_1x3_weights.npy", weights_layout),
489 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
490 PadStrideInfo(1, 1, 1, 0))
491 .
set_name(unit_name +
"Branch_1/Conv2d_0b_1x3/convolution")
493 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0b_1x3_BatchNorm_moving_variance.npy"),
497 .
set_name(unit_name +
"Branch_1/Conv2d_0b_1x3/BatchNorm")
500 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0c_3x1_weights.npy", weights_layout),
501 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
502 PadStrideInfo(1, 1, 0, 1))
503 .
set_name(unit_name +
"Branch_1/Conv2d_0c_3x1/convolution")
505 get_weights_accessor(data_path, unit_path +
"Branch_1_Conv2d_0c_3x1_BatchNorm_moving_variance.npy"),
509 .
set_name(unit_name +
"Branch_1/Conv2d_0c_3x1/BatchNorm")
517 PadStrideInfo(1, 1, 0, 0))
518 .
set_name(unit_name +
"Conv2d_1x1/convolution");
527 graph <<
EltwiseLayer(std::move(i_l), std::move(i_r), EltwiseOperation::Add).
set_name(unit_name +
"add");
537 void reduction_a(
const std::string &data_path,
DataLayout weights_layout)
543 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
544 PadStrideInfo(2, 2, 0, 0))
545 .
set_name(
"Mixed_6a/Branch_0/Conv2d_1a_3x3/convolution")
547 get_weights_accessor(data_path,
"Mixed_6a_Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
551 .
set_name(
"Mixed_6a/Branch_0/Conv2d_1a_3x3/BatchNorm")
558 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
559 PadStrideInfo(1, 1, 0, 0))
560 .
set_name(
"Mixed_6a/Branch_1/Conv2d_0a_1x1/convolution")
562 get_weights_accessor(data_path,
"Mixed_6a_Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
566 .
set_name(
"Mixed_6a/Branch_1/Conv2d_0a_1x1/BatchNorm")
570 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
571 PadStrideInfo(1, 1, 1, 1))
572 .
set_name(
"Mixed_6a/Branch_1/Conv2d_0b_3x3/convolution")
574 get_weights_accessor(data_path,
"Mixed_6a_Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
578 .
set_name(
"Mixed_6a/Branch_1/Conv2d_0b_3x3/BatchNorm")
582 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
583 PadStrideInfo(2, 2, 0, 0))
584 .
set_name(
"Mixed_6a/Branch_1/Conv2d_1a_3x3/convolution")
586 get_weights_accessor(data_path,
"Mixed_6a_Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
590 .
set_name(
"Mixed_6a/Branch_1/Conv2d_1a_3x3/BatchNorm")
598 graph <<
ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c)).
set_name(
"Mixed_6a/concat");
601 void reduction_b(
const std::string &data_path,
DataLayout weights_layout)
607 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
608 PadStrideInfo(1, 1, 0, 0))
609 .
set_name(
"Mixed_7a/Branch_0/Conv2d_0a_1x1/convolution")
611 get_weights_accessor(data_path,
"Mixed_7a_Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
615 .
set_name(
"Mixed_7a/Branch_0/Conv2d_0a_1x1/BatchNorm")
619 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
620 PadStrideInfo(2, 2, 0, 0))
621 .
set_name(
"Mixed_7a/Branch_0/Conv2d_1a_3x3/convolution")
623 get_weights_accessor(data_path,
"Mixed_7a_Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
627 .
set_name(
"Mixed_7a/Branch_0/Conv2d_1a_3x3/BatchNorm")
634 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
635 PadStrideInfo(1, 1, 0, 0))
636 .
set_name(
"Mixed_7a/Branch_1/Conv2d_0a_1x1/convolution")
638 get_weights_accessor(data_path,
"Mixed_7a_Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
642 .
set_name(
"Mixed_7a/Branch_1/Conv2d_0a_1x1/BatchNorm")
646 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
647 PadStrideInfo(2, 2, 0, 0))
648 .
set_name(
"Mixed_7a/Branch_1/Conv2d_1a_3x3/convolution")
650 get_weights_accessor(data_path,
"Mixed_7a_Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
654 .
set_name(
"Mixed_7a/Branch_1/Conv2d_1a_3x3/BatchNorm")
661 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
662 PadStrideInfo(1, 1, 0, 0))
663 .
set_name(
"Mixed_7a/Branch_2/Conv2d_0a_1x1/convolution")
665 get_weights_accessor(data_path,
"Mixed_7a_Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
669 .
set_name(
"Mixed_7a/Branch_2/Conv2d_0a_1x1/BatchNorm")
673 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
674 PadStrideInfo(1, 1, 1, 1))
675 .
set_name(
"Mixed_7a/Branch_2/Conv2d_0b_3x3/convolution")
677 get_weights_accessor(data_path,
"Mixed_7a_Branch_2_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
681 .
set_name(
"Mixed_7a/Branch_2/Conv2d_0b_3x3/BatchNorm")
685 std::unique_ptr<arm_compute::graph::ITensorAccessor>(
nullptr),
686 PadStrideInfo(2, 2, 0, 0))
687 .
set_name(
"Mixed_7a/Branch_2/Conv2d_1a_3x3/convolution")
689 get_weights_accessor(data_path,
"Mixed_7a_Branch_2_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
693 .
set_name(
"Mixed_7a/Branch_2/Conv2d_1a_3x3/BatchNorm")
701 graph <<
ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d)).
set_name(
"Mixed_7a/concat");
717 int main(
int argc,
char **argv)
719 return arm_compute::utils::run_example<InceptionResNetV1Example>(argc, argv);
Graph configuration structure Device target types.
CLTunerMode tuner_mode
Tuner mode to be used by the CL tuner.
std::unique_ptr< graph::ITensorAccessor > get_input_accessor(const arm_compute::utils::CommonGraphParams &graph_parameters, std::unique_ptr< IPreprocessor > preprocessor=nullptr, bool bgr=true)
Generates appropriate input accessor according to the specified graph parameters. ...
void consume_common_graph_parameters(CommonGraphValidateOptions &options, CommonParams &common_params)
Consumes the consume_common_graph_parameters graph options and creates a structure containing any inf...
Includes all the Graph headers at once.
Common command line options used to configure the graph examples.
Class to parse command line arguments.
arm_compute::DataLayout data_layout
std::string mlgo_file
Filename to load MLGO heuristics from.
std::unique_ptr< graph::ITensorAccessor > get_random_accessor(PixelValue lower, PixelValue upper, const std::random_device::result_type seed=0)
Generates appropriate random accessor.
std::string tuner_file
File to load/store tuning values from.
#define ARM_COMPUTE_EXIT_ON_MSG(cond, msg)
If the condition is true, the given message is printed and program exits.
Num samples, channels, height, width.
TensorShape permute_shape(TensorShape tensor_shape, DataLayout in_data_layout, DataLayout out_data_layout)
Permutes a given tensor shape given the input and output data layout.
bool is_data_type_quantized_asymmetric(DataType dt)
Check if a given data type is of asymmetric quantized type.
TensorDescriptor & set_layout(DataLayout data_layout)
Sets tensor descriptor data layout.
Structure holding all the common graph parameters.
bool use_tuner
Use a tuner in tunable backends.
std::unique_ptr< graph::ITensorAccessor > get_weights_accessor(const std::string &path, const std::string &data_file, DataLayout file_layout=DataLayout::NCHW)
Generates appropriate weights accessor according to the specified path.
int num_threads
Number of threads to use (thread capable backends), if 0 the backend will auto-initialize, if -1 the backend will stay as it is.
int main(int argc, char **argv)
Main program for Inception ResNet V1.
Stream frontend class to construct simple graphs in a stream fashion.
Batchnormalization Layer.
DataLayout
[DataLayout enum definition]
ILayer & set_name(std::string name)
Sets the name of the layer.
void set_help(std::string help)
Set the help message for the option.
const float batch_norm_epsilon