Compute Library
 21.02
graph_yolov3.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2021 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #include "arm_compute/graph.h"
27 #include "utils/GraphUtils.h"
28 #include "utils/Utils.h"
29 
30 using namespace arm_compute::utils;
31 using namespace arm_compute::graph::frontend;
32 using namespace arm_compute::graph_utils;
33 
34 /** Example demonstrating how to implement YOLOv3 network using the Compute Library's graph API */
35 class GraphYOLOv3Example : public Example
36 {
37 public:
38  GraphYOLOv3Example()
39  : cmd_parser(), common_opts(cmd_parser), common_params(), graph(0, "YOLOv3")
40  {
41  }
42 
43  bool do_setup(int argc, char **argv) override
44  {
45  // Parse arguments
46  cmd_parser.parse(argc, argv);
47  cmd_parser.validate();
48 
49  // Consume common parameters
50  common_params = consume_common_graph_parameters(common_opts);
51 
52  // Return when help menu is requested
53  if(common_params.help)
54  {
55  cmd_parser.print_help(argv[0]);
56  return false;
57  }
58 
59  // Checks
60  ARM_COMPUTE_EXIT_ON_MSG(arm_compute::is_data_type_quantized_asymmetric(common_params.data_type), "QASYMM8 not supported for this graph");
61 
62  // Print parameter values
63  std::cout << common_params << std::endl;
64 
65  // Get trainable parameters data path
66  std::string data_path = common_params.data_path;
67 
68  // Create a preprocessor object
69  std::unique_ptr<IPreprocessor> preprocessor = std::make_unique<TFPreproccessor>(0.f);
70 
71  // Create input descriptor
72  const TensorShape tensor_shape = permute_shape(TensorShape(608U, 608U, 3U, 1U), DataLayout::NCHW, common_params.data_layout);
73  TensorDescriptor input_descriptor = TensorDescriptor(tensor_shape, common_params.data_type).set_layout(common_params.data_layout);
74 
75  // Set weights trained layout
76  const DataLayout weights_layout = DataLayout::NCHW;
77 
78  graph << common_params.target
79  << common_params.fast_math_hint
80  << InputLayer(input_descriptor, get_input_accessor(common_params, std::move(preprocessor), false));
81  std::pair<SubStream, SubStream> intermediate_layers = darknet53(data_path, weights_layout);
82  graph << ConvolutionLayer(
83  1U, 1U, 512U,
84  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_53_w.npy", weights_layout),
85  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
86  PadStrideInfo(1, 1, 0, 0))
87  .set_name("conv2d_53")
89  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_53_mean.npy"),
90  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_53_var.npy"),
91  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_53_gamma.npy"),
92  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_53_beta.npy"),
93  0.000001f)
94  .set_name("conv2d_53/BatchNorm")
95  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_53/LeakyRelu")
97  3U, 3U, 1024U,
98  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_54_w.npy", weights_layout),
99  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
100  PadStrideInfo(1, 1, 1, 1))
101  .set_name("conv2d_54")
103  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_54_mean.npy"),
104  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_54_var.npy"),
105  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_54_gamma.npy"),
106  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_54_beta.npy"),
107  0.000001f)
108  .set_name("conv2d_54/BatchNorm")
109  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_54/LeakyRelu")
110  << ConvolutionLayer(
111  1U, 1U, 512U,
112  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_55_w.npy", weights_layout),
113  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
114  PadStrideInfo(1, 1, 0, 0))
115  .set_name("conv2d_55")
117  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_55_mean.npy"),
118  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_55_var.npy"),
119  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_55_gamma.npy"),
120  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_55_beta.npy"),
121  0.000001f)
122  .set_name("conv2d_55/BatchNorm")
123  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_55/LeakyRelu")
124  << ConvolutionLayer(
125  3U, 3U, 1024U,
126  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_56_w.npy", weights_layout),
127  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
128  PadStrideInfo(1, 1, 1, 1))
129  .set_name("conv2d_56")
131  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_56_mean.npy"),
132  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_56_var.npy"),
133  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_56_gamma.npy"),
134  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_56_beta.npy"),
135  0.000001f)
136  .set_name("conv2d_56/BatchNorm")
137  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_56/LeakyRelu")
138  << ConvolutionLayer(
139  1U, 1U, 512U,
140  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_57_w.npy", weights_layout),
141  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
142  PadStrideInfo(1, 1, 0, 0))
143  .set_name("conv2d_57")
145  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_57_mean.npy"),
146  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_57_var.npy"),
147  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_57_gamma.npy"),
148  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_57_beta.npy"),
149  0.000001f)
150  .set_name("conv2d_57/BatchNorm")
151  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_57/LeakyRelu");
152  SubStream route_1(graph);
153  graph << ConvolutionLayer(
154  3U, 3U, 1024U,
155  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_58_w.npy", weights_layout),
156  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
157  PadStrideInfo(1, 1, 1, 1))
158  .set_name("conv2d_58")
160  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_58_mean.npy"),
161  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_58_var.npy"),
162  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_58_gamma.npy"),
163  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_58_beta.npy"),
164  0.000001f)
165  .set_name("conv2d_58/BatchNorm")
166  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_58/LeakyRelu")
167  << ConvolutionLayer(
168  1U, 1U, 255U,
169  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_59_w.npy", weights_layout),
170  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_59_b.npy", weights_layout),
171  PadStrideInfo(1, 1, 0, 0))
172  .set_name("conv2d_59")
173  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, 1.f)).set_name("conv2d_59/Linear")
174  << YOLOLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC, 0.1f)).set_name("Yolo1")
175  << OutputLayer(get_output_accessor(common_params, 5));
176  route_1 << ConvolutionLayer(
177  1U, 1U, 256U,
178  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_60_w.npy", weights_layout),
179  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
180  PadStrideInfo(1, 1, 0, 0))
181  .set_name("conv2d_60")
183  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_59_mean.npy"),
184  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_59_var.npy"),
185  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_59_gamma.npy"),
186  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_59_beta.npy"),
187  0.000001f)
188  .set_name("conv2d_59/BatchNorm")
189  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_60/LeakyRelu")
191  SubStream concat_1(route_1);
192  concat_1 << ConcatLayer(std::move(route_1), std::move(intermediate_layers.second)).set_name("Route1")
193  << ConvolutionLayer(
194  1U, 1U, 256U,
195  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_61_w.npy", weights_layout),
196  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
197  PadStrideInfo(1, 1, 0, 0))
198  .set_name("conv2d_61")
200  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_60_mean.npy"),
201  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_60_var.npy"),
202  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_60_gamma.npy"),
203  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_60_beta.npy"),
204  0.000001f)
205  .set_name("conv2d_60/BatchNorm")
206  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_61/LeakyRelu")
207  << ConvolutionLayer(
208  3U, 3U, 512U,
209  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_62_w.npy", weights_layout),
210  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
211  PadStrideInfo(1, 1, 1, 1))
212  .set_name("conv2d_62")
214  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_61_mean.npy"),
215  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_61_var.npy"),
216  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_61_gamma.npy"),
217  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_61_beta.npy"),
218  0.000001f)
219  .set_name("conv2d_61/BatchNorm")
220  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_62/LeakyRelu")
221  << ConvolutionLayer(
222  1U, 1U, 256U,
223  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_63_w.npy", weights_layout),
224  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
225  PadStrideInfo(1, 1, 0, 0))
226  .set_name("conv2d_63")
228  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_62_mean.npy"),
229  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_62_var.npy"),
230  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_62_gamma.npy"),
231  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_62_beta.npy"),
232  0.000001f)
233  .set_name("conv2d_62/BatchNorm")
234  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_63/LeakyRelu")
235  << ConvolutionLayer(
236  3U, 3U, 512U,
237  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_64_w.npy", weights_layout),
238  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
239  PadStrideInfo(1, 1, 1, 1))
240  .set_name("conv2d_64")
242  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_63_mean.npy"),
243  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_63_var.npy"),
244  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_63_gamma.npy"),
245  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_63_beta.npy"),
246  0.000001f)
247  .set_name("conv2d_63/BatchNorm")
248  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_64/LeakyRelu")
249  << ConvolutionLayer(
250  1U, 1U, 256U,
251  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_65_w.npy", weights_layout),
252  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
253  PadStrideInfo(1, 1, 0, 0))
254  .set_name("conv2d_65")
256  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_64_mean.npy"),
257  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_64_var.npy"),
258  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_64_gamma.npy"),
259  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_64_beta.npy"),
260  0.000001f)
261  .set_name("conv2d_65/BatchNorm")
262  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_65/LeakyRelu");
263  SubStream route_2(concat_1);
264  concat_1 << ConvolutionLayer(
265  3U, 3U, 512U,
266  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_66_w.npy", weights_layout),
267  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
268  PadStrideInfo(1, 1, 1, 1))
269  .set_name("conv2d_66")
271  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_65_mean.npy"),
272  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_65_var.npy"),
273  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_65_gamma.npy"),
274  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_65_beta.npy"),
275  0.000001f)
276  .set_name("conv2d_65/BatchNorm")
277  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_66/LeakyRelu")
278  << ConvolutionLayer(
279  1U, 1U, 255U,
280  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_67_w.npy", weights_layout),
281  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_67_b.npy", weights_layout),
282  PadStrideInfo(1, 1, 0, 0))
283  .set_name("conv2d_67")
284  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, 1.f)).set_name("conv2d_67/Linear")
285  << YOLOLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC, 0.1f)).set_name("Yolo2")
286  << OutputLayer(get_output_accessor(common_params, 5));
287  route_2 << ConvolutionLayer(
288  1U, 1U, 128U,
289  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_68_w.npy", weights_layout),
290  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
291  PadStrideInfo(1, 1, 0, 0))
292  .set_name("conv2d_68")
294  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_66_mean.npy"),
295  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_66_var.npy"),
296  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_66_gamma.npy"),
297  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_66_beta.npy"),
298  0.000001f)
299  .set_name("conv2d_66/BatchNorm")
300  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_68/LeakyRelu")
302  SubStream concat_2(route_2);
303  concat_2 << ConcatLayer(std::move(route_2), std::move(intermediate_layers.first)).set_name("Route2")
304  << ConvolutionLayer(
305  1U, 1U, 128U,
306  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_69_w.npy", weights_layout),
307  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
308  PadStrideInfo(1, 1, 0, 0))
309  .set_name("conv2d_69")
311  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_67_mean.npy"),
312  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_67_var.npy"),
313  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_67_gamma.npy"),
314  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_67_beta.npy"),
315  0.000001f)
316  .set_name("conv2d_67/BatchNorm")
317  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_69/LeakyRelu")
318  << ConvolutionLayer(
319  3U, 3U, 256U,
320  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_70_w.npy", weights_layout),
321  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
322  PadStrideInfo(1, 1, 1, 1))
323  .set_name("conv2d_70")
325  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_68_mean.npy"),
326  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_68_var.npy"),
327  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_68_gamma.npy"),
328  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_68_beta.npy"),
329  0.000001f)
330  .set_name("conv2d_68/BatchNorm")
331  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_70/LeakyRelu")
332  << ConvolutionLayer(
333  1U, 1U, 128U,
334  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_71_w.npy", weights_layout),
335  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
336  PadStrideInfo(1, 1, 0, 0))
337  .set_name("conv2d_71")
339  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_69_mean.npy"),
340  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_69_var.npy"),
341  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_69_gamma.npy"),
342  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_69_beta.npy"),
343  0.000001f)
344  .set_name("conv2d_69/BatchNorm")
345  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_71/LeakyRelu")
346  << ConvolutionLayer(
347  3U, 3U, 256U,
348  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_72_w.npy", weights_layout),
349  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
350  PadStrideInfo(1, 1, 1, 1))
351  .set_name("conv2d_72")
353  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_70_mean.npy"),
354  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_70_var.npy"),
355  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_70_gamma.npy"),
356  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_70_beta.npy"),
357  0.000001f)
358  .set_name("conv2d_70/BatchNorm")
359  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_72/LeakyRelu")
360  << ConvolutionLayer(
361  1U, 1U, 128U,
362  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_73_w.npy", weights_layout),
363  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
364  PadStrideInfo(1, 1, 0, 0))
365  .set_name("conv2d_73")
367  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_71_mean.npy"),
368  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_71_var.npy"),
369  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_71_gamma.npy"),
370  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_71_beta.npy"),
371  0.000001f)
372  .set_name("conv2d_71/BatchNorm")
373  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_73/LeakyRelu")
374  << ConvolutionLayer(
375  3U, 3U, 256U,
376  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_74_w.npy", weights_layout),
377  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
378  PadStrideInfo(1, 1, 1, 1))
379  .set_name("conv2d_74")
381  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_72_mean.npy"),
382  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_72_var.npy"),
383  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_72_gamma.npy"),
384  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_72_beta.npy"),
385  0.000001f)
386  .set_name("conv2d_72/BatchNorm")
387  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_74/LeakyRelu")
388  << ConvolutionLayer(
389  1U, 1U, 255U,
390  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_75_w.npy", weights_layout),
391  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_75_b.npy", weights_layout),
392  PadStrideInfo(1, 1, 0, 0))
393  .set_name("conv2d_75")
394  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR, 1.f)).set_name("conv2d_75/Linear")
395  << YOLOLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LOGISTIC, 0.1f)).set_name("Yolo3")
396  << OutputLayer(get_output_accessor(common_params, 5));
397 
398  // Finalize graph
399  GraphConfig config;
400  config.num_threads = common_params.threads;
401  config.use_tuner = common_params.enable_tuner;
402  config.tuner_mode = common_params.tuner_mode;
403  config.tuner_file = common_params.tuner_file;
404  config.mlgo_file = common_params.mlgo_file;
405 
406  graph.finalize(common_params.target, config);
407 
408  return true;
409  }
410  void do_run() override
411  {
412  // Run graph
413  graph.run();
414  }
415 
416 private:
417  CommandLineParser cmd_parser;
418  CommonGraphOptions common_opts;
419  CommonGraphParams common_params;
420  Stream graph;
421 
422  std::pair<SubStream, SubStream> darknet53(const std::string &data_path, DataLayout weights_layout)
423  {
424  graph << ConvolutionLayer(
425  3U, 3U, 32U,
426  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_1_w.npy", weights_layout),
427  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
428  PadStrideInfo(1, 1, 1, 1))
429  .set_name("conv2d_1/Conv2D")
431  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_1_mean.npy"),
432  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_1_var.npy"),
433  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_1_gamma.npy"),
434  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_1_beta.npy"),
435  0.000001f)
436  .set_name("conv2d_1/BatchNorm")
437  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_1/LeakyRelu")
438  << ConvolutionLayer(
439  3U, 3U, 64U,
440  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_2_w.npy", weights_layout),
441  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
442  PadStrideInfo(2, 2, 1, 1))
443  .set_name("conv2d_2/Conv2D")
445  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_2_mean.npy"),
446  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_2_var.npy"),
447  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_2_gamma.npy"),
448  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_2_beta.npy"),
449  0.000001f)
450  .set_name("conv2d_2/BatchNorm")
451  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_2/LeakyRelu");
452  darknet53_block(data_path, "3", weights_layout, 32U);
453  graph << ConvolutionLayer(
454  3U, 3U, 128U,
455  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_5_w.npy", weights_layout),
456  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
457  PadStrideInfo(2, 2, 1, 1))
458  .set_name("conv2d_5/Conv2D")
460  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_5_mean.npy"),
461  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_5_var.npy"),
462  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_5_gamma.npy"),
463  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_5_beta.npy"),
464  0.000001f)
465  .set_name("conv2d_5/BatchNorm")
466  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_5/LeakyRelu");
467  darknet53_block(data_path, "6", weights_layout, 64U);
468  darknet53_block(data_path, "8", weights_layout, 64U);
469  graph << ConvolutionLayer(
470  3U, 3U, 256U,
471  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_10_w.npy", weights_layout),
472  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
473  PadStrideInfo(2, 2, 1, 1))
474  .set_name("conv2d_10/Conv2D")
476  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_10_mean.npy"),
477  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_10_var.npy"),
478  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_10_gamma.npy"),
479  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_10_beta.npy"),
480  0.000001f)
481  .set_name("conv2d_10/BatchNorm")
482  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_10/LeakyRelu");
483  darknet53_block(data_path, "11", weights_layout, 128U);
484  darknet53_block(data_path, "13", weights_layout, 128U);
485  darknet53_block(data_path, "15", weights_layout, 128U);
486  darknet53_block(data_path, "17", weights_layout, 128U);
487  darknet53_block(data_path, "19", weights_layout, 128U);
488  darknet53_block(data_path, "21", weights_layout, 128U);
489  darknet53_block(data_path, "23", weights_layout, 128U);
490  darknet53_block(data_path, "25", weights_layout, 128U);
491  SubStream layer_36(graph);
492  graph << ConvolutionLayer(
493  3U, 3U, 512U,
494  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_27_w.npy", weights_layout),
495  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
496  PadStrideInfo(2, 2, 1, 1))
497  .set_name("conv2d_27/Conv2D")
499  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_27_mean.npy"),
500  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_27_var.npy"),
501  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_27_gamma.npy"),
502  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_27_beta.npy"),
503  0.000001f)
504  .set_name("conv2d_27/BatchNorm")
505  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_27/LeakyRelu");
506  darknet53_block(data_path, "28", weights_layout, 256U);
507  darknet53_block(data_path, "30", weights_layout, 256U);
508  darknet53_block(data_path, "32", weights_layout, 256U);
509  darknet53_block(data_path, "34", weights_layout, 256U);
510  darknet53_block(data_path, "36", weights_layout, 256U);
511  darknet53_block(data_path, "38", weights_layout, 256U);
512  darknet53_block(data_path, "40", weights_layout, 256U);
513  darknet53_block(data_path, "42", weights_layout, 256U);
514  SubStream layer_61(graph);
515  graph << ConvolutionLayer(
516  3U, 3U, 1024U,
517  get_weights_accessor(data_path, "/cnn_data/yolov3_model/conv2d_44_w.npy", weights_layout),
518  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
519  PadStrideInfo(2, 2, 1, 1))
520  .set_name("conv2d_44/Conv2D")
522  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_44_mean.npy"),
523  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_44_var.npy"),
524  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_44_gamma.npy"),
525  get_weights_accessor(data_path, "/cnn_data/yolov3_model/batch_normalization_44_beta.npy"),
526  0.000001f)
527  .set_name("conv2d_44/BatchNorm")
528  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_44/LeakyRelu");
529  darknet53_block(data_path, "45", weights_layout, 512U);
530  darknet53_block(data_path, "47", weights_layout, 512U);
531  darknet53_block(data_path, "49", weights_layout, 512U);
532  darknet53_block(data_path, "51", weights_layout, 512U);
533 
534  return std::pair<SubStream, SubStream>(layer_36, layer_61);
535  }
536 
537  void darknet53_block(const std::string &data_path, std::string &&param_path, DataLayout weights_layout,
538  unsigned int filter_size)
539  {
540  std::string total_path = "/cnn_data/yolov3_model/";
541  std::string param_path2 = arm_compute::support::cpp11::to_string(arm_compute::support::cpp11::stoi(param_path) + 1);
542  SubStream i_a(graph);
543  SubStream i_b(graph);
544  i_a << ConvolutionLayer(
545  1U, 1U, filter_size,
546  get_weights_accessor(data_path, total_path + "conv2d_" + param_path + "_w.npy", weights_layout),
547  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
548  PadStrideInfo(1, 1, 0, 0))
549  .set_name("conv2d_" + param_path + "/Conv2D")
551  get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path + "_mean.npy"),
552  get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path + "_var.npy"),
553  get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path + "_gamma.npy"),
554  get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path + "_beta.npy"),
555  0.000001f)
556  .set_name("conv2d_" + param_path + "/BatchNorm")
557  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_" + param_path + "/LeakyRelu")
558  << ConvolutionLayer(
559  3U, 3U, filter_size * 2,
560  get_weights_accessor(data_path, total_path + "conv2d_" + param_path2 + "_w.npy", weights_layout),
561  std::unique_ptr<arm_compute::graph::ITensorAccessor>(nullptr),
562  PadStrideInfo(1, 1, 1, 1))
563  .set_name("conv2d_" + param_path2 + "/Conv2D")
565  get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path2 + "_mean.npy"),
566  get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path2 + "_var.npy"),
567  get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path2 + "_gamma.npy"),
568  get_weights_accessor(data_path, total_path + "batch_normalization_" + param_path2 + "_beta.npy"),
569  0.000001f)
570  .set_name("conv2d_" + param_path2 + "/BatchNorm")
571  << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LEAKY_RELU, 0.1f)).set_name("conv2d_" + param_path2 + "/LeakyRelu");
572 
573  graph << EltwiseLayer(std::move(i_a), std::move(i_b), EltwiseOperation::Add).set_name("").set_name("add_" + param_path + "_" + param_path2);
574  }
575 };
576 
577 /** Main program for YOLOv3
578  *
579  * Model is based on:
580  * https://arxiv.org/abs/1804.02767
581  * "YOLOv3: An Incremental Improvement"
582  * Joseph Redmon, Ali Farhadi
583  *
584  * @note To list all the possible arguments execute the binary appended with the --help option
585  *
586  * @param[in] argc Number of arguments
587  * @param[in] argv Arguments
588  *
589  * @return Return code
590  */
591 int main(int argc, char **argv)
592 {
593  return arm_compute::utils::run_example<GraphYOLOv3Example>(argc, argv);
594 }
Graph configuration structure Device target types.
Definition: Types.h:80
CLTunerMode tuner_mode
Tuner mode to be used by the CL tuner.
Definition: Types.h:87
std::unique_ptr< graph::ITensorAccessor > get_input_accessor(const arm_compute::utils::CommonGraphParams &graph_parameters, std::unique_ptr< IPreprocessor > preprocessor=nullptr, bool bgr=true)
Generates appropriate input accessor according to the specified graph parameters. ...
Definition: GraphUtils.h:497
std::string to_string(T &&value)
Convert integer and float values to string.
void consume_common_graph_parameters(CommonGraphValidateOptions &options, CommonParams &common_params)
Consumes the consume_common_graph_parameters graph options and creates a structure containing any inf...
Includes all the Graph headers at once.
Common command line options used to configure the graph examples.
Output values are defined to match the source pixel whose center is nearest to the sample position...
Class to parse command line arguments.
std::string mlgo_file
Filename to load MLGO heuristics from.
Definition: Types.h:90
std::string tuner_file
File to load/store tuning values from.
Definition: Types.h:89
#define ARM_COMPUTE_EXIT_ON_MSG(cond, msg)
If the condition is true, the given message is printed and program exits.
Definition: Error.h:379
Abstract Example class.
Definition: Utils.h:78
int stoi(const std::string &str, std::size_t *pos=0, NumericBase base=NumericBase::BASE_10)
Convert string values to integer.
Definition: StringSupport.h:55
Num samples, channels, height, width.
TensorShape permute_shape(TensorShape tensor_shape, DataLayout in_data_layout, DataLayout out_data_layout)
Permutes a given tensor shape given the input and output data layout.
Definition: GraphUtils.h:664
bool is_data_type_quantized_asymmetric(DataType dt)
Check if a given data type is of asymmetric quantized type.
Definition: Utils.h:1190
TensorDescriptor & set_layout(DataLayout data_layout)
Sets tensor descriptor data layout.
Structure holding all the common graph parameters.
std::unique_ptr< graph::ITensorAccessor > get_output_accessor(const arm_compute::utils::CommonGraphParams &graph_parameters, size_t top_n=5, bool is_validation=false, std::ostream &output_stream=std::cout)
Generates appropriate output accessor according to the specified graph parameters.
Definition: GraphUtils.h:543
bool use_tuner
Use a tuner in tunable backends.
Definition: Types.h:85
std::unique_ptr< graph::ITensorAccessor > get_weights_accessor(const std::string &path, const std::string &data_file, DataLayout file_layout=DataLayout::NCHW)
Generates appropriate weights accessor according to the specified path.
Definition: GraphUtils.h:475
int num_threads
Number of threads to use (thread capable backends), if 0 the backend will auto-initialize, if -1 the backend will stay as it is.
Definition: Types.h:88
int main(int argc, char **argv)
Main program for YOLOv3.
Stream frontend class to construct simple graphs in a stream fashion.
Definition: Stream.h:45
DataLayout
[DataLayout enum definition]
Definition: Types.h:120
ILayer & set_name(std::string name)
Sets the name of the layer.
Definition: ILayer.h:55