xref: /aosp_15_r20/external/ComputeLibrary/examples/graph_yolov3.cpp (revision c217d954acce2dbc11938adb493fc0abd69584f3)
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"
25 #include "support/ToolchainSupport.h"
26 #include "utils/CommonGraphOptions.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:
GraphYOLOv3Example()38     GraphYOLOv3Example()
39         : cmd_parser(), common_opts(cmd_parser), common_params(), graph(0, "YOLOv3")
40     {
41     }
42 
do_setup(int argc,char ** argv)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")
88               << BatchNormalizationLayer(
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")
96               << ConvolutionLayer(
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")
102               << BatchNormalizationLayer(
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")
116               << BatchNormalizationLayer(
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")
130               << BatchNormalizationLayer(
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")
144               << BatchNormalizationLayer(
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")
159               << BatchNormalizationLayer(
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")
182                 << BatchNormalizationLayer(
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")
190                 << ResizeLayer(InterpolationPolicy::NEAREST_NEIGHBOR, 2, 2).set_name("Upsample_60");
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")
199                  << BatchNormalizationLayer(
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")
213                  << BatchNormalizationLayer(
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")
227                  << BatchNormalizationLayer(
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")
241                  << BatchNormalizationLayer(
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")
255                  << BatchNormalizationLayer(
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")
270                  << BatchNormalizationLayer(
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")
293                 << BatchNormalizationLayer(
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")
301                 << ResizeLayer(InterpolationPolicy::NEAREST_NEIGHBOR, 2, 2).set_name("Upsample_68");
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")
310                  << BatchNormalizationLayer(
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")
324                  << BatchNormalizationLayer(
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")
338                  << BatchNormalizationLayer(
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")
352                  << BatchNormalizationLayer(
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")
366                  << BatchNormalizationLayer(
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")
380                  << BatchNormalizationLayer(
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     }
do_run()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 
darknet53(const std::string & data_path,DataLayout weights_layout)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")
430               << BatchNormalizationLayer(
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")
444               << BatchNormalizationLayer(
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")
459               << BatchNormalizationLayer(
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")
475               << BatchNormalizationLayer(
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")
498               << BatchNormalizationLayer(
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")
521               << BatchNormalizationLayer(
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 
darknet53_block(const std::string & data_path,std::string && param_path,DataLayout weights_layout,unsigned int filter_size)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")
550             << BatchNormalizationLayer(
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")
564             << BatchNormalizationLayer(
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  */
main(int argc,char ** argv)591 int main(int argc, char **argv)
592 {
593     return arm_compute::utils::run_example<GraphYOLOv3Example>(argc, argv);
594 }
595