arm_compute v19.02
Change-Id: I853a3ecf38f206da13c1b03640c8adf73c20477c
diff --git a/examples/SConscript b/examples/SConscript
index 56dac0d..7af8a7f 100644
--- a/examples/SConscript
+++ b/examples/SConscript
@@ -103,3 +103,20 @@
Depends(prog, arm_compute_dependency)
alias = examples_env.Alias(example, prog)
Default(alias)
+
+#FIXME Delete 3rdparty builds before release
+for file in Glob("#3rdparty/examples/graph_*.cpp"):
+ example = os.path.basename(os.path.splitext(str(file))[0])
+ prog = None
+
+ if env['os'] in ['android', 'bare_metal'] or env['standalone']:
+ prog = examples_env.Program(example, [examples_env.Object(source=file, target=example), utils, graph_utils], LIBS = examples_libs + arm_compute_graph_libs, LINKFLAGS=examples_env["LINKFLAGS"]+['-Wl,--whole-archive',graph_dependency,'-Wl,--no-whole-archive'])
+ prog = install_bin(prog)
+ Depends(prog, graph_dependency)
+ else:
+ #-Wl,--allow-shlib-undefined: Ignore dependencies of dependencies
+ prog = examples_env.Program(example, [examples_env.Object(source=file, target=example), utils, graph_utils], LIBS = examples_libs + arm_compute_graph_libs, LINKFLAGS=examples_env["LINKFLAGS"]+['-Wl,--allow-shlib-undefined'] )
+ prog = install_bin(prog)
+ Depends(prog, graph_dependency)
+ alias = examples_env.Alias(example, prog)
+ Default(alias)
diff --git a/examples/graph_alexnet.cpp b/examples/graph_alexnet.cpp
index cfa8e94..989e232 100644
--- a/examples/graph_alexnet.cpp
+++ b/examples/graph_alexnet.cpp
@@ -176,6 +176,8 @@
* "ImageNet Classification with Deep Convolutional Neural Networks"
* Alex Krizhevsky and Sutskever, Ilya and Hinton, Geoffrey E
*
+ * Provenance: https://github.com/BVLC/caffe/tree/master/models/bvlc_alexnet
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_googlenet.cpp b/examples/graph_googlenet.cpp
index 0b3ecff..583ca2c 100644
--- a/examples/graph_googlenet.cpp
+++ b/examples/graph_googlenet.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -56,7 +56,6 @@
// Checks
ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
- ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
// Print parameter values
std::cout << common_params << std::endl;
@@ -83,40 +82,44 @@
get_weights_accessor(data_path, "/cnn_data/googlenet_model/conv1/conv1_7x7_s2_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/googlenet_model/conv1/conv1_7x7_s2_b.npy"),
PadStrideInfo(2, 2, 3, 3))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
- << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)))
- << NormalizationLayer(NormalizationLayerInfo(NormType::CROSS_MAP, 5, 0.0001f, 0.75f))
+ .set_name("conv1/7x7_s2")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv1/relu_7x7")
+ << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL))).set_name("pool1/3x3_s2")
+ << NormalizationLayer(NormalizationLayerInfo(NormType::CROSS_MAP, 5, 0.0001f, 0.75f)).set_name("pool1/norm1")
<< ConvolutionLayer(
1U, 1U, 64U,
get_weights_accessor(data_path, "/cnn_data/googlenet_model/conv2/conv2_3x3_reduce_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/googlenet_model/conv2/conv2_3x3_reduce_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("conv2/3x3_reduce")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv2/relu_3x3_reduce")
<< ConvolutionLayer(
3U, 3U, 192U,
get_weights_accessor(data_path, "/cnn_data/googlenet_model/conv2/conv2_3x3_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/googlenet_model/conv2/conv2_3x3_b.npy"),
PadStrideInfo(1, 1, 1, 1))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
- << NormalizationLayer(NormalizationLayerInfo(NormType::CROSS_MAP, 5, 0.0001f, 0.75f))
- << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)));
- graph << get_inception_node(data_path, "inception_3a", weights_layout, 64, std::make_tuple(96U, 128U), std::make_tuple(16U, 32U), 32U);
- graph << get_inception_node(data_path, "inception_3b", weights_layout, 128, std::make_tuple(128U, 192U), std::make_tuple(32U, 96U), 64U);
- graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)));
- graph << get_inception_node(data_path, "inception_4a", weights_layout, 192, std::make_tuple(96U, 208U), std::make_tuple(16U, 48U), 64U);
- graph << get_inception_node(data_path, "inception_4b", weights_layout, 160, std::make_tuple(112U, 224U), std::make_tuple(24U, 64U), 64U);
- graph << get_inception_node(data_path, "inception_4c", weights_layout, 128, std::make_tuple(128U, 256U), std::make_tuple(24U, 64U), 64U);
- graph << get_inception_node(data_path, "inception_4d", weights_layout, 112, std::make_tuple(144U, 288U), std::make_tuple(32U, 64U), 64U);
- graph << get_inception_node(data_path, "inception_4e", weights_layout, 256, std::make_tuple(160U, 320U), std::make_tuple(32U, 128U), 128U);
- graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)));
- graph << get_inception_node(data_path, "inception_5a", weights_layout, 256, std::make_tuple(160U, 320U), std::make_tuple(32U, 128U), 128U);
- graph << get_inception_node(data_path, "inception_5b", weights_layout, 384, std::make_tuple(192U, 384U), std::make_tuple(48U, 128U), 128U);
- graph << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, 7, PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL)))
+ .set_name("conv2/3x3")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv2/relu_3x3")
+ << NormalizationLayer(NormalizationLayerInfo(NormType::CROSS_MAP, 5, 0.0001f, 0.75f)).set_name("conv2/norm2")
+ << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL))).set_name("pool2/3x3_s2");
+ graph << get_inception_node(data_path, "inception_3a", weights_layout, 64, std::make_tuple(96U, 128U), std::make_tuple(16U, 32U), 32U).set_name("inception_3a/concat");
+ graph << get_inception_node(data_path, "inception_3b", weights_layout, 128, std::make_tuple(128U, 192U), std::make_tuple(32U, 96U), 64U).set_name("inception_3b/concat");
+ graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL))).set_name("pool3/3x3_s2");
+ graph << get_inception_node(data_path, "inception_4a", weights_layout, 192, std::make_tuple(96U, 208U), std::make_tuple(16U, 48U), 64U).set_name("inception_4a/concat");
+ graph << get_inception_node(data_path, "inception_4b", weights_layout, 160, std::make_tuple(112U, 224U), std::make_tuple(24U, 64U), 64U).set_name("inception_4b/concat");
+ graph << get_inception_node(data_path, "inception_4c", weights_layout, 128, std::make_tuple(128U, 256U), std::make_tuple(24U, 64U), 64U).set_name("inception_4c/concat");
+ graph << get_inception_node(data_path, "inception_4d", weights_layout, 112, std::make_tuple(144U, 288U), std::make_tuple(32U, 64U), 64U).set_name("inception_4d/concat");
+ graph << get_inception_node(data_path, "inception_4e", weights_layout, 256, std::make_tuple(160U, 320U), std::make_tuple(32U, 128U), 128U).set_name("inception_4e/concat");
+ graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL))).set_name("pool4/3x3_s2");
+ graph << get_inception_node(data_path, "inception_5a", weights_layout, 256, std::make_tuple(160U, 320U), std::make_tuple(32U, 128U), 128U).set_name("inception_5a/concat");
+ graph << get_inception_node(data_path, "inception_5b", weights_layout, 384, std::make_tuple(192U, 384U), std::make_tuple(48U, 128U), 128U).set_name("inception_5b/concat");
+ graph << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, 7, PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL))).set_name("pool5/7x7_s1")
<< FullyConnectedLayer(
1000U,
get_weights_accessor(data_path, "/cnn_data/googlenet_model/loss3/loss3_classifier_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/googlenet_model/loss3/loss3_classifier_b.npy"))
- << SoftmaxLayer()
+ .set_name("loss3/classifier")
+ << SoftmaxLayer().set_name("prob")
<< OutputLayer(get_output_accessor(common_params, 5));
// Finalize graph
@@ -154,7 +157,8 @@
get_weights_accessor(data_path, total_path + "1x1_w.npy", weights_layout),
get_weights_accessor(data_path, total_path + "1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/relu_1x1");
SubStream i_b(graph);
i_b << ConvolutionLayer(
@@ -162,13 +166,15 @@
get_weights_accessor(data_path, total_path + "3x3_reduce_w.npy", weights_layout),
get_weights_accessor(data_path, total_path + "3x3_reduce_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/3x3_reduce")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/relu_3x3_reduce")
<< ConvolutionLayer(
3U, 3U, std::get<1>(b_filters),
get_weights_accessor(data_path, total_path + "3x3_w.npy", weights_layout),
get_weights_accessor(data_path, total_path + "3x3_b.npy"),
PadStrideInfo(1, 1, 1, 1))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/3x3")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/relu_3x3");
SubStream i_c(graph);
i_c << ConvolutionLayer(
@@ -176,22 +182,25 @@
get_weights_accessor(data_path, total_path + "5x5_reduce_w.npy", weights_layout),
get_weights_accessor(data_path, total_path + "5x5_reduce_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/5x5_reduce")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/relu_5x5_reduce")
<< ConvolutionLayer(
5U, 5U, std::get<1>(c_filters),
get_weights_accessor(data_path, total_path + "5x5_w.npy", weights_layout),
get_weights_accessor(data_path, total_path + "5x5_b.npy"),
PadStrideInfo(1, 1, 2, 2))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/5x5")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/relu_5x5");
SubStream i_d(graph);
- i_d << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL)))
+ i_d << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL))).set_name(param_path + "/pool")
<< ConvolutionLayer(
1U, 1U, d_filt,
get_weights_accessor(data_path, total_path + "pool_proj_w.npy", weights_layout),
get_weights_accessor(data_path, total_path + "pool_proj_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/pool_proj")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/relu_pool_proj");
return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d));
}
@@ -204,6 +213,8 @@
* "Going deeper with convolutions"
* Christian Szegedy, Wei Liu, Yangqing Jia, Pierre Sermanet, Scott Reed, Dragomir Anguelov, Dumitru Erhan, Vincent Vanhoucke, Andrew Rabinovich
*
+ * Provenance: https://github.com/BVLC/caffe/tree/master/models/bvlc_googlenet
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_inception_resnet_v1.cpp b/examples/graph_inception_resnet_v1.cpp
new file mode 100644
index 0000000..e99f688
--- /dev/null
+++ b/examples/graph_inception_resnet_v1.cpp
@@ -0,0 +1,718 @@
+/*
+ * Copyright (c) 2018 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/graph.h"
+#include "support/ToolchainSupport.h"
+#include "utils/CommonGraphOptions.h"
+#include "utils/GraphUtils.h"
+#include "utils/Utils.h"
+
+using namespace arm_compute::utils;
+using namespace arm_compute::graph::frontend;
+using namespace arm_compute::graph_utils;
+
+const float batch_norm_epsilon = 0.0010000000474974513f;
+
+/** Example demonstrating how to implement Inception ResNet V1 network using the Compute Library's graph API */
+class InceptionResNetV1Example final : public Example
+{
+public:
+ InceptionResNetV1Example()
+ : cmd_parser(), common_opts(cmd_parser), common_params(), model_input_width(nullptr), model_input_height(nullptr), graph(0, "InceptionResNetV1")
+ {
+ model_input_width = cmd_parser.add_option<SimpleOption<unsigned int>>("image-width", 512);
+ model_input_height = cmd_parser.add_option<SimpleOption<unsigned int>>("image-height", 512);
+
+ // Add model id option
+ model_input_width->set_help("Input image width.");
+ model_input_height->set_help("Input image height.");
+ }
+ InceptionResNetV1Example(const InceptionResNetV1Example &) = delete;
+ InceptionResNetV1Example &operator=(const InceptionResNetV1Example &) = delete;
+ InceptionResNetV1Example(InceptionResNetV1Example &&) = default; // NOLINT
+ InceptionResNetV1Example &operator=(InceptionResNetV1Example &&) = default; // NOLINT
+ ~InceptionResNetV1Example() override = default;
+ bool do_setup(int argc, char **argv) override
+ {
+ // Parse arguments
+ cmd_parser.parse(argc, argv);
+
+ // Consume common parameters
+ common_params = consume_common_graph_parameters(common_opts);
+
+ // Return when help menu is requested
+ if(common_params.help)
+ {
+ cmd_parser.print_help(argv[0]);
+ return false;
+ }
+ // Get input image width and height
+ const unsigned int image_width = model_input_width->value();
+ const unsigned int image_height = model_input_height->value();
+
+ // Set default layout if needed
+ if(!common_opts.data_layout->is_set() && common_params.target == Target::NEON)
+ {
+ common_params.data_layout = DataLayout::NCHW;
+ }
+
+ // Checks
+ ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
+
+ // Print parameter values
+ std::cout << common_params << std::endl;
+ std::cout << "Image width: " << image_width << std::endl;
+ std::cout << "Image height: " << image_height << std::endl;
+
+ // Create model path
+ std::string data_path = common_params.data_path;
+ std::string model_path = "/cnn_data/inception_resnet_v1_model/";
+ if(!data_path.empty())
+ {
+ data_path += model_path;
+ }
+
+ // Create a preprocessor object
+ std::unique_ptr<IPreprocessor> preprocessor = arm_compute::support::cpp14::make_unique<TFPreproccessor>(0.f, 1.f);
+
+ // Create input descriptor
+ const TensorShape tensor_shape = permute_shape(TensorShape(image_width, image_height, 3U, 1U), DataLayout::NCHW, common_params.data_layout);
+ TensorDescriptor input_descriptor = TensorDescriptor(tensor_shape, common_params.data_type).set_layout(common_params.data_layout);
+
+ // Set weights trained layout
+ const DataLayout weights_layout = DataLayout::NCHW;
+
+ graph << common_params.target
+ << common_params.fast_math_hint
+ << InputLayer(input_descriptor, get_input_accessor(common_params, std::move(preprocessor), false))
+ // Conv2d_1a_3x3
+ << ConvolutionLayer(3U, 3U, 32U,
+ get_weights_accessor(data_path, "Conv2d_1a_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(2, 2, 0, 0))
+ .set_name("Conv2d_1a_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Conv2d_1a_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_1a_3x3/Relu")
+ // Conv2d_2a_3x3
+ << ConvolutionLayer(3U, 3U, 32U,
+ get_weights_accessor(data_path, "Conv2d_2a_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name("Conv2d_2a_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_2a_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Conv2d_2a_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Conv2d_2a_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Conv2d_2a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_2a_3x3/Relu")
+ // Conv2d_2b_3x3
+ << ConvolutionLayer(3U, 3U, 64U,
+ get_weights_accessor(data_path, "Conv2d_2b_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 1, 1))
+ .set_name("Conv2d_2b_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_2b_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Conv2d_2b_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Conv2d_2b_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Conv2d_2b_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_2b_3x3/Relu")
+ // MaxPool_3a_3x3
+ << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true)).set_name("MaxPool_3a_3x3/MaxPool")
+ // Conv2d_3b_1x1
+ << ConvolutionLayer(1U, 1U, 80U,
+ get_weights_accessor(data_path, "Conv2d_3b_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name("Conv2d_3b_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_3b_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Conv2d_3b_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Conv2d_3b_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Conv2d_3b_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_3b_1x1/Relu")
+ // Conv2d_4a_3x3
+ << ConvolutionLayer(3U, 3U, 192U,
+ get_weights_accessor(data_path, "Conv2d_4a_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name("Conv2d_4a_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_4a_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Conv2d_4a_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Conv2d_4a_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Conv2d_4a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_4a_3x3/Relu")
+ // Conv2d_4b_3x3
+ << ConvolutionLayer(3U, 3U, 256U,
+ get_weights_accessor(data_path, "Conv2d_4b_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(2, 2, 0, 0))
+ .set_name("Conv2d_4a_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv2d_4b_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Conv2d_4b_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Conv2d_4b_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Conv2d_4b_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_4b_3x3/Relu");
+
+ // 5 x Inception-resnet-A
+ block35_repeat(data_path, weights_layout, 5);
+ // Reduction-A
+ reduction_a(data_path, weights_layout);
+ // 10 x Inception-Resnet-B
+ block17_repeat(data_path, weights_layout, 10);
+ // Reduction-B
+ reduction_b(data_path, weights_layout);
+ // 5 x Inception-resnet-C
+ block8_repeat(data_path, weights_layout, 5, 0.2f, true);
+
+ block8_repeat(data_path, weights_layout, 1, 1.f, false);
+
+ // Logits tail
+ graph << PoolingLayer(PoolingLayerInfo(PoolingType::AVG)).set_name("Logits/AvgPool_1a_8x8")
+ << FlattenLayer().set_name("Logits/Flatten")
+ << FullyConnectedLayer(
+ 128U,
+ get_weights_accessor(data_path, "Logits_Logits_weights.npy", weights_layout),
+ get_weights_accessor(data_path, "Logits_Logits_biases.npy"))
+ .set_name("Logits/Logits")
+ << OutputLayer(arm_compute::support::cpp14::make_unique<DummyAccessor>(0));
+
+ // Finalize graph
+ GraphConfig config;
+ config.num_threads = common_params.threads;
+ config.use_tuner = common_params.enable_tuner;
+ config.tuner_file = common_params.tuner_file;
+
+ graph.finalize(common_params.target, config);
+
+ return true;
+ }
+
+ void do_run() override
+ {
+ graph.run();
+ }
+
+private:
+ CommandLineParser cmd_parser;
+ CommonGraphOptions common_opts;
+ CommonGraphParams common_params;
+ SimpleOption<unsigned int> *model_input_width{ nullptr };
+ SimpleOption<unsigned int> *model_input_height{ nullptr };
+ Stream graph;
+
+private:
+ void block35_repeat(const std::string &data_path, DataLayout weights_layout, unsigned int num_blocks)
+ {
+ for(unsigned int i = 0; i < num_blocks; ++i)
+ {
+ std::stringstream unit_path_ss;
+ unit_path_ss << "Repeat_block35_" << (i + 1) << "_";
+ std::stringstream unit_name_ss;
+ unit_name_ss << "Repeat/block35_" << (i + 1) << "/";
+
+ std::string unit_path = unit_path_ss.str();
+ std::string unit_name = unit_name_ss.str();
+
+ // Create left and write substreams
+ SubStream i_l(graph);
+ SubStream i_r(graph);
+
+ // Branch 0
+ SubStream i_la(i_l);
+ i_la << ConvolutionLayer(1U, 1U, 32U,
+ get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name(unit_name + "Branch_0/Conv2d_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_0/Conv2d_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_0/Conv2d_1x1/Relu");
+
+ // Branch 1
+ SubStream i_lb(i_l);
+ i_lb << ConvolutionLayer(1U, 1U, 32U,
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0a_1x1/Relu")
+ << ConvolutionLayer(3U, 3U, 32U,
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 1, 1))
+ .set_name(unit_name + "Branch_1/Conv2d_0b_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_1/Conv2d_0b_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0b_3x3/Relu");
+
+ // Branch 2
+ SubStream i_lc(i_l);
+ i_lc << ConvolutionLayer(1U, 1U, 32U,
+ get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name(unit_name + "Branch_2/Conv2d_0a_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_2/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_2/Conv2d_0a_1x1/Relu")
+ << ConvolutionLayer(3U, 3U, 32U,
+ get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0b_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 1, 1))
+ .set_name(unit_name + "Branch_2/Conv2d_0b_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_2/Conv2d_0b_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_2/Conv2d_0b_3x3/Relu")
+ << ConvolutionLayer(3U, 3U, 32U,
+ get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0c_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 1, 1))
+ .set_name(unit_name + "Branch_2/Conv2d_0c_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_2/Conv2d_0c_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_2/Conv2d_0c_3x3/Relu");
+
+ // Concatenate
+ i_l << ConcatLayer(std::move(i_la), std::move(i_lb), std::move(i_lc)).set_name(unit_name + "concat")
+ << ConvolutionLayer(1U, 1U, 256U,
+ get_weights_accessor(data_path, unit_path + "Conv2d_1x1_weights.npy", weights_layout),
+ get_weights_accessor(data_path, unit_path + "Conv2d_1x1_biases.npy", weights_layout),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name(unit_name + "Conv2d_1x1/convolution")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, 0.17f, 0.f)).set_name(unit_name + "mul");
+
+ graph << EltwiseLayer(std::move(i_l), std::move(i_r), EltwiseOperation::Add).set_name(unit_name + "add")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Relu");
+ }
+ }
+
+ void block17_repeat(const std::string &data_path, DataLayout weights_layout, unsigned int num_blocks)
+ {
+ for(unsigned int i = 0; i < num_blocks; ++i)
+ {
+ std::stringstream unit_path_ss;
+ unit_path_ss << "Repeat_1_block17_" << (i + 1) << "_";
+ std::stringstream unit_name_ss;
+ unit_name_ss << "Repeat_1/block17_" << (i + 1) << "/";
+
+ std::string unit_path = unit_path_ss.str();
+ std::string unit_name = unit_name_ss.str();
+
+ // Create left and write substreams
+ SubStream i_l(graph);
+ SubStream i_r(graph);
+
+ // Branch 0
+ SubStream i_la(i_l);
+ i_la << ConvolutionLayer(1U, 1U, 128U,
+ get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name(unit_name + "Branch_0/Conv2d_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_0/Conv2d_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_0/Conv2d_1x1/Relu");
+
+ // Branch 1
+ SubStream i_lb(i_l);
+ i_lb << ConvolutionLayer(1U, 1U, 128U,
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0a_1x1/Relu")
+ << ConvolutionLayer(7U, 1U, 128U,
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 3, 0))
+ .set_name(unit_name + "Branch_1/Conv2d_0b_1x7/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_1/Conv2d_0b_1x7/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0b_1x7/Relu")
+ << ConvolutionLayer(1U, 7U, 128U,
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 3))
+ .set_name(unit_name + "Branch_1/Conv2d_0c_7x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_1/Conv2d_0c_7x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0c_7x1/Relu");
+
+ // Concatenate
+ i_l << ConcatLayer(std::move(i_la), std::move(i_lb)).set_name(unit_name + "concat")
+ << ConvolutionLayer(1U, 1U, 896U,
+ get_weights_accessor(data_path, unit_path + "Conv2d_1x1_weights.npy", weights_layout),
+ get_weights_accessor(data_path, unit_path + "Conv2d_1x1_biases.npy", weights_layout),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name(unit_name + "Conv2d_1x1/convolution")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, 0.10f, 0.f)).set_name(unit_name + "mul");
+
+ graph << EltwiseLayer(std::move(i_l), std::move(i_r), EltwiseOperation::Add).set_name(unit_name + "add")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Relu");
+ }
+ }
+
+ void block8_repeat(const std::string &data_path, DataLayout weights_layout, unsigned int num_blocks, float scale, bool has_activation)
+ {
+ for(unsigned int i = 0; i < num_blocks; ++i)
+ {
+ std::stringstream unit_path_ss;
+ std::stringstream unit_name_ss;
+ if(num_blocks != 1)
+ {
+ unit_path_ss << "Repeat_2_block8_" << (i + 1) << "_";
+ unit_name_ss << "Repeat_2/block8_" << (i + 1) << "/";
+ }
+ else
+ {
+ unit_path_ss << "Block8_";
+ unit_name_ss << "Block8/";
+ }
+
+ std::string unit_path = unit_path_ss.str();
+ std::string unit_name = unit_name_ss.str();
+
+ // Create left and write substreams
+ SubStream i_l(graph);
+ SubStream i_r(graph);
+
+ // Branch 0
+ SubStream i_la(i_l);
+ i_la << ConvolutionLayer(1U, 1U, 192U,
+ get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name(unit_name + "Branch_0/Conv2d_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_0_Conv2d_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_0/Conv2d_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_0/Conv2d_1x1/Relu");
+
+ // Branch 1
+ SubStream i_lb(i_l);
+ i_lb << ConvolutionLayer(1U, 1U, 192U,
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0a_1x1/Relu")
+ << ConvolutionLayer(3U, 1U, 192U,
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 1, 0))
+ .set_name(unit_name + "Branch_1/Conv2d_0b_1x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_1/Conv2d_0b_1x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0b_1x3/Relu")
+ << ConvolutionLayer(1U, 3U, 192U,
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_3x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 1))
+ .set_name(unit_name + "Branch_1/Conv2d_0c_3x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, unit_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name(unit_name + "Branch_1/Conv2d_0c_3x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Branch_1/Conv2d_0c_3x1/Relu");
+
+ // Concatenate
+ i_l << ConcatLayer(std::move(i_la), std::move(i_lb)).set_name(unit_name + "concat")
+ << ConvolutionLayer(1U, 1U, 1792U,
+ get_weights_accessor(data_path, unit_path + "Conv2d_1x1_weights.npy", weights_layout),
+ get_weights_accessor(data_path, unit_path + "Conv2d_1x1_biases.npy", weights_layout),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name(unit_name + "Conv2d_1x1/convolution");
+
+ // Scale result
+ if(scale != 1.f)
+ {
+ i_l << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, scale, 0.f)).set_name(unit_name + "mul");
+ }
+
+ // Residual add
+ graph << EltwiseLayer(std::move(i_l), std::move(i_r), EltwiseOperation::Add).set_name(unit_name + "add");
+
+ // Apply activation if needed
+ if(has_activation)
+ {
+ graph << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "Relu");
+ }
+ }
+ }
+
+ void reduction_a(const std::string &data_path, DataLayout weights_layout)
+ {
+ // Branch 0
+ SubStream i_a(graph);
+ i_a << ConvolutionLayer(3U, 3U, 384U,
+ get_weights_accessor(data_path, "Mixed_6a_Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(2, 2, 0, 0))
+ .set_name("Mixed_6a/Branch_0/Conv2d_1a_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_6a_Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Mixed_6a_Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Mixed_6a_Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Mixed_6a/Branch_0/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_0/Conv2d_1a_3x3/Relu");
+
+ // Branch 1
+ SubStream i_b(graph);
+ i_b << ConvolutionLayer(1U, 1U, 192U,
+ get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name("Mixed_6a/Branch_1/Conv2d_0a_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Mixed_6a/Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_1/Conv2d_0a_1x1/Relu")
+ << ConvolutionLayer(3U, 3U, 192U,
+ get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0b_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 1, 1))
+ .set_name("Mixed_6a/Branch_1/Conv2d_0b_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_0b_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Mixed_6a/Branch_1/Conv2d_0b_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_1/Conv2d_0b_3x3/Relu")
+ << ConvolutionLayer(3U, 3U, 256U,
+ get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(2, 2, 0, 0))
+ .set_name("Mixed_6a/Branch_1/Conv2d_1a_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Mixed_6a_Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Mixed_6a/Branch_1/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_1/Conv2d_1a_3x3/Relu");
+
+ // Branch 2
+ SubStream i_c(graph);
+ i_c << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0), true)).set_name("Mixed_6a/Branch_2/MaxPool_1a_3x3");
+
+ // Concatenate
+ graph << ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c)).set_name("Mixed_6a/concat");
+ }
+
+ void reduction_b(const std::string &data_path, DataLayout weights_layout)
+ {
+ // Branch 0
+ SubStream i_a(graph);
+ i_a << ConvolutionLayer(1U, 1U, 256U,
+ get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name("Mixed_7a/Branch_0/Conv2d_0a_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Mixed_7a/Branch_0/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_0/Conv2d_0a_1x1/Relu")
+ << ConvolutionLayer(3U, 3U, 384U,
+ get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(2, 2, 0, 0))
+ .set_name("Mixed_7a/Branch_0/Conv2d_1a_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Mixed_7a/Branch_0/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_0/Conv2d_1a_3x3/Relu");
+
+ // Branch 1
+ SubStream i_b(graph);
+ i_b << ConvolutionLayer(1U, 1U, 256U,
+ get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/Relu")
+ << ConvolutionLayer(3U, 3U, 256U,
+ get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(2, 2, 0, 0))
+ .set_name("Mixed_7a/Branch_1/Conv2d_1a_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Mixed_7a/Branch_1/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_1/Conv2d_1a_3x3/Relu");
+
+ // Branch 2
+ SubStream i_c(graph);
+ i_c << ConvolutionLayer(1U, 1U, 256U,
+ get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name("Mixed_7a/Branch_2/Conv2d_0a_1x1/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Mixed_7a/Branch_2/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_2/Conv2d_0a_1x1/Relu")
+ << ConvolutionLayer(3U, 3U, 256U,
+ get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0b_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 1, 1))
+ .set_name("Mixed_7a/Branch_2/Conv2d_0b_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_0b_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Mixed_7a/Branch_2/Conv2d_0b_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_2/Conv2d_0b_3x3/Relu")
+ << ConvolutionLayer(3U, 3U, 256U,
+ get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_1a_3x3_weights.npy", weights_layout),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(2, 2, 0, 0))
+ .set_name("Mixed_7a/Branch_2/Conv2d_1a_3x3/convolution")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
+ get_random_accessor(1.f, 1.f),
+ get_weights_accessor(data_path, "Mixed_7a_Branch_2_Conv2d_1a_3x3_BatchNorm_beta.npy"),
+ batch_norm_epsilon)
+ .set_name("Mixed_7a/Branch_2/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_2/Conv2d_1a_3x3/Relu");
+
+ // Branch 3
+ SubStream i_d(graph);
+ i_d << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0), true)).set_name("Mixed_7a/Branch_3/MaxPool_1a_3x3");
+
+ // Concatenate
+ graph << ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d)).set_name("Mixed_7a/concat");
+ }
+};
+
+/** Main program for Inception ResNet V1
+ *
+ * Model is based on:
+ * https://arxiv.org/abs/1602.07261
+ * "Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning"
+ * Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi
+ *
+ * @note To list all the possible arguments execute the binary appended with the --help option
+ *
+ * @param[in] argc Number of arguments
+ * @param[in] argv Arguments
+ */
+int main(int argc, char **argv)
+{
+ return arm_compute::utils::run_example<InceptionResNetV1Example>(argc, argv);
+}
diff --git a/examples/graph_inception_resnet_v2.cpp b/examples/graph_inception_resnet_v2.cpp
index 5115696..8e79978 100644
--- a/examples/graph_inception_resnet_v2.cpp
+++ b/examples/graph_inception_resnet_v2.cpp
@@ -62,7 +62,6 @@
// Checks
ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
- ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
// Print parameter values
std::cout << common_params << std::endl;
@@ -788,6 +787,8 @@
* "Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning"
* Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi
*
+ * Provenance: download.tensorflow.org/models/inception_resnet_v2_2016_08_30.tar.gz
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_inception_v3.cpp b/examples/graph_inception_v3.cpp
index d9b7b05..517e492 100644
--- a/examples/graph_inception_v3.cpp
+++ b/examples/graph_inception_v3.cpp
@@ -56,7 +56,6 @@
// Checks
ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
- ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
// Print parameter values
std::cout << common_params << std::endl;
@@ -852,6 +851,8 @@
* "Rethinking the Inception Architecture for Computer Vision"
* Christian Szegedy, Vincent Vanhoucke, Sergey Ioffe, Jonathon Shlens, Zbigniew Wojna
*
+ * Provenance: download.tensorflow.org/models/inception_v3_2016_08_28.tar.gz
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_inception_v4.cpp b/examples/graph_inception_v4.cpp
index d4854cf..0b0360a 100644
--- a/examples/graph_inception_v4.cpp
+++ b/examples/graph_inception_v4.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 ARM Limited.
+ * Copyright (c) 2018-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -56,7 +56,6 @@
// Checks
ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
- ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
// Print parameter values
std::cout << common_params << std::endl;
@@ -81,64 +80,71 @@
<< ConvolutionLayer(3U, 3U, 32U,
get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
+ .set_name("Conv2d_1a_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_1a_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_1a_3x3/Relu")
// Conv2d_2a_3x3
<< ConvolutionLayer(3U, 3U, 32U,
get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name("Conv2d_2a_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2a_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Conv2d_2a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_2a_3x3/Relu")
// Conv2d_2b_3x3
<< ConvolutionLayer(3U, 3U, 64U,
get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
+ .set_name("Conv2d_2b_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Conv2d_2b_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name("Conv2d_2b_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_2b_3x3/Relu");
- graph << get_mixed_3a(data_path, weights_layout);
- graph << get_mixed_4a(data_path, weights_layout);
- graph << get_mixed_5a(data_path, weights_layout);
+ graph << get_mixed_3a(data_path, weights_layout).set_name("Mixed_3a/concat");
+ graph << get_mixed_4a(data_path, weights_layout).set_name("Mixed_4a/concat");
+ graph << get_mixed_5a(data_path, weights_layout).set_name("Mixed_5a/concat");
// 4 inception A blocks
- graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5b");
- graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5c");
- graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5d");
- graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5e");
+ graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5b").set_name("Mixed_5b/concat");
+ graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5c").set_name("Mixed_5c/concat");
+ graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5d").set_name("Mixed_5d/concat");
+ graph << get_inceptionA_block(data_path, weights_layout, "Mixed_5e").set_name("Mixed_5e/concat");
// reduction A block
- graph << get_reductionA_block(data_path, weights_layout);
+ graph << get_reductionA_block(data_path, weights_layout).set_name("Mixed_6a/concat");
// 7 inception B blocks
- graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6b");
- graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6c");
- graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6d");
- graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6e");
- graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6f");
- graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6g");
- graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6h");
+ graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6b").set_name("Mixed_6b/concat");
+ graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6c").set_name("Mixed_6c/concat");
+ graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6d").set_name("Mixed_6d/concat");
+ graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6e").set_name("Mixed_6e/concat");
+ graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6f").set_name("Mixed_6f/concat");
+ graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6g").set_name("Mixed_6g/concat");
+ graph << get_inceptionB_block(data_path, weights_layout, "Mixed_6h").set_name("Mixed_6h/concat");
// reduction B block
- graph << get_reductionB_block(data_path, weights_layout);
+ graph << get_reductionB_block(data_path, weights_layout).set_name("Mixed_7a/concat");
// 3 inception C blocks
- graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7b");
- graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7c");
- graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7d");
- graph << PoolingLayer(PoolingLayerInfo(PoolingType::AVG))
- << FlattenLayer()
+ graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7b").set_name("Mixed_7b/concat");
+ graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7c").set_name("Mixed_7c/concat");
+ graph << get_inceptionC_block(data_path, weights_layout, "Mixed_7d").set_name("Mixed_7d/concat");
+ graph << PoolingLayer(PoolingLayerInfo(PoolingType::AVG)).set_name("Logits/AvgPool_1a/AvgPool")
+ << FlattenLayer().set_name("Logits/Flatten")
<< FullyConnectedLayer(
1001U,
get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Logits_Logits_weights.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/inceptionv4_model/Logits_Logits_biases.npy"))
- << SoftmaxLayer()
+ .set_name("Logits/MatMul")
+ << SoftmaxLayer().set_name("Logits/Predictions")
<< OutputLayer(get_output_accessor(common_params, 5));
// Finalize graph
@@ -169,18 +175,20 @@
std::string total_path = "/cnn_data/inceptionv4_model/Mixed_3a_";
SubStream i_a(graph);
- i_a << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true));
+ i_a << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true)).set_name("Mixed_3a/Branch_0/MaxPool_0a_3x3/MaxPool");
SubStream i_b(graph);
i_b << ConvolutionLayer(3U, 3U, 96U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
+ .set_name("Mixed_3a/Branch_1/Conv2d_0a_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name("Mixed_3a/Branch_1/Conv2d_0a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_3a/Branch_1/Conv2d_0a_3x3/Relu");
return ConcatLayer(std::move(i_a), std::move(i_b));
}
@@ -193,59 +201,71 @@
i_a << ConvolutionLayer(1U, 1U, 64U,
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name("Mixed_4a/Branch_0/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Mixed_4a/Branch_0/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_4a/Branch_0/Conv2d_0a_1x1/Relu")
<< ConvolutionLayer(3U, 3U, 96U,
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name("Mixed_4a/Branch_0/Conv2d_1a_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name("Mixed_4a/Branch_0/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_4a/Branch_0/Conv2d_1a_3x3/Relu");
SubStream i_b(graph);
i_b << ConvolutionLayer(1U, 1U, 64U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name("Mixed_4a/Branch_1/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Mixed_4a/Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_4a/Branch_1/Conv2d_0a_1x1/Relu")
<< ConvolutionLayer(7U, 1U, 64U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
+ .set_name("Mixed_4a/Branch_1/Conv2d_0b_1x7/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Mixed_4a/Branch_1/Conv2d_0b_1x7/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_4a/Branch_1/Conv2d_0b_1x7/Relu")
<< ConvolutionLayer(1U, 7U, 64U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
+ .set_name("Mixed_4a/Branch_1/Conv2d_0c_7x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Mixed_4a/Branch_1/Conv2d_0c_7x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_4a/Branch_1/Conv2d_0c_7x1/Relu")
<< ConvolutionLayer(3U, 3U, 96U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name("Mixed_4a/Branch_1/Conv2d_1a_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name("Mixed_4a/Branch_1/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_4a/Branch_1/Conv2d_1a_3x3/Relu");
return ConcatLayer(std::move(i_a), std::move(i_b));
}
@@ -258,15 +278,17 @@
i_a << ConvolutionLayer(3U, 3U, 192U,
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
+ .set_name("Mixed_5a/Branch_0/Conv2d_1a_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name("Mixed_5a/Branch_0/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_5a/Branch_0/Conv2d_1a_3x3/Relu");
SubStream i_b(graph);
- i_b << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true));
+ i_b << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true)).set_name("Mixed_5a/Branch_1/MaxPool_1a_3x3/MaxPool");
return ConcatLayer(std::move(i_a), std::move(i_b));
}
@@ -279,73 +301,87 @@
i_a << ConvolutionLayer(1U, 1U, 96U,
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Relu");
SubStream i_b(graph);
i_b << ConvolutionLayer(1U, 1U, 64U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Relu")
<< ConvolutionLayer(3U, 3U, 96U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
+ .set_name(param_path + "/Branch_1/Conv2d_0b_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_1/Conv2d_0b_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0b_3x3/Relu");
SubStream i_c(graph);
i_c << ConvolutionLayer(1U, 1U, 64U,
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Relu")
<< ConvolutionLayer(3U, 3U, 96U,
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
+ .set_name(param_path + "/Branch_2/Conv2d_0b_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/Branch_2/Conv2d_0b_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0b_3x3/Relu")
<< ConvolutionLayer(3U, 3U, 96U,
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
+ .set_name(param_path + "/Branch_2/Conv2d_0c_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_2/Conv2d_0c_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0c_3x3/Relu");
SubStream i_d(graph);
- i_d << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, 3, PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL), true))
+ i_d << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, 3, PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL), true)).set_name(param_path + "/Branch_3/AvgPool_0a_3x3/AvgPool")
<< ConvolutionLayer(1U, 1U, 96U,
get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Relu");
return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d));
}
@@ -358,44 +394,52 @@
i_a << ConvolutionLayer(3U, 3U, 384U,
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
+ .set_name("Mixed_6a/Branch_0/Conv2d_1a_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name("Mixed_6a/Branch_0/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_0/Conv2d_1a_3x3/Relu");
SubStream i_b(graph);
i_b << ConvolutionLayer(1U, 1U, 192U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name("Mixed_6a/Branch_1/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Mixed_6a/Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_1/Conv2d_0a_1x1/Relu")
<< ConvolutionLayer(3U, 3U, 224U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 1, 1))
+ .set_name("Mixed_6a/Branch_1/Conv2d_0b_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Mixed_6a/Branch_1/Conv2d_0b_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_1/Conv2d_0b_3x3/Relu")
<< ConvolutionLayer(3U, 3U, 256U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
+ .set_name("Mixed_6a/Branch_1/Conv2d_1a_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name("Mixed_6a/Branch_1/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_6a/Branch_1/Conv2d_1a_3x3/Relu");
SubStream i_c(graph);
- i_c << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true));
+ i_c << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true)).set_name("Mixed_6a/Branch_2/MaxPool_1a_3x3/MaxPool");
return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c));
}
@@ -408,100 +452,120 @@
i_a << ConvolutionLayer(1U, 1U, 384U,
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Relu");
SubStream i_b(graph);
i_b << ConvolutionLayer(1U, 1U, 192U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Relu")
<< ConvolutionLayer(7U, 1U, 224U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
+ .set_name(param_path + "/Branch_1/Conv2d_0b_1x7/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/Branch_1/Conv2d_0b_1x7/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0b_1x7/Relu")
<< ConvolutionLayer(1U, 7U, 256U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
+ .set_name(param_path + "/Branch_1/Conv2d_0c_7x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_1/Conv2d_0c_7x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0c_7x1/Relu");
SubStream i_c(graph);
i_c << ConvolutionLayer(1U, 1U, 192U,
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Relu")
<< ConvolutionLayer(1U, 7U, 192U,
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
+ .set_name(param_path + "/Branch_2/Conv2d_0b_7x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/Branch_2/Conv2d_0b_7x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0b_7x1/Relu")
<< ConvolutionLayer(7U, 1U, 224U,
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
+ .set_name(param_path + "/Branch_2/Conv2d_0c_1x7/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/Branch_2/Conv2d_0c_1x7/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0c_1x7/Relu")
<< ConvolutionLayer(1U, 7U, 224U,
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
+ .set_name(param_path + "/Branch_2/Conv2d_0d_7x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/Branch_2/Conv2d_0d_7x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0d_7x1/Relu")
<< ConvolutionLayer(7U, 1U, 256U,
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
+ .set_name(param_path + "/Branch_2/Conv2d_0e_1x7/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_2/Conv2d_0e_1x7/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0e_1x7/Relu");
SubStream i_d(graph);
- i_d << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, 3, PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL), true))
+ i_d << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, 3, PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL), true)).set_name(param_path + "/Branch_3/AvgPool_0a_3x3/AvgPool")
<< ConvolutionLayer(1U, 1U, 128U,
get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Relu");
return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d));
}
@@ -514,62 +578,74 @@
i_a << ConvolutionLayer(1U, 1U, 192U,
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/Relu")
<< ConvolutionLayer(3U, 3U, 192U,
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
+ .set_name("Mixed_7a/Branch_0/Conv2d_1a_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name("Mixed_7a/Branch_0/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_0/Conv2d_1a_3x3/Relu");
SubStream i_b(graph);
i_b << ConvolutionLayer(1U, 1U, 256U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_1/Conv2d_0a_1x1/Relu")
<< ConvolutionLayer(7U, 1U, 256U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 3, 0))
+ .set_name("Mixed_7a/Branch_1/Conv2d_0b_1x7/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Mixed_7a/Branch_1/Conv2d_0b_1x7/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_1/Conv2d_0b_1x7/Relu")
<< ConvolutionLayer(1U, 7U, 320U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 3))
+ .set_name("Mixed_7a/Branch_1/Conv2d_0c_7x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name("Mixed_7a/Branch_1/Conv2d_0c_7x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_1/Conv2d_0c_7x1/Relu")
<< ConvolutionLayer(3U, 3U, 320U,
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(2, 2, 0, 0))
+ .set_name("Mixed_7a/Branch_1/Conv2d_1a_3x3/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name("Mixed_7a/Branch_1/Conv2d_1a_3x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Mixed_7a/Branch_1/Conv2d_1a_3x3/Relu");
SubStream i_c(graph);
- i_c << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true));
+ i_c << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), true)).set_name("Mixed_7a/Branch_2/MaxPool_1a_3x3/MaxPool");
return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c));
}
@@ -582,12 +658,14 @@
i_a << ConvolutionLayer(1U, 1U, 256U,
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_0/Conv2d_0a_1x1/Relu");
SubStream i_b(graph);
i_b << ConvolutionLayer(
@@ -595,13 +673,15 @@
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0a_1x1/Relu");
SubStream i_b1(i_b);
i_b1 << ConvolutionLayer(
@@ -609,13 +689,15 @@
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(1, 1, 1, 0))
+ .set_name(param_path + "/Branch_1/Conv2d_0b_1x3/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_1/Conv2d_0b_1x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0b_1x3/Relu");
SubStream i_b2(i_b);
i_b2 << ConvolutionLayer(
@@ -623,16 +705,18 @@
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(1, 1, 0, 1))
+ .set_name(param_path + "/Branch_1/Conv2d_0c_3x1/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_3x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_1/Conv2d_0c_3x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_1/Conv2d_0c_3x1/Relu");
// Merge b1 and b2
- i_b << ConcatLayer(std::move(i_b1), std::move(i_b2));
+ i_b << ConcatLayer(std::move(i_b1), std::move(i_b2)).set_name(param_path + "/Branch_1/concat");
SubStream i_c(graph);
i_c << ConvolutionLayer(
@@ -640,37 +724,43 @@
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0a_1x1/Relu")
<< ConvolutionLayer(
1U, 3U, 448U,
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(1, 1, 0, 1))
+ .set_name(param_path + "/Branch_2/Conv2d_0b_3x1/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
+ .set_name(param_path + "/Branch_2/Conv2d_0b_3x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0b_3x1/Relu")
<< ConvolutionLayer(
3U, 1U, 512U,
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(1, 1, 1, 0))
+ .set_name(param_path + "/Branch_2/Conv2d_0c_1x3/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_2/Conv2d_0c_1x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0c_1x3/Relu");
SubStream i_c1(i_c);
i_c1 << ConvolutionLayer(
@@ -678,13 +768,15 @@
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(1, 1, 1, 0))
+ .set_name(param_path + "/Branch_2/Conv2d_0d_1x3/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_1x3_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_2/Conv2d_0d_1x3/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0d_1x3/Relu");
SubStream i_c2(i_c);
i_c2 << ConvolutionLayer(
@@ -692,28 +784,32 @@
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(1, 1, 0, 1))
+ .set_name(param_path + "/Branch_2/Conv2d_0e_3x1/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_3x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_2/Conv2d_0e_3x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_2/Conv2d_0e_3x1/Relu");
// Merge i_c1 and i_c2
- i_c << ConcatLayer(std::move(i_c1), std::move(i_c2));
+ i_c << ConcatLayer(std::move(i_c1), std::move(i_c2)).set_name(param_path + "/Branch_2/concat");
SubStream i_d(graph);
- i_d << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, 3, PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL), true))
+ i_d << PoolingLayer(PoolingLayerInfo(PoolingType::AVG, 3, PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL), true)).set_name(param_path + "/Branch_3/AvgPool_0a_3x3/AvgPool")
<< ConvolutionLayer(1U, 1U, 256U,
get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_weights.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr), PadStrideInfo(1, 1, 0, 0))
+ .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Conv2D")
<< BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"),
get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"),
get_random_accessor(1.f, 1.f),
get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"),
0.001f)
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/Branch_3/Conv2d_0b_1x1/Relu");
return ConcatLayer(std::move(i_a), std::move(i_b), std::move(i_c), std::move(i_d));
}
@@ -726,6 +822,8 @@
* "Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning"
* Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi
*
+ * Provenance: download.tensorflow.org/models/inception_v4_2016_09_09.tar.gz
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_mobilenet.cpp b/examples/graph_mobilenet.cpp
index 19a395d..10bb890 100644
--- a/examples/graph_mobilenet.cpp
+++ b/examples/graph_mobilenet.cpp
@@ -323,7 +323,7 @@
3U, 3U,
get_weights_accessor(data_path, total_path + "depthwise_weights.npy"),
get_weights_accessor(data_path, total_path + "depthwise_bias.npy"),
- dwc_pad_stride_info, depth_weights_quant_info)
+ dwc_pad_stride_info, 1, depth_weights_quant_info)
.set_name(total_path + "depthwise/depthwise")
<< ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 6.f)).set_name(total_path + "depthwise/Relu6")
<< ConvolutionLayer(
@@ -345,6 +345,9 @@
* "MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications"
* Andrew G. Howard, Menglong Zhu, Bo Chen, Dmitry Kalenichenko, Weijun Wang, Tobias Weyand, Marco Andreetto, Hartwig Adam
*
+ * Provenance: download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_224.tgz
+ * download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.75_160.tgz
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_mobilenet_v2.cpp b/examples/graph_mobilenet_v2.cpp
index 2bff367..429a3d2 100644
--- a/examples/graph_mobilenet_v2.cpp
+++ b/examples/graph_mobilenet_v2.cpp
@@ -61,89 +61,29 @@
return false;
}
- // Checks
- ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
- ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
-
// Print parameter values
std::cout << common_params << std::endl;
- // Create model path
- std::string model_path = "/cnn_data/mobilenet_v2_1.0_224_model/";
-
// Create input descriptor
const TensorShape tensor_shape = permute_shape(TensorShape(224U, 224U, 3U, 1U), DataLayout::NCHW, common_params.data_layout);
TensorDescriptor input_descriptor = TensorDescriptor(tensor_shape, common_params.data_type).set_layout(common_params.data_layout);
- // Create a preprocessor object
- std::unique_ptr<IPreprocessor> preprocessor = arm_compute::support::cpp14::make_unique<TFPreproccessor>();
-
- // Get trainable parameters data path
- std::string data_path = common_params.data_path;
-
- // Add model path to data path
- if(!data_path.empty())
- {
- data_path += model_path;
- }
-
- // Create graph
+ // Set graph hints
graph << common_params.target
<< DepthwiseConvolutionMethod::Optimized3x3 // FIXME(COMPMID-1073): Add heuristics to automatically call the optimized 3x3 method
- << common_params.fast_math_hint
- << InputLayer(input_descriptor, get_input_accessor(common_params, std::move(preprocessor), false))
- << ConvolutionLayer(3U, 3U, 32U,
- get_weights_accessor(data_path, "Conv_weights.npy", DataLayout::NCHW),
- std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
- PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL))
- .set_name("Conv")
- << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv_BatchNorm_moving_mean.npy"),
- get_weights_accessor(data_path, "Conv_BatchNorm_moving_variance.npy"),
- get_weights_accessor(data_path, "Conv_BatchNorm_gamma.npy"),
- get_weights_accessor(data_path, "Conv_BatchNorm_beta.npy"),
- 0.0010000000474974513f)
- .set_name("Conv/BatchNorm")
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, 6.f))
- .set_name("Conv/Relu6");
+ << common_params.fast_math_hint;
- get_expanded_conv(data_path, "expanded_conv", 32U, 16U, PadStrideInfo(1, 1, 1, 1));
- get_expanded_conv(data_path, "expanded_conv_1", 16U, 24U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL), true);
- get_expanded_conv(data_path, "expanded_conv_2", 24U, 24U, PadStrideInfo(1, 1, 1, 1), true, true);
- get_expanded_conv(data_path, "expanded_conv_3", 24U, 32U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL), true);
- get_expanded_conv(data_path, "expanded_conv_4", 32U, 32U, PadStrideInfo(1, 1, 1, 1), true, true);
- get_expanded_conv(data_path, "expanded_conv_5", 32U, 32U, PadStrideInfo(1, 1, 1, 1), true, true);
- get_expanded_conv(data_path, "expanded_conv_6", 32U, 64U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL), true);
- get_expanded_conv(data_path, "expanded_conv_7", 64U, 64U, PadStrideInfo(1, 1, 1, 1), true, true);
- get_expanded_conv(data_path, "expanded_conv_8", 64U, 64U, PadStrideInfo(1, 1, 1, 1), true, true);
- get_expanded_conv(data_path, "expanded_conv_9", 64U, 64U, PadStrideInfo(1, 1, 1, 1), true, true);
- get_expanded_conv(data_path, "expanded_conv_10", 64U, 96U, PadStrideInfo(1, 1, 1, 1), true);
- get_expanded_conv(data_path, "expanded_conv_11", 96U, 96U, PadStrideInfo(1, 1, 1, 1), true, true);
- get_expanded_conv(data_path, "expanded_conv_12", 96U, 96U, PadStrideInfo(1, 1, 1, 1), true, true);
- get_expanded_conv(data_path, "expanded_conv_13", 96U, 160U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL), true);
- get_expanded_conv(data_path, "expanded_conv_14", 160U, 160U, PadStrideInfo(1, 1, 1, 1), true, true);
- get_expanded_conv(data_path, "expanded_conv_15", 160U, 160U, PadStrideInfo(1, 1, 1, 1), true, true);
- get_expanded_conv(data_path, "expanded_conv_16", 160U, 320U, PadStrideInfo(1, 1, 1, 1), true);
-
- graph << ConvolutionLayer(1U, 1U, 1280U,
- get_weights_accessor(data_path, "Conv_1_weights.npy", DataLayout::NCHW),
- std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
- PadStrideInfo(1, 1, 0, 0))
- .set_name("Conv_1")
- << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv_1_BatchNorm_moving_mean.npy"),
- get_weights_accessor(data_path, "Conv_1_BatchNorm_moving_variance.npy"),
- get_weights_accessor(data_path, "Conv_1_BatchNorm_gamma.npy"),
- get_weights_accessor(data_path, "Conv_1_BatchNorm_beta.npy"),
- 0.0010000000474974513f)
- .set_name("Conv_1/BatchNorm")
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, 6.f))
- .set_name("Conv_1/Relu6")
- << PoolingLayer(PoolingLayerInfo(PoolingType::AVG)).set_name("Logits/AvgPool")
- << ConvolutionLayer(1U, 1U, 1001U,
- get_weights_accessor(data_path, "Logits_Conv2d_1c_1x1_weights.npy", DataLayout::NCHW),
- get_weights_accessor(data_path, "Logits_Conv2d_1c_1x1_biases.npy"),
- PadStrideInfo(1, 1, 0, 0))
- .set_name("Logits/Conv2d_1c_1x1")
- << ReshapeLayer(TensorShape(1001U)).set_name("Predictions/Reshape")
+ // Create core graph
+ if(arm_compute::is_data_type_float(common_params.data_type))
+ {
+ create_graph_float(input_descriptor);
+ }
+ else
+ {
+ create_graph_qasymm8(input_descriptor);
+ }
+ // Create common tail
+ graph << ReshapeLayer(TensorShape(1001U)).set_name("Predictions/Reshape")
<< SoftmaxLayer().set_name("Predictions/Softmax")
<< OutputLayer(get_output_accessor(common_params, 5));
@@ -170,16 +110,102 @@
CommonGraphParams common_params;
Stream graph;
- void get_expanded_conv(const std::string &data_path, std::string &¶m_path,
- unsigned int input_channels, unsigned int output_channels,
- PadStrideInfo dwc_pad_stride_info,
- bool has_expand = false, bool is_residual = false, unsigned int expansion_size = 6)
+private:
+ enum class IsResidual
+ {
+ Yes,
+ No
+ };
+
+ enum class HasExpand
+ {
+ Yes,
+ No
+ };
+
+private:
+ void create_graph_float(TensorDescriptor &input_descriptor)
+ {
+ // Create model path
+ const std::string model_path = "/cnn_data/mobilenet_v2_1.0_224_model/";
+
+ // Create a preprocessor object
+ std::unique_ptr<IPreprocessor> preprocessor = arm_compute::support::cpp14::make_unique<TFPreproccessor>();
+
+ // Get trainable parameters data path
+ std::string data_path = common_params.data_path;
+
+ // Add model path to data path
+ if(!data_path.empty())
+ {
+ data_path += model_path;
+ }
+
+ graph << InputLayer(input_descriptor, get_input_accessor(common_params, std::move(preprocessor), false))
+ << ConvolutionLayer(3U, 3U, 32U,
+ get_weights_accessor(data_path, "Conv_weights.npy", DataLayout::NCHW),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL))
+ .set_name("Conv")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Conv_BatchNorm_moving_variance.npy"),
+ get_weights_accessor(data_path, "Conv_BatchNorm_gamma.npy"),
+ get_weights_accessor(data_path, "Conv_BatchNorm_beta.npy"),
+ 0.0010000000474974513f)
+ .set_name("Conv/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, 6.f))
+ .set_name("Conv/Relu6");
+
+ get_expanded_conv_float(data_path, "expanded_conv", 32U, 16U, PadStrideInfo(1, 1, 1, 1));
+ get_expanded_conv_float(data_path, "expanded_conv_1", 16U, 24U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL), HasExpand::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_2", 24U, 24U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes, IsResidual::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_3", 24U, 32U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL), HasExpand::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_4", 32U, 32U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes, IsResidual::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_5", 32U, 32U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes, IsResidual::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_6", 32U, 64U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL), HasExpand::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_7", 64U, 64U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes, IsResidual::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_8", 64U, 64U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes, IsResidual::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_9", 64U, 64U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes, IsResidual::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_10", 64U, 96U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_11", 96U, 96U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes, IsResidual::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_12", 96U, 96U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes, IsResidual::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_13", 96U, 160U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL), HasExpand::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_14", 160U, 160U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes, IsResidual::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_15", 160U, 160U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes, IsResidual::Yes);
+ get_expanded_conv_float(data_path, "expanded_conv_16", 160U, 320U, PadStrideInfo(1, 1, 1, 1), HasExpand::Yes);
+
+ graph << ConvolutionLayer(1U, 1U, 1280U,
+ get_weights_accessor(data_path, "Conv_1_weights.npy", DataLayout::NCHW),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name("Conv_1")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, "Conv_1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, "Conv_1_BatchNorm_moving_variance.npy"),
+ get_weights_accessor(data_path, "Conv_1_BatchNorm_gamma.npy"),
+ get_weights_accessor(data_path, "Conv_1_BatchNorm_beta.npy"),
+ 0.0010000000474974513f)
+ .set_name("Conv_1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::BOUNDED_RELU, 6.f))
+ .set_name("Conv_1/Relu6")
+ << PoolingLayer(PoolingLayerInfo(PoolingType::AVG)).set_name("Logits/AvgPool")
+ << ConvolutionLayer(1U, 1U, 1001U,
+ get_weights_accessor(data_path, "Logits_Conv2d_1c_1x1_weights.npy", DataLayout::NCHW),
+ get_weights_accessor(data_path, "Logits_Conv2d_1c_1x1_biases.npy"),
+ PadStrideInfo(1, 1, 0, 0))
+ .set_name("Logits/Conv2d_1c_1x1");
+ }
+
+ void get_expanded_conv_float(const std::string &data_path, std::string &¶m_path,
+ unsigned int input_channels, unsigned int output_channels,
+ PadStrideInfo dwc_pad_stride_info,
+ HasExpand has_expand = HasExpand::No, IsResidual is_residual = IsResidual::No,
+ unsigned int expansion_size = 6)
{
std::string total_path = param_path + "_";
SubStream left(graph);
// Add expand node
- if(has_expand)
+ if(has_expand == HasExpand::Yes)
{
left << ConvolutionLayer(1U, 1U, input_channels * expansion_size,
get_weights_accessor(data_path, total_path + "expand_weights.npy", DataLayout::NCHW),
@@ -222,7 +248,190 @@
0.0010000000474974513)
.set_name(param_path + "/project/BatchNorm");
- if(is_residual)
+ if(is_residual == IsResidual::Yes)
+ {
+ // Add residual node
+ SubStream right(graph);
+ graph << EltwiseLayer(std::move(left), std::move(right), EltwiseOperation::Add).set_name(param_path + "/add");
+ }
+ else
+ {
+ graph.forward_tail(left.tail_node());
+ }
+ }
+
+ void create_graph_qasymm8(TensorDescriptor &input_descriptor)
+ {
+ // Create model path
+ const std::string model_path = "/cnn_data/mobilenet_v2_1.0_224_quantized_model";
+
+ // Get trainable parameters data path
+ std::string data_path = common_params.data_path;
+
+ // Add model path to data path
+ if(!data_path.empty())
+ {
+ data_path += model_path;
+ }
+
+ const QuantizationInfo in_quant_info = QuantizationInfo(0.0078125f, 128);
+ const QuantizationInfo mid_quant_info = QuantizationInfo(0.023528477177023888f, 128);
+
+ const std::vector<QuantizationInfo> conv_weights_quant_info =
+ {
+ QuantizationInfo(0.03396892547607422f, 122), // Conv
+ QuantizationInfo(0.005167067516595125f, 125), // Conv1
+ QuantizationInfo(0.0016910821432247758f, 113) // Conv2d_1c_1x1
+ };
+
+ // Pointwise expand convolution quantization info
+ const std::vector<QuantizationInfo> pwc_q =
+ {
+ QuantizationInfo(0.254282623529f, 129), // expand_0 (Dummy)
+ QuantizationInfo(0.009758507832884789f, 127), // expand_1
+ QuantizationInfo(0.0036556976847350597f, 144), // expand_2
+ QuantizationInfo(0.0029988749884068966f, 104), // expand_3
+ QuantizationInfo(0.0019244228024035692f, 128), // expand_4
+ QuantizationInfo(0.0013649158645421267f, 135), // expand_5
+ QuantizationInfo(0.0019170437008142471f, 127), // expand_6
+ QuantizationInfo(0.0015538912266492844f, 125), // expand_7
+ QuantizationInfo(0.0014702979242429137f, 134), // expand_8
+ QuantizationInfo(0.0013733493397012353f, 127), // expand_9
+ QuantizationInfo(0.0016282502328976989f, 131), // expand_10
+ QuantizationInfo(0.0016309921629726887f, 134), // expand_11
+ QuantizationInfo(0.0018258779309689999f, 138), // expand_12
+ QuantizationInfo(0.0013828007504343987f, 123), // expand_13
+ QuantizationInfo(0.0020222084131091833f, 135), // expand_14
+ QuantizationInfo(0.04281935095787048f, 102), // expand_15
+ QuantizationInfo(0.002046825597062707f, 135) // expand_16
+ };
+ // Depthwise expand convolution quantization info
+ const std::vector<QuantizationInfo> dwc_q =
+ {
+ QuantizationInfo(0.3436955213546753f, 165), // expand_0
+ QuantizationInfo(0.020969120785593987f, 109), // expand_1
+ QuantizationInfo(0.16981913149356842f, 52), // expand_2
+ QuantizationInfo(0.017202870920300484f, 143), // expand_3
+ QuantizationInfo(0.06525065749883652f, 118), // expand_4
+ QuantizationInfo(0.07909784466028214f, 95), // expand_5
+ QuantizationInfo(0.010087885893881321f, 127), // expand_6
+ QuantizationInfo(0.06092711538076401f, 110), // expand_7
+ QuantizationInfo(0.052407849580049515f, 133), // expand_8
+ QuantizationInfo(0.04077887907624245f, 155), // expand_9
+ QuantizationInfo(0.031107846647500992f, 143), // expand_10
+ QuantizationInfo(0.07080810517072678f, 66), // expand_11
+ QuantizationInfo(0.07448793947696686f, 159), // expand_12
+ QuantizationInfo(0.01525793131440878f, 92), // expand_13
+ QuantizationInfo(0.04166752099990845f, 147), // expand_14
+ QuantizationInfo(0.04281935095787048f, 102), // expand_15
+ QuantizationInfo(0.16456253826618195, 201) // expand_16
+ };
+ // Project convolution quantization info
+ const std::vector<QuantizationInfo> prwc_q =
+ {
+ QuantizationInfo(0.03737175464630127f, 140), // expand_0
+ QuantizationInfo(0.0225360207259655f, 156), // expand_1
+ QuantizationInfo(0.02740888111293316f, 122), // expand_2
+ QuantizationInfo(0.016844693571329117f, 111), // expand_3
+ QuantizationInfo(0.019062912091612816f, 146), // expand_4
+ QuantizationInfo(0.018293123692274094f, 128), // expand_5
+ QuantizationInfo(0.014601286500692368f, 147), // expand_6
+ QuantizationInfo(0.016782939434051514f, 124), // expand_7
+ QuantizationInfo(0.012898261658847332f, 125), // expand_8
+ QuantizationInfo(0.019561484456062317f, 144), // expand_9
+ QuantizationInfo(0.007436311338096857f, 129), // expand_10
+ QuantizationInfo(0.00838223285973072f, 136), // expand_11
+ QuantizationInfo(0.023982593789696693f, 154), // expand_12
+ QuantizationInfo(0.009447949007153511f, 140), // expand_13
+ QuantizationInfo(0.00789870135486126f, 139), // expand_14
+ QuantizationInfo(0.03697410225868225f, 131), // expand_15
+ QuantizationInfo(0.008009289391338825f, 111) // expand_16
+ };
+
+ graph << InputLayer(input_descriptor.set_quantization_info(in_quant_info),
+ get_weights_accessor(data_path, common_params.image))
+ << ConvolutionLayer(
+ 3U, 3U, 32U,
+ get_weights_accessor(data_path, "Conv_weights.npy"),
+ get_weights_accessor(data_path, "Conv_bias.npy"),
+ PadStrideInfo(2U, 2U, 0U, 1U, 0U, 1U, DimensionRoundingType::FLOOR),
+ 1, conv_weights_quant_info.at(0), mid_quant_info)
+ .set_name("Conv")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 6.f)).set_name("Conv/Relu6")
+ << DepthwiseConvolutionLayer(3U, 3U,
+ get_weights_accessor(data_path, "expanded_conv_depthwise_depthwise_weights.npy"),
+ get_weights_accessor(data_path, "expanded_conv_depthwise_depthwise_biases.npy"),
+ PadStrideInfo(1, 1, 1, 1), 1, dwc_q.at(0))
+ .set_name("expanded_conv/depthwise/depthwise")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 6.f)).set_name("expanded_conv/depthwise/Relu6")
+ << ConvolutionLayer(1U, 1U, 16U,
+ get_weights_accessor(data_path, "expanded_conv_project_weights.npy"),
+ get_weights_accessor(data_path, "expanded_conv_project_biases.npy"),
+ PadStrideInfo(1, 1, 0, 0), 1, prwc_q.at(0))
+ .set_name("expanded_conv/project/Conv2D");
+
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_1", IsResidual::No, 96U, 24U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL),
+ pwc_q.at(1), dwc_q.at(1), prwc_q.at(1));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_2", IsResidual::Yes, 144U, 24U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(2), dwc_q.at(2), prwc_q.at(2));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_3", IsResidual::No, 144U, 32U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL),
+ pwc_q.at(3), dwc_q.at(3), prwc_q.at(3));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_4", IsResidual::Yes, 192U, 32U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(4), dwc_q.at(4), prwc_q.at(4));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_5", IsResidual::Yes, 192U, 32U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(5), dwc_q.at(5), prwc_q.at(5));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_6", IsResidual::No, 192U, 64U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL),
+ pwc_q.at(6), dwc_q.at(6), prwc_q.at(6));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_7", IsResidual::Yes, 384U, 64U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(7), dwc_q.at(7), prwc_q.at(7));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_8", IsResidual::Yes, 384U, 64U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(8), dwc_q.at(8), prwc_q.at(8));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_9", IsResidual::Yes, 384U, 64U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(9), dwc_q.at(9), prwc_q.at(9));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_10", IsResidual::No, 384U, 96U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(10), dwc_q.at(10), prwc_q.at(10));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_11", IsResidual::Yes, 576U, 96U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(11), dwc_q.at(11), prwc_q.at(11));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_12", IsResidual::Yes, 576U, 96U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(12), dwc_q.at(12), prwc_q.at(12));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_13", IsResidual::No, 576U, 160U, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL),
+ pwc_q.at(13), dwc_q.at(13), prwc_q.at(13));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_14", IsResidual::Yes, 960U, 160U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(14), dwc_q.at(14), prwc_q.at(14));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_15", IsResidual::Yes, 960U, 160U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(15), dwc_q.at(15), prwc_q.at(15));
+ get_expanded_conv_qasymm8(data_path, "expanded_conv_16", IsResidual::No, 960U, 320U, PadStrideInfo(1, 1, 1, 1), pwc_q.at(16), dwc_q.at(16), prwc_q.at(16));
+
+ graph << ConvolutionLayer(1U, 1U, 1280U,
+ get_weights_accessor(data_path, "Conv_1_weights.npy"),
+ get_weights_accessor(data_path, "Conv_1_biases.npy"),
+ PadStrideInfo(1, 1, 0, 0), 1, conv_weights_quant_info.at(1))
+ .set_name("Conv_1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 6.f)).set_name("Conv_1/Relu6")
+ << PoolingLayer(PoolingLayerInfo(PoolingType::AVG)).set_name("Logits/AvgPool")
+ << ConvolutionLayer(1U, 1U, 1001U,
+ get_weights_accessor(data_path, "Logits_Conv2d_1c_1x1_weights.npy"),
+ get_weights_accessor(data_path, "Logits_Conv2d_1c_1x1_biases.npy"),
+ PadStrideInfo(1, 1, 0, 0), 1, conv_weights_quant_info.at(2))
+ .set_name("Logits/Conv2d_1c_1x1");
+ }
+
+ void get_expanded_conv_qasymm8(const std::string &data_path, std::string &¶m_path, IsResidual is_residual,
+ unsigned int input_channels, unsigned int output_channels,
+ PadStrideInfo dwc_pad_stride_info,
+ const QuantizationInfo &pwi, const QuantizationInfo &dwi, const QuantizationInfo &pji)
+ {
+ std::string total_path = param_path + "_";
+
+ SubStream left(graph);
+ left << ConvolutionLayer(1U, 1U, input_channels,
+ get_weights_accessor(data_path, total_path + "project_weights.npy"),
+ get_weights_accessor(data_path, total_path + "project_biases.npy"),
+ PadStrideInfo(1, 1, 0, 0), 1, pwi)
+ .set_name(param_path + "/Conv2D")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 6.f)).set_name(param_path + "/Conv2D/Relu6")
+ << DepthwiseConvolutionLayer(3U, 3U,
+ get_weights_accessor(data_path, total_path + "depthwise_depthwise_weights.npy"),
+ get_weights_accessor(data_path, total_path + "depthwise_depthwise_biases.npy"),
+ dwc_pad_stride_info, 1, dwi)
+ .set_name(param_path + "/depthwise/depthwise")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 6.f)).set_name(param_path + "/depthwise/Relu6")
+ << ConvolutionLayer(1U, 1U, output_channels,
+ get_weights_accessor(data_path, total_path + "project_weights.npy"),
+ get_weights_accessor(data_path, total_path + "project_biases.npy"),
+ PadStrideInfo(1, 1, 0, 0), 1, pji)
+ .set_name(param_path + "/project/Conv2D");
+
+ if(is_residual == IsResidual::Yes)
{
// Add residual node
SubStream right(graph);
@@ -242,6 +451,8 @@
* "MobileNetV2: Inverted Residuals and Linear Bottlenecks"
* Mark Sandler, Andrew Howard, Menglong Zhu, Andrey Zhmoginov, Liang-Chieh Chen
*
+ * Provenance: https://storage.googleapis.com/mobilenet_v2/checkpoints/mobilenet_v2_1.0_224.tgz
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_resnet12.cpp b/examples/graph_resnet12.cpp
new file mode 100644
index 0000000..5912863
--- /dev/null
+++ b/examples/graph_resnet12.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2018-2019 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/graph.h"
+#include "support/ToolchainSupport.h"
+#include "utils/CommonGraphOptions.h"
+#include "utils/GraphUtils.h"
+#include "utils/Utils.h"
+
+using namespace arm_compute::utils;
+using namespace arm_compute::graph::frontend;
+using namespace arm_compute::graph_utils;
+
+/** Example demonstrating how to implement ResNet12 network using the Compute Library's graph API */
+class GraphResNet12Example : public Example
+{
+public:
+ GraphResNet12Example()
+ : cmd_parser(), common_opts(cmd_parser), model_input_width(nullptr), model_input_height(nullptr), common_params(), graph(0, "ResNet12")
+ {
+ model_input_width = cmd_parser.add_option<SimpleOption<unsigned int>>("image-width", 192);
+ model_input_height = cmd_parser.add_option<SimpleOption<unsigned int>>("image-height", 128);
+
+ // Add model id option
+ model_input_width->set_help("Input image width.");
+ model_input_height->set_help("Input image height.");
+ }
+ GraphResNet12Example(const GraphResNet12Example &) = delete;
+ GraphResNet12Example &operator=(const GraphResNet12Example &) = delete;
+ GraphResNet12Example(GraphResNet12Example &&) = default; // NOLINT
+ GraphResNet12Example &operator=(GraphResNet12Example &&) = default; // NOLINT
+ ~GraphResNet12Example() override = default;
+ bool do_setup(int argc, char **argv) override
+ {
+ // Parse arguments
+ cmd_parser.parse(argc, argv);
+
+ // Consume common parameters
+ common_params = consume_common_graph_parameters(common_opts);
+
+ // Return when help menu is requested
+ if(common_params.help)
+ {
+ cmd_parser.print_help(argv[0]);
+ return false;
+ }
+
+ // Get input image width and height
+ const unsigned int image_width = model_input_width->value();
+ const unsigned int image_height = model_input_height->value();
+
+ // Checks
+ ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
+
+ // Print parameter values
+ std::cout << common_params << std::endl;
+ std::cout << "Image width: " << image_width << std::endl;
+ std::cout << "Image height: " << image_height << std::endl;
+
+ // Get trainable parameters data path
+ const std::string data_path = common_params.data_path;
+ const std::string model_path = "/cnn_data/resnet12_model/";
+
+ // Create a preprocessor object
+ std::unique_ptr<IPreprocessor> preprocessor = arm_compute::support::cpp14::make_unique<TFPreproccessor>();
+
+ // Create input descriptor
+ const TensorShape tensor_shape = permute_shape(TensorShape(image_width, image_height, 3U, 1U), DataLayout::NCHW, common_params.data_layout);
+ TensorDescriptor input_descriptor = TensorDescriptor(tensor_shape, common_params.data_type).set_layout(common_params.data_layout);
+
+ // Set weights trained layout
+ const DataLayout weights_layout = DataLayout::NCHW;
+
+ graph << common_params.target
+ << common_params.fast_math_hint
+ << InputLayer(input_descriptor, get_input_accessor(common_params, std::move(preprocessor), false /* Do not convert to BGR */))
+ << ConvolutionLayer(
+ 9U, 9U, 64U,
+ get_weights_accessor(data_path, "conv1_weights.npy", weights_layout),
+ get_weights_accessor(data_path, "conv1_biases.npy", weights_layout),
+ PadStrideInfo(1, 1, 4, 4))
+ .set_name("conv1/convolution")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv1/Relu");
+
+ add_residual_block(data_path, "block1", weights_layout);
+ add_residual_block(data_path, "block2", weights_layout);
+ add_residual_block(data_path, "block3", weights_layout);
+ add_residual_block(data_path, "block4", weights_layout);
+
+ graph << ConvolutionLayer(
+ 3U, 3U, 64U,
+ get_weights_accessor(data_path, "conv10_weights.npy", weights_layout),
+ get_weights_accessor(data_path, "conv10_biases.npy"),
+ PadStrideInfo(1, 1, 1, 1))
+ .set_name("conv10/convolution")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv10/Relu")
+ << ConvolutionLayer(
+ 3U, 3U, 64U,
+ get_weights_accessor(data_path, "conv11_weights.npy", weights_layout),
+ get_weights_accessor(data_path, "conv11_biases.npy"),
+ PadStrideInfo(1, 1, 1, 1))
+ .set_name("conv11/convolution")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv11/Relu")
+ << ConvolutionLayer(
+ 9U, 9U, 3U,
+ get_weights_accessor(data_path, "conv12_weights.npy", weights_layout),
+ get_weights_accessor(data_path, "conv12_biases.npy"),
+ PadStrideInfo(1, 1, 4, 4))
+ .set_name("conv12/convolution")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::TANH)).set_name("conv12/Tanh")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, 0.58f, 0.5f)).set_name("conv12/Linear")
+ << OutputLayer(arm_compute::support::cpp14::make_unique<DummyAccessor>(0));
+
+ // Finalize graph
+ GraphConfig config;
+ config.num_threads = common_params.threads;
+ config.use_tuner = common_params.enable_tuner;
+ config.tuner_file = common_params.tuner_file;
+
+ graph.finalize(common_params.target, config);
+
+ return true;
+ }
+
+ void do_run() override
+ {
+ // Run graph
+ graph.run();
+ }
+
+private:
+ CommandLineParser cmd_parser;
+ CommonGraphOptions common_opts;
+ SimpleOption<unsigned int> *model_input_width{ nullptr };
+ SimpleOption<unsigned int> *model_input_height{ nullptr };
+ CommonGraphParams common_params;
+ Stream graph;
+
+ void add_residual_block(const std::string &data_path, const std::string &name, DataLayout weights_layout)
+ {
+ std::stringstream unit_path_ss;
+ unit_path_ss << data_path << name << "_";
+ std::stringstream unit_name_ss;
+ unit_name_ss << name << "/";
+
+ std::string unit_path = unit_path_ss.str();
+ std::string unit_name = unit_name_ss.str();
+
+ SubStream left(graph);
+ SubStream right(graph);
+
+ right << ConvolutionLayer(
+ 3U, 3U, 64U,
+ get_weights_accessor(data_path, unit_path + "conv1_weights.npy", weights_layout),
+ get_weights_accessor(data_path, unit_path + "conv1_biases.npy", weights_layout),
+ PadStrideInfo(1, 1, 1, 1))
+ .set_name(unit_name + "conv1/convolution")
+ << BatchNormalizationLayer(
+ get_weights_accessor(data_path, unit_path + "conv1_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "conv1_BatchNorm_moving_variance.npy"),
+ get_weights_accessor(data_path, unit_path + "conv1_BatchNorm_gamma.npy"),
+ get_weights_accessor(data_path, unit_path + "conv1_BatchNorm_beta.npy"),
+ 0.0000100099996416f)
+ .set_name(unit_name + "conv1/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "conv1/Relu")
+
+ << ConvolutionLayer(
+ 3U, 3U, 64U,
+ get_weights_accessor(data_path, unit_path + "conv2_weights.npy", weights_layout),
+ get_weights_accessor(data_path, unit_path + "conv2_biases.npy", weights_layout),
+ PadStrideInfo(1, 1, 1, 1))
+ .set_name(unit_name + "conv2/convolution")
+ << BatchNormalizationLayer(
+ get_weights_accessor(data_path, unit_path + "conv2_BatchNorm_moving_mean.npy"),
+ get_weights_accessor(data_path, unit_path + "conv2_BatchNorm_moving_variance.npy"),
+ get_weights_accessor(data_path, unit_path + "conv2_BatchNorm_gamma.npy"),
+ get_weights_accessor(data_path, unit_path + "conv2_BatchNorm_beta.npy"),
+ 0.0000100099996416f)
+ .set_name(unit_name + "conv2/BatchNorm")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(unit_name + "conv2/Relu");
+
+ graph << EltwiseLayer(std::move(left), std::move(right), EltwiseOperation::Add).set_name(unit_name + "add");
+ }
+};
+
+/** Main program for ResNet12
+ *
+ * Model is based on:
+ * https://arxiv.org/pdf/1709.01118.pdf
+ * "WESPE: Weakly Supervised Photo Enhancer for Digital Cameras"
+ * Andrey Ignatov, Nikolay Kobyshev, Kenneth Vanhoey, Radu Timofte, Luc Van Gool
+ *
+ * @note To list all the possible arguments execute the binary appended with the --help option
+ *
+ * @param[in] argc Number of arguments
+ * @param[in] argv Arguments
+ */
+int main(int argc, char **argv)
+{
+ return arm_compute::utils::run_example<GraphResNet12Example>(argc, argv);
+}
diff --git a/examples/graph_resnet50.cpp b/examples/graph_resnet50.cpp
index ffdce2d..b6e20d6 100644
--- a/examples/graph_resnet50.cpp
+++ b/examples/graph_resnet50.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -56,7 +56,6 @@
// Checks
ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
- ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
// Print parameter values
std::cout << common_params << std::endl;
@@ -115,6 +114,8 @@
GraphConfig config;
config.num_threads = common_params.threads;
config.use_tuner = common_params.enable_tuner;
+ config.tuner_file = common_params.tuner_file;
+
graph.finalize(common_params.target, config);
return true;
@@ -241,6 +242,8 @@
* "Deep Residual Learning for Image Recognition"
* Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun
*
+ * Provenance: download.tensorflow.org/models/resnet_v1_50_2016_08_28.tar.gz
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_resnet_v2_50.cpp b/examples/graph_resnet_v2_50.cpp
index c5c2e29..77807b8 100644
--- a/examples/graph_resnet_v2_50.cpp
+++ b/examples/graph_resnet_v2_50.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 ARM Limited.
+ * Copyright (c) 2018-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -56,7 +56,6 @@
// Checks
ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
- ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
// Print parameter values
std::cout << common_params << std::endl;
@@ -118,6 +117,8 @@
GraphConfig config;
config.num_threads = common_params.threads;
config.use_tuner = common_params.enable_tuner;
+ config.tuner_file = common_params.tuner_file;
+
graph.finalize(common_params.target, config);
return true;
@@ -236,6 +237,8 @@
* "Identity Mappings in Deep Residual Networks"
* Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun
*
+ * Provenance: download.tensorflow.org/models/resnet_v2_50_2017_04_14.tar.gz
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_resnext50.cpp b/examples/graph_resnext50.cpp
index f611535..8b33f90 100644
--- a/examples/graph_resnext50.cpp
+++ b/examples/graph_resnext50.cpp
@@ -56,7 +56,6 @@
// Checks
ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
- ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
// Print parameter values
std::cout << common_params << std::endl;
diff --git a/examples/graph_shufflenet.cpp b/examples/graph_shufflenet.cpp
index af8d11b..e6016f0 100644
--- a/examples/graph_shufflenet.cpp
+++ b/examples/graph_shufflenet.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 ARM Limited.
+ * Copyright (c) 2018-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -57,12 +57,11 @@
// Set default layout if needed (Single kernel grouped convolution not yet supported int NHWC)
if(!common_opts.data_layout->is_set())
{
- common_params.data_layout = DataLayout::NCHW;
+ common_params.data_layout = DataLayout::NHWC;
}
// Checks
ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
- ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
// Print parameter values
std::cout << common_params << std::endl;
@@ -245,6 +244,8 @@
* "ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices"
* Xiangyu Zhang, Xinyu Zhou, Mengxiao Lin, Jian Sun
*
+ * Provenance: https://s3.amazonaws.com/download.onnx/models/opset_9/shufflenet.tar.gz
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_squeezenet.cpp b/examples/graph_squeezenet.cpp
index 17ec26e..f78fe5d 100644
--- a/examples/graph_squeezenet.cpp
+++ b/examples/graph_squeezenet.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -56,7 +56,6 @@
// Checks
ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
- ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
// Print parameter values
std::cout << common_params << std::endl;
@@ -83,75 +82,85 @@
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/conv1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/conv1_b.npy"),
PadStrideInfo(2, 2, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
- << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)))
+ .set_name("conv1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("relu_conv1")
+ << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL))).set_name("pool1")
<< ConvolutionLayer(
1U, 1U, 16U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire2_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire2_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire2", weights_layout, 64U, 64U);
+ .set_name("fire2/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire2/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire2", weights_layout, 64U, 64U).set_name("fire2/concat");
graph << ConvolutionLayer(
1U, 1U, 16U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire3_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire3_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire3", weights_layout, 64U, 64U);
+ .set_name("fire3/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire3/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire3", weights_layout, 64U, 64U).set_name("fire3/concat");
graph << ConvolutionLayer(
1U, 1U, 32U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire4_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire4_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire4", weights_layout, 128U, 128U);
- graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)))
+ .set_name("fire4/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire4/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire4", weights_layout, 128U, 128U).set_name("fire4/concat");
+ graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL))).set_name("pool4")
<< ConvolutionLayer(
1U, 1U, 32U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire5_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire5_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire5", weights_layout, 128U, 128U);
+ .set_name("fire5/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire5/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire5", weights_layout, 128U, 128U).set_name("fire5/concat");
graph << ConvolutionLayer(
1U, 1U, 48U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire6_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire6_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire6", weights_layout, 192U, 192U);
+ .set_name("fire6/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire6/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire6", weights_layout, 192U, 192U).set_name("fire6/concat");
graph << ConvolutionLayer(
1U, 1U, 48U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire7_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire7_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire7", weights_layout, 192U, 192U);
+ .set_name("fire7/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire7/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire7", weights_layout, 192U, 192U).set_name("fire7/concat");
graph << ConvolutionLayer(
1U, 1U, 64U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire8_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire8_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire8", weights_layout, 256U, 256U);
- graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)))
+ .set_name("fire8/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire8/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire8", weights_layout, 256U, 256U).set_name("fire8/concat");
+ graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL))).set_name("pool8")
<< ConvolutionLayer(
1U, 1U, 64U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire9_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire9_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire9", weights_layout, 256U, 256U);
+ .set_name("fire9/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire9/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire9", weights_layout, 256U, 256U).set_name("fire9/concat");
graph << ConvolutionLayer(
1U, 1U, 1000U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/conv10_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/conv10_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
- << PoolingLayer(PoolingLayerInfo(PoolingType::AVG))
- << FlattenLayer()
- << SoftmaxLayer()
+ .set_name("conv10")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("relu_conv10")
+ << PoolingLayer(PoolingLayerInfo(PoolingType::AVG)).set_name("pool10")
+ << FlattenLayer().set_name("flatten")
+ << SoftmaxLayer().set_name("prob")
<< OutputLayer(get_output_accessor(common_params, 5));
// Finalize graph
@@ -186,7 +195,8 @@
get_weights_accessor(data_path, total_path + "expand1x1_w.npy", weights_layout),
get_weights_accessor(data_path, total_path + "expand1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/expand1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/relu_expand1x1");
SubStream i_b(graph);
i_b << ConvolutionLayer(
@@ -194,7 +204,8 @@
get_weights_accessor(data_path, total_path + "expand3x3_w.npy", weights_layout),
get_weights_accessor(data_path, total_path + "expand3x3_b.npy"),
PadStrideInfo(1, 1, 1, 1))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/expand3x3")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/relu_expand3x3");
return ConcatLayer(std::move(i_a), std::move(i_b));
}
@@ -207,6 +218,8 @@
* "SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size"
* Forrest N. Iandola, Song Han, Matthew W. Moskewicz, Khalid Ashraf, William J. Dally, Kurt Keutzer
*
+ * Provenance: https://github.com/DeepScale/SqueezeNet/blob/master/SqueezeNet_v1.0/squeezenet_v1.0.caffemodel
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_squeezenet_v1_1.cpp b/examples/graph_squeezenet_v1_1.cpp
index bfa6938..22a15df 100644
--- a/examples/graph_squeezenet_v1_1.cpp
+++ b/examples/graph_squeezenet_v1_1.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 ARM Limited.
+ * Copyright (c) 2018-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -56,7 +56,6 @@
// Checks
ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
- ARM_COMPUTE_EXIT_ON_MSG(common_params.data_type == DataType::F16 && common_params.target == Target::NEON, "F16 NEON not supported for this graph");
// Print parameter values
std::cout << common_params << std::endl;
@@ -83,75 +82,85 @@
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/conv1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/conv1_b.npy"),
PadStrideInfo(2, 2, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
- << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)))
+ .set_name("conv1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("relu_conv1")
+ << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL))).set_name("pool1")
<< ConvolutionLayer(
1U, 1U, 16U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire2_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire2_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire2", weights_layout, 64U, 64U);
+ .set_name("fire2/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire2/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire2", weights_layout, 64U, 64U).set_name("fire2/concat");
graph << ConvolutionLayer(
1U, 1U, 16U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire3_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire3_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire3", weights_layout, 64U, 64U);
- graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)))
+ .set_name("fire3/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire3/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire3", weights_layout, 64U, 64U).set_name("fire3/concat");
+ graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL))).set_name("pool3")
<< ConvolutionLayer(
1U, 1U, 32U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire4_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire4_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire4", weights_layout, 128U, 128U);
+ .set_name("fire4/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire4/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire4", weights_layout, 128U, 128U).set_name("fire4/concat");
graph << ConvolutionLayer(
1U, 1U, 32U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire5_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire5_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire5", weights_layout, 128U, 128U);
- graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)))
+ .set_name("fire5/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire5/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire5", weights_layout, 128U, 128U).set_name("fire5/concat");
+ graph << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL))).set_name("pool5")
<< ConvolutionLayer(
1U, 1U, 48U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire6_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire6_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire6", weights_layout, 192U, 192U);
+ .set_name("fire6/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire6/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire6", weights_layout, 192U, 192U).set_name("fire6/concat");
graph << ConvolutionLayer(
1U, 1U, 48U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire7_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire7_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire7", weights_layout, 192U, 192U);
+ .set_name("fire7/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire7/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire7", weights_layout, 192U, 192U).set_name("fire7/concat");
graph << ConvolutionLayer(
1U, 1U, 64U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire8_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire8_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire8", weights_layout, 256U, 256U);
+ .set_name("fire8/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire8/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire8", weights_layout, 256U, 256U).set_name("fire8/concat");
graph << ConvolutionLayer(
1U, 1U, 64U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire9_squeeze1x1_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/fire9_squeeze1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
- graph << get_expand_fire_node(data_path, "fire9", weights_layout, 256U, 256U);
+ .set_name("fire9/squeeze1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("fire9/relu_squeeze1x1");
+ graph << get_expand_fire_node(data_path, "fire9", weights_layout, 256U, 256U).set_name("fire9/concat");
graph << ConvolutionLayer(
1U, 1U, 1000U,
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/conv10_w.npy", weights_layout),
get_weights_accessor(data_path, "/cnn_data/squeezenet_v1_1_model/conv10_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
- << PoolingLayer(PoolingLayerInfo(PoolingType::AVG))
- << FlattenLayer()
- << SoftmaxLayer()
+ .set_name("conv10")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("relu_conv10")
+ << PoolingLayer(PoolingLayerInfo(PoolingType::AVG)).set_name("pool10")
+ << FlattenLayer().set_name("flatten")
+ << SoftmaxLayer().set_name("prob")
<< OutputLayer(get_output_accessor(common_params, 5));
// Finalize graph
@@ -186,7 +195,8 @@
get_weights_accessor(data_path, total_path + "expand1x1_w.npy", weights_layout),
get_weights_accessor(data_path, total_path + "expand1x1_b.npy"),
PadStrideInfo(1, 1, 0, 0))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/expand1x1")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/relu_expand1x1");
SubStream i_b(graph);
i_b << ConvolutionLayer(
@@ -194,7 +204,8 @@
get_weights_accessor(data_path, total_path + "expand3x3_w.npy", weights_layout),
get_weights_accessor(data_path, total_path + "expand3x3_b.npy"),
PadStrideInfo(1, 1, 1, 1))
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
+ .set_name(param_path + "/expand3x3")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "/relu_expand3x3");
return ConcatLayer(std::move(i_a), std::move(i_b));
}
@@ -207,6 +218,8 @@
* "SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size"
* Forrest N. Iandola, Song Han, Matthew W. Moskewicz, Khalid Ashraf, William J. Dally, Kurt Keutzer
*
+ * Provenance: https://github.com/DeepScale/SqueezeNet/blob/master/SqueezeNet_v1.1/squeezenet_v1.1.caffemodel
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_srcnn955.cpp b/examples/graph_srcnn955.cpp
new file mode 100644
index 0000000..a8976a1
--- /dev/null
+++ b/examples/graph_srcnn955.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2018-2019 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/graph.h"
+#include "support/ToolchainSupport.h"
+#include "utils/CommonGraphOptions.h"
+#include "utils/GraphUtils.h"
+#include "utils/Utils.h"
+
+using namespace arm_compute::utils;
+using namespace arm_compute::graph::frontend;
+using namespace arm_compute::graph_utils;
+
+/** Example demonstrating how to implement SRCNN 9-5-5 network using the Compute Library's graph API */
+class GraphSRCNN955Example : public Example
+{
+public:
+ GraphSRCNN955Example()
+ : cmd_parser(), common_opts(cmd_parser), model_input_width(nullptr), model_input_height(nullptr), common_params(), graph(0, "SRCNN955")
+ {
+ model_input_width = cmd_parser.add_option<SimpleOption<unsigned int>>("image-width", 300);
+ model_input_height = cmd_parser.add_option<SimpleOption<unsigned int>>("image-height", 300);
+
+ // Add model id option
+ model_input_width->set_help("Input image width.");
+ model_input_height->set_help("Input image height.");
+ }
+ GraphSRCNN955Example(const GraphSRCNN955Example &) = delete;
+ GraphSRCNN955Example &operator=(const GraphSRCNN955Example &) = delete;
+ GraphSRCNN955Example(GraphSRCNN955Example &&) = default; // NOLINT
+ GraphSRCNN955Example &operator=(GraphSRCNN955Example &&) = default; // NOLINT
+ ~GraphSRCNN955Example() override = default;
+ bool do_setup(int argc, char **argv) override
+ {
+ // Parse arguments
+ cmd_parser.parse(argc, argv);
+
+ // Consume common parameters
+ common_params = consume_common_graph_parameters(common_opts);
+
+ // Return when help menu is requested
+ if(common_params.help)
+ {
+ cmd_parser.print_help(argv[0]);
+ return false;
+ }
+
+ // Get input image width and height
+ const unsigned int image_width = model_input_width->value();
+ const unsigned int image_height = model_input_height->value();
+
+ // Print parameter values
+ std::cout << common_params << std::endl;
+ std::cout << "Image width: " << image_width << std::endl;
+ std::cout << "Image height: " << image_height << std::endl;
+
+ // Checks
+ ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
+
+ // Get trainable parameters data path
+ const std::string data_path = common_params.data_path;
+ const std::string model_path = "/cnn_data/srcnn955_model/";
+
+ // Create a preprocessor object
+ std::unique_ptr<IPreprocessor> preprocessor = arm_compute::support::cpp14::make_unique<TFPreproccessor>();
+
+ // Create input descriptor
+ const TensorShape tensor_shape = permute_shape(TensorShape(image_width, image_height, 3U, 1U), DataLayout::NCHW, common_params.data_layout);
+ TensorDescriptor input_descriptor = TensorDescriptor(tensor_shape, common_params.data_type).set_layout(common_params.data_layout);
+
+ // Set weights trained layout
+ const DataLayout weights_layout = DataLayout::NCHW;
+
+ graph << common_params.target
+ << common_params.fast_math_hint
+ << InputLayer(input_descriptor, get_input_accessor(common_params, std::move(preprocessor), false /* Do not convert to BGR */))
+ << ConvolutionLayer(
+ 9U, 9U, 64U,
+ get_weights_accessor(data_path, "conv1_weights.npy", weights_layout),
+ get_weights_accessor(data_path, "conv1_biases.npy"),
+ PadStrideInfo(1, 1, 4, 4))
+ .set_name("conv1/convolution")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv1/Relu")
+ << ConvolutionLayer(
+ 5U, 5U, 32U,
+ get_weights_accessor(data_path, "conv2_weights.npy", weights_layout),
+ get_weights_accessor(data_path, "conv2_biases.npy"),
+ PadStrideInfo(1, 1, 2, 2))
+ .set_name("conv2/convolution")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv2/Relu")
+ << ConvolutionLayer(
+ 5U, 5U, 3U,
+ get_weights_accessor(data_path, "conv3_weights.npy", weights_layout),
+ get_weights_accessor(data_path, "conv3_biases.npy"),
+ PadStrideInfo(1, 1, 2, 2))
+ .set_name("conv3/convolution")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv3/Relu")
+ << OutputLayer(arm_compute::support::cpp14::make_unique<DummyAccessor>(0));
+
+ // Finalize graph
+ GraphConfig config;
+ config.num_threads = common_params.threads;
+ config.use_tuner = common_params.enable_tuner;
+ config.tuner_file = common_params.tuner_file;
+
+ graph.finalize(common_params.target, config);
+
+ return true;
+ }
+
+ void do_run() override
+ {
+ // Run graph
+ graph.run();
+ }
+
+private:
+ CommandLineParser cmd_parser;
+ CommonGraphOptions common_opts;
+ SimpleOption<unsigned int> *model_input_width{ nullptr };
+ SimpleOption<unsigned int> *model_input_height{ nullptr };
+ CommonGraphParams common_params;
+ Stream graph;
+};
+
+/** Main program for SRCNN 9-5-5
+ *
+ * Model is based on:
+ * http://mmlab.ie.cuhk.edu.hk/projects/SRCNN.html
+ * "Image Super-Resolution Using Deep Convolutional Networks"
+ * Chao Dong, Chen Change Loy, Kaiming He, Xiaoou Tang
+ *
+ * @note To list all the possible arguments execute the binary appended with the --help option
+ *
+ * @param[in] argc Number of arguments
+ * @param[in] argv Arguments
+ */
+int main(int argc, char **argv)
+{
+ return arm_compute::utils::run_example<GraphSRCNN955Example>(argc, argv);
+}
diff --git a/examples/graph_ssd_mobilenet.cpp b/examples/graph_ssd_mobilenet.cpp
new file mode 100644
index 0000000..780ee38
--- /dev/null
+++ b/examples/graph_ssd_mobilenet.cpp
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2018 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/graph.h"
+#include "support/ToolchainSupport.h"
+#include "utils/CommonGraphOptions.h"
+#include "utils/GraphUtils.h"
+#include "utils/Utils.h"
+
+using namespace arm_compute;
+using namespace arm_compute::utils;
+using namespace arm_compute::graph::frontend;
+using namespace arm_compute::graph_utils;
+
+/** Example demonstrating how to implement MobileNetSSD's network using the Compute Library's graph API */
+class GraphSSDMobilenetExample : public Example
+{
+public:
+ GraphSSDMobilenetExample()
+ : cmd_parser(), common_opts(cmd_parser), common_params(), graph(0, "MobileNetSSD")
+ {
+ // Add topk option
+ keep_topk_opt = cmd_parser.add_option<SimpleOption<int>>("topk", 100);
+ keep_topk_opt->set_help("Top k detections results per image.");
+ }
+ GraphSSDMobilenetExample(const GraphSSDMobilenetExample &) = delete;
+ GraphSSDMobilenetExample &operator=(const GraphSSDMobilenetExample &) = delete;
+ GraphSSDMobilenetExample(GraphSSDMobilenetExample &&) = default; // NOLINT
+ GraphSSDMobilenetExample &operator=(GraphSSDMobilenetExample &&) = default; // NOLINT
+ ~GraphSSDMobilenetExample() override = default;
+ bool do_setup(int argc, char **argv) override
+ {
+ // Parse arguments
+ cmd_parser.parse(argc, argv);
+
+ // Consume common parameters
+ common_params = consume_common_graph_parameters(common_opts);
+
+ // Return when help menu is requested
+ if(common_params.help)
+ {
+ cmd_parser.print_help(argv[0]);
+ return false;
+ }
+
+ // Print parameter values
+ std::cout << common_params << std::endl;
+
+ // Create input descriptor
+ const TensorShape tensor_shape = permute_shape(TensorShape(300, 300, 3U, 1U), DataLayout::NCHW, common_params.data_layout);
+ TensorDescriptor input_descriptor = TensorDescriptor(tensor_shape, common_params.data_type).set_layout(common_params.data_layout);
+
+ // Set graph hints
+ graph << common_params.target
+ << DepthwiseConvolutionMethod::Optimized3x3 // FIXME(COMPMID-1073): Add heuristics to automatically call the optimized 3x3 method
+ << common_params.fast_math_hint;
+
+ // Create core graph
+ std::string model_path = "/cnn_data/ssd_mobilenet_model/";
+
+ // Create a preprocessor object
+ const std::array<float, 3> mean_rgb{ { 127.5f, 127.5f, 127.5f } };
+ std::unique_ptr<IPreprocessor> preprocessor = arm_compute::support::cpp14::make_unique<CaffePreproccessor>(mean_rgb, 0.007843f);
+
+ // Get trainable parameters data path
+ std::string data_path = common_params.data_path;
+
+ // Add model path to data path
+ if(!data_path.empty())
+ {
+ data_path += model_path;
+ }
+
+ graph << InputLayer(input_descriptor,
+ get_input_accessor(common_params, std::move(preprocessor)));
+
+ SubStream conv_11(graph);
+ conv_11 << ConvolutionLayer(
+ 3U, 3U, 32U,
+ get_weights_accessor(data_path, "conv0_w.npy"),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ PadStrideInfo(2, 2, 1, 1))
+ .set_name("conv0");
+ conv_11 << BatchNormalizationLayer(get_weights_accessor(data_path, "conv0_bn_mean.npy"),
+ get_weights_accessor(data_path, "conv0_bn_var.npy"),
+ get_weights_accessor(data_path, "conv0_scale_w.npy"),
+ get_weights_accessor(data_path, "conv0_scale_b.npy"), 0.00001f)
+ .set_name("conv0/bn")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv0/relu");
+
+ conv_11 << get_node_A(conv_11, data_path, "conv1", 64, PadStrideInfo(1, 1, 1, 1), PadStrideInfo(1, 1, 0, 0));
+ conv_11 << get_node_A(conv_11, data_path, "conv2", 128, PadStrideInfo(2, 2, 1, 1), PadStrideInfo(1, 1, 0, 0));
+ conv_11 << get_node_A(conv_11, data_path, "conv3", 128, PadStrideInfo(1, 1, 1, 1), PadStrideInfo(1, 1, 0, 0));
+ conv_11 << get_node_A(conv_11, data_path, "conv4", 256, PadStrideInfo(2, 2, 1, 1), PadStrideInfo(1, 1, 0, 0));
+ conv_11 << get_node_A(conv_11, data_path, "conv5", 256, PadStrideInfo(1, 1, 1, 1), PadStrideInfo(1, 1, 0, 0));
+ conv_11 << get_node_A(conv_11, data_path, "conv6", 512, PadStrideInfo(2, 2, 1, 1), PadStrideInfo(1, 1, 0, 0));
+ conv_11 << get_node_A(conv_11, data_path, "conv7", 512, PadStrideInfo(1, 1, 1, 1), PadStrideInfo(1, 1, 0, 0));
+ conv_11 << get_node_A(conv_11, data_path, "conv8", 512, PadStrideInfo(1, 1, 1, 1), PadStrideInfo(1, 1, 0, 0));
+ conv_11 << get_node_A(conv_11, data_path, "conv9", 512, PadStrideInfo(1, 1, 1, 1), PadStrideInfo(1, 1, 0, 0));
+ conv_11 << get_node_A(conv_11, data_path, "conv10", 512, PadStrideInfo(1, 1, 1, 1), PadStrideInfo(1, 1, 0, 0));
+ conv_11 << get_node_A(conv_11, data_path, "conv11", 512, PadStrideInfo(1, 1, 1, 1), PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_13(conv_11);
+ conv_13 << get_node_A(conv_11, data_path, "conv12", 1024, PadStrideInfo(2, 2, 1, 1), PadStrideInfo(1, 1, 0, 0));
+ conv_13 << get_node_A(conv_13, data_path, "conv13", 1024, PadStrideInfo(1, 1, 1, 1), PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_14(conv_13);
+ conv_14 << get_node_B(conv_13, data_path, "conv14", 512, PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 2, 1, 1));
+
+ SubStream conv_15(conv_14);
+ conv_15 << get_node_B(conv_14, data_path, "conv15", 256, PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 2, 1, 1));
+
+ SubStream conv_16(conv_15);
+ conv_16 << get_node_B(conv_15, data_path, "conv16", 256, PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 2, 1, 1));
+
+ SubStream conv_17(conv_16);
+ conv_17 << get_node_B(conv_16, data_path, "conv17", 128, PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 2, 1, 1));
+
+ //mbox_loc
+ SubStream conv_11_mbox_loc(conv_11);
+ conv_11_mbox_loc << get_node_C(conv_11, data_path, "conv11_mbox_loc", 12, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_13_mbox_loc(conv_13);
+ conv_13_mbox_loc << get_node_C(conv_13, data_path, "conv13_mbox_loc", 24, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_14_2_mbox_loc(conv_14);
+ conv_14_2_mbox_loc << get_node_C(conv_14, data_path, "conv14_2_mbox_loc", 24, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_15_2_mbox_loc(conv_15);
+ conv_15_2_mbox_loc << get_node_C(conv_15, data_path, "conv15_2_mbox_loc", 24, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_16_2_mbox_loc(conv_16);
+ conv_16_2_mbox_loc << get_node_C(conv_16, data_path, "conv16_2_mbox_loc", 24, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_17_2_mbox_loc(conv_17);
+ conv_17_2_mbox_loc << get_node_C(conv_17, data_path, "conv17_2_mbox_loc", 24, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream mbox_loc(graph);
+ mbox_loc << ConcatLayer(std::move(conv_11_mbox_loc), std::move(conv_13_mbox_loc), conv_14_2_mbox_loc, std::move(conv_15_2_mbox_loc),
+ std::move(conv_16_2_mbox_loc), std::move(conv_17_2_mbox_loc));
+
+ //mbox_conf
+ SubStream conv_11_mbox_conf(conv_11);
+ conv_11_mbox_conf << get_node_C(conv_11, data_path, "conv11_mbox_conf", 63, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_13_mbox_conf(conv_13);
+ conv_13_mbox_conf << get_node_C(conv_13, data_path, "conv13_mbox_conf", 126, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_14_2_mbox_conf(conv_14);
+ conv_14_2_mbox_conf << get_node_C(conv_14, data_path, "conv14_2_mbox_conf", 126, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_15_2_mbox_conf(conv_15);
+ conv_15_2_mbox_conf << get_node_C(conv_15, data_path, "conv15_2_mbox_conf", 126, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_16_2_mbox_conf(conv_16);
+ conv_16_2_mbox_conf << get_node_C(conv_16, data_path, "conv16_2_mbox_conf", 126, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream conv_17_2_mbox_conf(conv_17);
+ conv_17_2_mbox_conf << get_node_C(conv_17, data_path, "conv17_2_mbox_conf", 126, PadStrideInfo(1, 1, 0, 0));
+
+ SubStream mbox_conf(graph);
+ mbox_conf << ConcatLayer(std::move(conv_11_mbox_conf), std::move(conv_13_mbox_conf), std::move(conv_14_2_mbox_conf),
+ std::move(conv_15_2_mbox_conf), std::move(conv_16_2_mbox_conf), std::move(conv_17_2_mbox_conf));
+ mbox_conf << ReshapeLayer(TensorShape(21U, 1917U)).set_name("mbox_conf/reshape");
+ mbox_conf << SoftmaxLayer().set_name("mbox_conf/softmax");
+ mbox_conf << FlattenLayer().set_name("mbox_conf/flat");
+
+ const std::vector<float> priorbox_variances = { 0.1f, 0.1f, 0.2f, 0.2f };
+ const float priorbox_offset = 0.5f;
+ const std::vector<float> priorbox_aspect_ratios = { 2.f, 3.f };
+
+ //mbox_priorbox branch
+ SubStream conv_11_mbox_priorbox(conv_11);
+
+ conv_11_mbox_priorbox << PriorBoxLayer(SubStream(graph),
+ PriorBoxLayerInfo({ 60.f }, priorbox_variances, priorbox_offset, true, false, {}, { 2.f }))
+ .set_name("conv11/priorbox");
+
+ SubStream conv_13_mbox_priorbox(conv_13);
+ conv_13_mbox_priorbox << PriorBoxLayer(SubStream(graph),
+ PriorBoxLayerInfo({ 105.f }, priorbox_variances, priorbox_offset, true, false, { 150.f }, priorbox_aspect_ratios))
+ .set_name("conv13/priorbox");
+
+ SubStream conv_14_2_mbox_priorbox(conv_14);
+ conv_14_2_mbox_priorbox << PriorBoxLayer(SubStream(graph),
+ PriorBoxLayerInfo({ 150.f }, priorbox_variances, priorbox_offset, true, false, { 195.f }, priorbox_aspect_ratios))
+ .set_name("conv14/priorbox");
+
+ SubStream conv_15_2_mbox_priorbox(conv_15);
+ conv_15_2_mbox_priorbox << PriorBoxLayer(SubStream(graph),
+ PriorBoxLayerInfo({ 195.f }, priorbox_variances, priorbox_offset, true, false, { 240.f }, priorbox_aspect_ratios))
+ .set_name("conv15/priorbox");
+
+ SubStream conv_16_2_mbox_priorbox(conv_16);
+ conv_16_2_mbox_priorbox << PriorBoxLayer(SubStream(graph),
+ PriorBoxLayerInfo({ 240.f }, priorbox_variances, priorbox_offset, true, false, { 285.f }, priorbox_aspect_ratios))
+ .set_name("conv16/priorbox");
+
+ SubStream conv_17_2_mbox_priorbox(conv_17);
+ conv_17_2_mbox_priorbox << PriorBoxLayer(SubStream(graph),
+ PriorBoxLayerInfo({ 285.f }, priorbox_variances, priorbox_offset, true, false, { 300.f }, priorbox_aspect_ratios))
+ .set_name("conv17/priorbox");
+
+ SubStream mbox_priorbox(graph);
+
+ mbox_priorbox << ConcatLayer(
+ (common_params.data_layout == DataLayout::NCHW) ? DataLayoutDimension::WIDTH : DataLayoutDimension::CHANNEL,
+ std::move(conv_11_mbox_priorbox), std::move(conv_13_mbox_priorbox), std::move(conv_14_2_mbox_priorbox),
+ std::move(conv_15_2_mbox_priorbox), std::move(conv_16_2_mbox_priorbox), std::move(conv_17_2_mbox_priorbox));
+
+ const int num_classes = 21;
+ const bool share_location = true;
+ const DetectionOutputLayerCodeType detection_type = DetectionOutputLayerCodeType::CENTER_SIZE;
+ const int keep_top_k = keep_topk_opt->value();
+ const float nms_threshold = 0.45f;
+ const int label_id_background = 0;
+ const float conf_thrs = 0.25f;
+ const int top_k = 100;
+
+ SubStream detection_ouput(mbox_loc);
+ detection_ouput << DetectionOutputLayer(std::move(mbox_conf), std::move(mbox_priorbox),
+ DetectionOutputLayerInfo(num_classes, share_location, detection_type, keep_top_k, nms_threshold, top_k, label_id_background, conf_thrs));
+ detection_ouput << OutputLayer(get_detection_output_accessor(common_params, { tensor_shape }));
+
+ // Finalize graph
+ GraphConfig config;
+ config.num_threads = common_params.threads;
+ config.use_tuner = common_params.enable_tuner;
+ config.tuner_file = common_params.tuner_file;
+
+ graph.finalize(common_params.target, config);
+
+ return true;
+ }
+ void do_run() override
+ {
+ // Run graph
+ graph.run();
+ }
+
+private:
+ CommandLineParser cmd_parser;
+ CommonGraphOptions common_opts;
+ SimpleOption<int> *keep_topk_opt{ nullptr };
+ CommonGraphParams common_params;
+ Stream graph;
+
+ ConcatLayer get_node_A(IStream &master_graph, const std::string &data_path, std::string &¶m_path,
+ unsigned int conv_filt,
+ PadStrideInfo dwc_pad_stride_info, PadStrideInfo conv_pad_stride_info)
+ {
+ const std::string total_path = param_path + "_";
+ SubStream sg(master_graph);
+
+ sg << DepthwiseConvolutionLayer(
+ 3U, 3U,
+ get_weights_accessor(data_path, total_path + "dw_w.npy"),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ dwc_pad_stride_info)
+ .set_name(param_path + "/dw")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "dw_bn_mean.npy"),
+ get_weights_accessor(data_path, total_path + "dw_bn_var.npy"),
+ get_weights_accessor(data_path, total_path + "dw_scale_w.npy"),
+ get_weights_accessor(data_path, total_path + "dw_scale_b.npy"), 0.00001f)
+ .set_name(param_path + "/dw/bn")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "dw/relu")
+
+ << ConvolutionLayer(
+ 1U, 1U, conv_filt,
+ get_weights_accessor(data_path, total_path + "w.npy"),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ conv_pad_stride_info)
+ .set_name(param_path + "/pw")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "bn_mean.npy"),
+ get_weights_accessor(data_path, total_path + "bn_var.npy"),
+ get_weights_accessor(data_path, total_path + "scale_w.npy"),
+ get_weights_accessor(data_path, total_path + "scale_b.npy"), 0.00001f)
+ .set_name(param_path + "/pw/bn")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(param_path + "pw/relu");
+
+ return ConcatLayer(std::move(sg));
+ }
+
+ ConcatLayer get_node_B(IStream &master_graph, const std::string &data_path, std::string &¶m_path,
+ unsigned int conv_filt,
+ PadStrideInfo conv_pad_stride_info_1, PadStrideInfo conv_pad_stride_info_2)
+ {
+ const std::string total_path = param_path + "_";
+ SubStream sg(master_graph);
+
+ sg << ConvolutionLayer(
+ 1, 1, conv_filt / 2,
+ get_weights_accessor(data_path, total_path + "1_w.npy"),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ conv_pad_stride_info_1)
+ .set_name(total_path + "1/conv")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "1_bn_mean.npy"),
+ get_weights_accessor(data_path, total_path + "1_bn_var.npy"),
+ get_weights_accessor(data_path, total_path + "1_scale_w.npy"),
+ get_weights_accessor(data_path, total_path + "1_scale_b.npy"), 0.00001f)
+ .set_name(total_path + "1/bn")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(total_path + "1/relu");
+
+ sg << ConvolutionLayer(
+ 3, 3, conv_filt,
+ get_weights_accessor(data_path, total_path + "2_w.npy"),
+ std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
+ conv_pad_stride_info_2)
+ .set_name(total_path + "2/conv")
+ << BatchNormalizationLayer(get_weights_accessor(data_path, total_path + "2_bn_mean.npy"),
+ get_weights_accessor(data_path, total_path + "2_bn_var.npy"),
+ get_weights_accessor(data_path, total_path + "2_scale_w.npy"),
+ get_weights_accessor(data_path, total_path + "2_scale_b.npy"), 0.00001f)
+ .set_name(total_path + "2/bn")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(total_path + "2/relu");
+
+ return ConcatLayer(std::move(sg));
+ }
+
+ ConcatLayer get_node_C(IStream &master_graph, const std::string &data_path, std::string &¶m_path,
+ unsigned int conv_filt, PadStrideInfo conv_pad_stride_info)
+ {
+ const std::string total_path = param_path + "_";
+ SubStream sg(master_graph);
+ sg << ConvolutionLayer(
+ 1U, 1U, conv_filt,
+ get_weights_accessor(data_path, total_path + "w.npy"),
+ get_weights_accessor(data_path, total_path + "b.npy"),
+ conv_pad_stride_info)
+ .set_name(param_path + "/conv");
+ if(common_params.data_layout == DataLayout::NCHW)
+ {
+ sg << PermuteLayer(PermutationVector(2U, 0U, 1U), DataLayout::NHWC).set_name(param_path + "/perm");
+ }
+ sg << FlattenLayer().set_name(param_path + "/flat");
+
+ return ConcatLayer(std::move(sg));
+ }
+};
+
+/** Main program for MobileNetSSD
+ *
+ * Model is based on:
+ * http://arxiv.org/abs/1512.02325
+ * SSD: Single Shot MultiBox Detector
+ * Wei Liu, Dragomir Anguelov, Dumitru Erhan, Christian Szegedy, Scott Reed, Cheng-Yang Fu, Alexander C. Berg
+ *
+ * Provenance: https://github.com/chuanqi305/MobileNet-SSD
+ *
+ * @note To list all the possible arguments execute the binary appended with the --help option
+ *
+ * @param[in] argc Number of arguments
+ * @param[in] argv Arguments
+ */
+int main(int argc, char **argv)
+{
+ return arm_compute::utils::run_example<GraphSSDMobilenetExample>(argc, argv);
+}
diff --git a/examples/graph_vgg16.cpp b/examples/graph_vgg16.cpp
index 482aab1..290d1e7 100644
--- a/examples/graph_vgg16.cpp
+++ b/examples/graph_vgg16.cpp
@@ -251,6 +251,8 @@
* "Very Deep Convolutional Networks for Large-Scale Image Recognition"
* Karen Simonyan, Andrew Zisserman
*
+ * Provenance: www.robots.ox.ac.uk/~vgg/software/very_deep/caffe/VGG_ILSVRC_16_layers.caffemodel
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_vgg19.cpp b/examples/graph_vgg19.cpp
index 3b17735..298ffa0 100644
--- a/examples/graph_vgg19.cpp
+++ b/examples/graph_vgg19.cpp
@@ -262,6 +262,8 @@
* "Very Deep Convolutional Networks for Large-Scale Image Recognition"
* Karen Simonyan, Andrew Zisserman
*
+ * Provenance: www.robots.ox.ac.uk/~vgg/software/very_deep/caffe/VGG_ILSVRC_19_layers.caffemodel
+ *
* @note To list all the possible arguments execute the binary appended with the --help option
*
* @param[in] argc Number of arguments
diff --git a/examples/graph_vgg_vdsr.cpp b/examples/graph_vgg_vdsr.cpp
new file mode 100644
index 0000000..ca7d10f
--- /dev/null
+++ b/examples/graph_vgg_vdsr.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2018 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/graph.h"
+#include "support/ToolchainSupport.h"
+#include "utils/CommonGraphOptions.h"
+#include "utils/GraphUtils.h"
+#include "utils/Utils.h"
+
+using namespace arm_compute;
+using namespace arm_compute::utils;
+using namespace arm_compute::graph::frontend;
+using namespace arm_compute::graph_utils;
+
+/** Example demonstrating how to implement VGG based VDSR network using the Compute Library's graph API */
+class GraphVDSRExample : public Example
+{
+public:
+ GraphVDSRExample()
+ : cmd_parser(), common_opts(cmd_parser), common_params(), graph(0, "VDSR")
+ {
+ model_input_width = cmd_parser.add_option<SimpleOption<unsigned int>>("image-width", 192);
+ model_input_height = cmd_parser.add_option<SimpleOption<unsigned int>>("image-height", 192);
+
+ // Add model id option
+ model_input_width->set_help("Input image width.");
+ model_input_height->set_help("Input image height.");
+ }
+ GraphVDSRExample(const GraphVDSRExample &) = delete;
+ GraphVDSRExample &operator=(const GraphVDSRExample &) = delete;
+ GraphVDSRExample(GraphVDSRExample &&) = default; // NOLINT
+ GraphVDSRExample &operator=(GraphVDSRExample &&) = default; // NOLINT
+ ~GraphVDSRExample() override = default;
+ bool do_setup(int argc, char **argv) override
+ {
+ // Parse arguments
+ cmd_parser.parse(argc, argv);
+
+ // Consume common parameters
+ common_params = consume_common_graph_parameters(common_opts);
+
+ // Return when help menu is requested
+ if(common_params.help)
+ {
+ cmd_parser.print_help(argv[0]);
+ return false;
+ }
+
+ // Get input image width and height
+ const unsigned int image_width = model_input_width->value();
+ const unsigned int image_height = model_input_height->value();
+
+ // Print parameter values
+ std::cout << common_params << std::endl;
+ std::cout << "Image width: " << image_width << std::endl;
+ std::cout << "Image height: " << image_height << std::endl;
+
+ // Get trainable parameters data path
+ const std::string data_path = common_params.data_path;
+ const std::string model_path = "/cnn_data/vdsr_model/";
+
+ // Create a preprocessor object
+ std::unique_ptr<IPreprocessor> preprocessor = arm_compute::support::cpp14::make_unique<TFPreproccessor>();
+
+ // Create input descriptor
+ const TensorShape tensor_shape = permute_shape(TensorShape(image_width, image_height, 1U, 1U), DataLayout::NCHW, common_params.data_layout);
+ TensorDescriptor input_descriptor = TensorDescriptor(tensor_shape, common_params.data_type).set_layout(common_params.data_layout);
+
+ // Set weights trained layout
+ const DataLayout weights_layout = DataLayout::NCHW;
+
+ // Note: Quantization info are random and used only for benchmarking purposes
+ graph << common_params.target
+ << common_params.fast_math_hint
+ << InputLayer(input_descriptor.set_quantization_info(QuantizationInfo(0.0078125f, 128)),
+ get_input_accessor(common_params, std::move(preprocessor), false));
+
+ SubStream left(graph);
+ SubStream right(graph);
+
+ // Layer 1
+ right << ConvolutionLayer(
+ 3U, 3U, 64U,
+ get_weights_accessor(data_path, "conv0_w.npy", weights_layout),
+ get_weights_accessor(data_path, "conv0_b.npy"),
+ PadStrideInfo(1, 1, 1, 1), 1, QuantizationInfo(0.031778190285f, 156), QuantizationInfo(0.0784313753247f, 128))
+ .set_name("conv0")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv0/Relu");
+
+ // Rest 17 layers
+ for(unsigned int i = 1; i < 19; ++i)
+ {
+ const std::string conv_w_path = "conv" + arm_compute::support::cpp11::to_string(i) + "_w.npy";
+ const std::string conv_b_path = "conv" + arm_compute::support::cpp11::to_string(i) + "_b.npy";
+ const std::string conv_name = "conv" + arm_compute::support::cpp11::to_string(i);
+ right << ConvolutionLayer(
+ 3U, 3U, 64U,
+ get_weights_accessor(data_path, conv_w_path, weights_layout),
+ get_weights_accessor(data_path, conv_b_path),
+ PadStrideInfo(1, 1, 1, 1), 1, QuantizationInfo(0.015851572156f, 93))
+ .set_name(conv_name)
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name(conv_name + "/Relu");
+ }
+
+ // Final layer
+ right << ConvolutionLayer(
+ 3U, 3U, 1U,
+ get_weights_accessor(data_path, "conv20_w.npy", weights_layout),
+ get_weights_accessor(data_path, "conv20_b.npy"),
+ PadStrideInfo(1, 1, 1, 1), 1, QuantizationInfo(0.015851572156f, 93))
+ .set_name("conv20")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("conv20/Relu");
+
+ // Add residual to input
+ graph << EltwiseLayer(std::move(left), std::move(right), EltwiseOperation::Add).set_name("add")
+ << OutputLayer(arm_compute::support::cpp14::make_unique<DummyAccessor>(0));
+
+ // Finalize graph
+ GraphConfig config;
+ config.num_threads = common_params.threads;
+ config.use_tuner = common_params.enable_tuner;
+ config.tuner_file = common_params.tuner_file;
+
+ graph.finalize(common_params.target, config);
+
+ return true;
+ }
+ void do_run() override
+ {
+ // Run graph
+ graph.run();
+ }
+
+private:
+ CommandLineParser cmd_parser;
+ CommonGraphOptions common_opts;
+ SimpleOption<unsigned int> *model_input_width{ nullptr };
+ SimpleOption<unsigned int> *model_input_height{ nullptr };
+ CommonGraphParams common_params;
+ Stream graph;
+};
+
+/** Main program for VGG-based VDSR
+ *
+ * Model is based on:
+ * https://arxiv.org/pdf/1511.04587.pdf
+ * "Accurate Image Super-Resolution Using Very Deep Convolutional Networks"
+ * Jiwon Kim, Jung Kwon Lee and Kyoung Mu Lee
+ *
+ * @note To list all the possible arguments execute the binary appended with the --help option
+ *
+ * @param[in] argc Number of arguments
+ * @param[in] argv Arguments
+ */
+int main(int argc, char **argv)
+{
+ return arm_compute::utils::run_example<GraphVDSRExample>(argc, argv);
+}
diff --git a/examples/graph_yolov3.cpp b/examples/graph_yolov3.cpp
index 11d564c..6d0f67e 100644
--- a/examples/graph_yolov3.cpp
+++ b/examples/graph_yolov3.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 ARM Limited.
+ * Copyright (c) 2018-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -170,7 +170,7 @@
PadStrideInfo(1, 1, 0, 0))
.set_name("conv2d_59")
<< ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, 1.f)).set_name("conv2d_59/Linear")
- << YOLOLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC, 0.1f), 80)
+ << YOLOLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC, 0.1f), 80).set_name("Yolo1")
<< OutputLayer(get_output_accessor(common_params, 5));
route_1 << ConvolutionLayer(
1U, 1U, 256U,
@@ -188,7 +188,7 @@
<< ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_60/LeakyRelu")
<< UpsampleLayer(Size2D(2, 2), InterpolationPolicy::NEAREST_NEIGHBOR).set_name("Upsample_60");
SubStream concat_1(route_1);
- concat_1 << ConcatLayer(std::move(route_1), std::move(intermediate_layers.second))
+ concat_1 << ConcatLayer(std::move(route_1), std::move(intermediate_layers.second)).set_name("Route1")
<< ConvolutionLayer(
1U, 1U, 256U,
get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_61_w.npy", weights_layout),
@@ -281,7 +281,7 @@
PadStrideInfo(1, 1, 0, 0))
.set_name("conv2d_67")
<< ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, 1.f)).set_name("conv2d_67/Linear")
- << YOLOLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC, 0.1f), 80)
+ << YOLOLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC, 0.1f), 80).set_name("Yolo2")
<< OutputLayer(get_output_accessor(common_params, 5));
route_2 << ConvolutionLayer(
1U, 1U, 128U,
@@ -299,7 +299,7 @@
<< ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_68/LeakyRelu")
<< UpsampleLayer(Size2D(2, 2), InterpolationPolicy::NEAREST_NEIGHBOR).set_name("Upsample_68");
SubStream concat_2(route_2);
- concat_2 << ConcatLayer(std::move(route_2), std::move(intermediate_layers.first))
+ concat_2 << ConcatLayer(std::move(route_2), std::move(intermediate_layers.first)).set_name("Route2")
<< ConvolutionLayer(
1U, 1U, 128U,
get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_69_w.npy", weights_layout),
@@ -391,7 +391,7 @@
PadStrideInfo(1, 1, 0, 0))
.set_name("conv2d_75")
<< ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, 1.f)).set_name("conv2d_75/Linear")
- << YOLOLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC, 0.1f), 80)
+ << YOLOLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC, 0.1f), 80).set_name("Yolo3")
<< OutputLayer(get_output_accessor(common_params, 5));
// Finalize graph
@@ -423,7 +423,7 @@
get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_1_w.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(1, 1, 1, 1))
- .set_name("conv2d_1")
+ .set_name("conv2d_1/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_1_mean.npy"),
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_1_var.npy"),
@@ -437,7 +437,7 @@
get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_2_w.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(2, 2, 1, 1))
- .set_name("conv2d_2")
+ .set_name("conv2d_2/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_2_mean.npy"),
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_2_var.npy"),
@@ -452,7 +452,7 @@
get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_5_w.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(2, 2, 1, 1))
- .set_name("conv2d_5")
+ .set_name("conv2d_5/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_5_mean.npy"),
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_5_var.npy"),
@@ -468,7 +468,7 @@
get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_10_w.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(2, 2, 1, 1))
- .set_name("conv2d_10")
+ .set_name("conv2d_10/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_10_mean.npy"),
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_10_var.npy"),
@@ -491,7 +491,7 @@
get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_27_w.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(2, 2, 1, 1))
- .set_name("conv2d_27")
+ .set_name("conv2d_27/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_27_mean.npy"),
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_27_var.npy"),
@@ -514,7 +514,7 @@
get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_44_w.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(2, 2, 1, 1))
- .set_name("conv2d_44")
+ .set_name("conv2d_44/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_44_mean.npy"),
get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_44_var.npy"),
@@ -543,6 +543,7 @@
get_weights_accessor(data_path, total_path + "conv2d_" + param_path + "_w.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(1, 1, 0, 0))
+ .set_name("conv2d_" + param_path + "/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path + "_mean.npy"),
get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path + "_var.npy"),
@@ -550,12 +551,13 @@
get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path + "_beta.npy"),
0.000001f)
.set_name("conv2d_" + param_path + "/BatchNorm")
- << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d" + param_path + "/LeakyRelu")
+ << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_" + param_path + "/LeakyRelu")
<< ConvolutionLayer(
3U, 3U, filter_size * 2,
get_weights_accessor(data_path, total_path + "conv2d_" + param_path2 + "_w.npy", weights_layout),
std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
PadStrideInfo(1, 1, 1, 1))
+ .set_name("conv2d_" + param_path2 + "/Conv2D")
<< BatchNormalizationLayer(
get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path2 + "_mean.npy"),
get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path2 + "_var.npy"),
@@ -565,7 +567,7 @@
.set_name("conv2d_" + param_path2 + "/BatchNorm")
<< ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_" + param_path2 + "/LeakyRelu");
- graph << EltwiseLayer(std::move(i_a), std::move(i_b), EltwiseOperation::Add);
+ graph << EltwiseLayer(std::move(i_a), std::move(i_b), EltwiseOperation::Add).set_name("").set_name("add_" + param_path + "_" + param_path2);
}
};