JeVois  1.22
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Loading...
Searching...
No Matches
Network.H
Go to the documentation of this file.
1// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2//
3// JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2021 by Laurent Itti, the University of Southern
4// California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5//
6// This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7// redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8// Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10// License for more details. You should have received a copy of the GNU General Public License along with this program;
11// if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12//
13// Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14// Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16/*! \file */
17
18#pragma once
19
21#include <jevois/Types/Enum.H>
22
23#include <ovxlib/vsi_nn_pub.h> // for data types and quantization types
24
25#include <opencv2/core/core.hpp>
26#include <vector>
27
28namespace jevois
29{
30 namespace dnn
31 {
32 namespace network
33 {
34 // We define all parameters for all derived classes here to avoid duplicate definitions. Different derived classes
35 // will use different subsets of all available parameters:
36 static jevois::ParameterCategory const ParamCateg("DNN Network Options");
37
38 //! Parameter \relates jevois::dnn::Network
39 JEVOIS_DECLARE_PARAMETER(comment, std::string, "Optional comment about the network",
40 "", ParamCateg);
41
42 //! Parameter \relates jevois::dnn::Network
43 JEVOIS_DECLARE_PARAMETER(url, std::string, "Optional URL for the network",
44 "", ParamCateg);
45
46 //! Parameter \relates jevois::dnn::Network
47 JEVOIS_DECLARE_PARAMETER(dataroot, std::string, "Root directory to use when config or model parameters "
48 "are relative paths.",
49 JEVOIS_SHARE_PATH, ParamCateg);
50
51 //! Parameter \relates jevois::dnn::Network
52 JEVOIS_DECLARE_PARAMETER(config, std::string, "Path to a text file that contains network configuration. "
53 "Can have extension .prototxt (Caffe), .pbtxt (TensorFlow), or .cfg (Darknet). "
54 "If path is relative, it will be prefixed by dataroot.",
55 "", ParamCateg);
56
57 //! Parameter \relates jevois::dnn::Network
58 JEVOIS_DECLARE_PARAMETER(model, std::string, "Path to a binary file of model contains trained weights. "
59 "Can have extension .caffemodel (Caffe), .pb (TensorFlow), .t7 or .net (Torch), "
60 ".tflite (TensorFlow Lite), or .weights (Darknet). If path is relative, it will be "
61 "prefixed by dataroot.",
62 "", ParamCateg);
63#ifdef JEVOIS_PRO
64 //! Parameter \relates jevois::dnn::NetworkNPU
65 JEVOIS_DECLARE_PARAMETER(library, std::string, "Optional path to a compiled .so library that can load and "
66 "instantiate a NPU model. If a library is provided, then intensors and outtensors "
67 "can be left empty, otherwise they have to describe exactly the inputs and outputs "
68 "of the NPU model. This library is obtained along with the NPU .nb model when "
69 "converting for NPU using the KSNN convert tool. If path is relative, it will be "
70 "prefixed by dataroot.",
71 "", ParamCateg);
72#endif
73
74#ifdef JEVOIS_PRO
75 //! Enum \relates jevois::dnn::Network
76 JEVOIS_DEFINE_ENUM_CLASS(Target, (CPU) (OpenCL) (OpenCL_FP16) (Myriad) (NPU) );
77#else
78 //! Enum \relates jevois::dnn::Network
79 JEVOIS_DEFINE_ENUM_CLASS(Target, (CPU) );
80#endif
81
82 //! Parameter \relates jevois::dnn::Network
83 JEVOIS_DECLARE_PARAMETER(target, Target, "OpenCV compute target to use. Changes will take effect "
84 "next time you load a different model.",
85 Target::CPU, Target_Values, ParamCateg);
86#ifdef JEVOIS_PRO
87 //! Enum \relates jevois::dnn::Network
88 JEVOIS_DEFINE_ENUM_CLASS(Backend, (OpenCV) (InferenceEngine) (TimVX) );
89#define JEVOIS_BACKEND_DEFAULT Backend::OpenCV
90#else
91 //! Enum \relates jevois::dnn::Network
92 JEVOIS_DEFINE_ENUM_CLASS(Backend, (Default) );
93#define JEVOIS_BACKEND_DEFAULT Backend::Default
94#endif
95
96 //! Parameter \relates jevois::dnn::Network
97 JEVOIS_DECLARE_PARAMETER(backend, Backend, "OpenCV compute backend to use. Default will use the inference "
98 "engine if available, otherwise OpenCV (note that inference engine only works on Intel "
99 "processors or MyriadX hardware, thus you should normally select OpenCV when running "
100 "on JeVois-Pro Platform, unless you want to use an optional MyriadX accelerator). "
101 "Changes will take effect next time you load a model.",
102 JEVOIS_BACKEND_DEFAULT, Backend_Values, ParamCateg);
103
104 //! Parameter \relates jevois::dnn::Network
105 JEVOIS_DECLARE_PARAMETER(intensors, std::string, "Specification of input tensors",
106 "", ParamCateg);
107
108 //! Parameter \relates jevois::dnn::Network
109 JEVOIS_DECLARE_PARAMETER(extraintensors, std::string, "Specification of extra fixed input tensors that will be "
110 "added after the regular intensors. Format is: "
111 "<type>:<shape>:val1 val2 ... valN, <type>:<shape>:val1 ... valN. For example, for "
112 "URetinex-Net: 32F:1x1x1:3.0",
113 "", ParamCateg);
114
115 //! Parameter \relates jevois::dnn::Network
116 JEVOIS_DECLARE_PARAMETER(outtensors, std::string, "Specification of output tensors",
117 "", ParamCateg);
118
119 //! Parameter \relates jevois::dnn::Network
120 JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(outtransform, std::string, "Specification of a sequence of operations "
121 "(reshape, transpose, split, merge, etc) to be applied to the output "
122 "tensors. Useful to match a particular network's outputs to the "
123 "tensor shapes expected by a particular post-processor. The sequence of "
124 "operations is separated by semicolons, and applied from left to right. "
125 "Operations specified here are applied after any de-quantization.",
126 "", ParamCateg);
127 //"Specification of reshaped output tensors; "
128 //"sometimes useful to re-interpret tensors to what a post-processor expects; for "
129 //"example, TPU YoloV4-Int-VOC outputs 5D tensors 32F:1x52x52x3x85, 32F:1x26x26x3x85, "
130 //"32F:1x13x13x3x85 but the YOLO post-processor expects 4D, which would be specified here "
131 //"as 32F:1x52x52x255, 32F:1x26x26x255, 32F:1x13x13x255. Note that this only changes "
132 //"the description of dimensions, but does not move any pixel data around (e.g., cannot "
133 //"convert from NCHW to NHWC, convert data types, etc). Use sparingly and with caution.",
134
135 //! Parameter \relates jevois::dnn::Network
136 JEVOIS_DECLARE_PARAMETER(dequant, bool, "Dequantize output tensors to float32 from their native quantized type",
137 true, ParamCateg);
138
139 //! Parameter \relates jevois::dnn::NetworkPython
140 JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(pynet, std::string, "Full path of the python network processor file. "
141 "Name of class defined in the file must match the file name without "
142 "the trailing '.py'",
143 "", ParamCateg);
144#ifdef JEVOIS_PRO
145 //! Parameter \relates jevois::dnn::Network
146 JEVOIS_DECLARE_PARAMETER(tpunum, size_t, "Coral EdgeTPU number to use to run this model, typically 0, or can be "
147 "1 when using a dual-TPU add-on board, or more when using additional TPUs connected "
148 "to USB ports",
149 0, ParamCateg);
150
151 //! Parameter \relates jevois::dnn::Network
152 JEVOIS_DECLARE_PARAMETER(spunum, size_t, "Hailo8 device number to use to run this model, typically 0 unless "
153 "several Hailo8 accelerators are connected to the system",
154 0, ParamCateg);
155
156 //! Parameter \relates jevois::dnn::NetworkNPU
157 JEVOIS_DECLARE_PARAMETER(verifygraph, bool, "Verify NPU graph after loading it",
158 true, ParamCateg);
159
160 //! Parameter \relates jevois::dnn::NetworkNPU
161 JEVOIS_DECLARE_PARAMETER(ovxver, std::string, "ovxlib version to use with NPU network, or leave blank "
162 "to use latest version",
163 "", boost::regex("^$|^[0-9]+\\.[0-9]+\\.[0-9]+$"), ParamCateg);
164
165 //! Parameter \relates jevois::dnn::NetworkHailo
166 JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(turbo, bool, "Turbo mode. Has no significant effect on small or "
167 "fast networks. Use with caution as it may lead to overheating, not "
168 "recommended for production",
169 false, ParamCateg);
170#endif
171 }
172
173 //! Abstract class to represent a neural network
174 /*! Derived classes provide implementation via OpenCV (on CPU, OpenCL, or OpenVino/Myriad-X), Amlogic/Vivante NPU,
175 Hailo-8, Python, or Google Coral TPU.
176
177 The Network class can apply optional transforms to the output tensors:
178
179 - `dequant`: dequantize the output tensors
180
181 - `outtransform`: apply a semicolon-separated sequence (from left to right) of transforms to the
182 outputs. Outputs are numbered starting at 0. Available transforms are:
183
184 + `shape(outnum, AxBxC...)` to reshape an output to a given new shape. Does not change or move any tensor
185 data. Total number of data elements must remain the same. Useful to squeeze/unsqueeze tensors.
186
187 + `transpose(outnum, oldaxisA, oldaxisB, ...)` where transposed new axis 0 (the outermost dimension, typically
188 batch size) will be from oldaxisA, new axis 1 from oldaxisB, etc. If outnum is *, transpose all outputs.
189
190 + `order(oldidx0, oldidx1, ...)` where the new ordering of the output tensors will be: new tensor 0: old
191 tensor oldidx0 (which is zero-based); new tensor 1: old tensor oldidx1, etc. It is ok to have duplicated or
192 missing entries.
193
194 + `split(outnum, axis, newsize1, ..., newsizeN)` where axis 0 is the outtermost dimension (typically, batch
195 size), and newsize1 + ... + newsizeN must be equal to the original size of that axis. If outnum is *, split
196 all outputs.
197
198 + `merge(axis, outnum1, ..., outnumN)` where axis 0 is the outermost dimension (typically, batch size) and
199 outnum1, ..., outnumN are the outputs to merge along that axis. All the outputs to be merged must have
200 matching number of dimensions, and matching sizes on all other axes. The merged tensor will replace the
201 first output listed in the merge, and the other listed will be removed. Outputs to merge must be listed in
202 ascending order (use an order() transform first if needed)
203
204 See the model zoo files in /jevoispro/share/dnn/ for examples. For instance:
205 \code{.py}
206 outtransform: "split(*,1,80,64); order(1,0,3,2,5,4); transpose(*,0,2,3,1)"
207 \endcode
208
209 \ingroup dnn */
210 class Network : public Component,
211 public Parameter<network::comment, network::url, network::outtransform, network::extraintensors>
212 {
213 public:
214 //! Inherited constructor ok
216
217 //! Destructor
218 /*! CAUTION: derived classes must call waitBeforeDestroy() in their destructor */
219 virtual ~Network();
220
221 //! If network is currently loading, wait until that is done before destroying
222 /*! CAUTION: derived classes must call waitBeforeDestroy() in their destructor */
223 void waitBeforeDestroy();
224
225 //! Returns true when network is ready to run (loaded and initialized)
226 bool ready();
227
228 //! Get shapes of all input tensors
229 virtual std::vector<vsi_nn_tensor_attr_t> inputShapes() = 0;
230
231 //! Get shapes of all output tensors
232 virtual std::vector<vsi_nn_tensor_attr_t> outputShapes() = 0;
233
234 //! Process input blobs and obtain output blobs
235 /*! Network implementations may push information data into the info string, which will be displayed to
236 user. Convention is: if an info line starts with '* ', it is a header, and if it starts with '- ' it is a
237 bullet. Info should always be organized into headers at the top level. */
238 std::vector<cv::Mat> process(std::vector<cv::Mat> const & blobs, std::vector<std::string> & info);
239
240 //! Freeze/unfreeze parameters that users should not change while running
241 /*! Note: derived classes can freeze their own params by overriding this function, and should remember to still
242 call the base class jevois::dnn::Network::freeze(doit) */
243 virtual void freeze(bool doit);
244
245 protected:
246 //! Load from disk
247 virtual void load() = 0;
248
249 //! Process input blobs and obtain output blobs
250 virtual std::vector<cv::Mat> doprocess(std::vector<cv::Mat> const & blobs,
251 std::vector<std::string> & info) = 0;
252
253 void onParamChange(network::outtransform const & param, std::string const & val) override;
254
255 private:
256 std::atomic<bool> itsLoading = false;
257 std::atomic<bool> itsLoaded = false;
258 std::future<void> itsLoadFut;
259
260 // Output transformations:
261 enum class Operator { Shape, Transpose, Order, Split, Merge };
262 struct Oper
263 {
264 Operator op;
265 std::vector<size_t> tnum; // output tensor numbers (indices within the output array)
266 std::vector<int> newvals; // New values (operator-dependent: could be new output orders, new tensor dims)
267 };
268 std::vector<Oper> itsOps;
269 };
270
271 } // namespace dnn
272} // namespace jevois
#define JEVOIS_SHARE_PATH
Base path for shared files (e.g., neural network weights, etc)
Definition Config.H:82
#define JEVOIS_BACKEND_DEFAULT
Definition Network.H:89
A component of a model hierarchy.
Definition Component.H:182
friend class Component
Allow Component and DynamicParameter to access our registry data, everyone else is locked out.
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(turbo, bool, "Turbo mode. Has no significant effect on small or " "fast networks. Use with caution as it may lead to overheating, not " "recommended for production", false, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(verifygraph, bool, "Verify NPU graph after loading it", true, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(ovxver, std::string, "ovxlib version to use with NPU network, or leave blank " "to use latest version", "", boost::regex("^$|^[0-9]+\\.[0-9]+\\.[0-9]+$"), ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(library, std::string, "Optional path to a compiled .so library that can load and " "instantiate a NPU model. If a library is provided, then intensors and outtensors " "can be left empty, otherwise they have to describe exactly the inputs and outputs " "of the NPU model. This library is obtained along with the NPU .nb model when " "converting for NPU using the KSNN convert tool. If path is relative, it will be " "prefixed by dataroot.", "", ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(pynet, std::string, "Full path of the python network processor file. " "Name of class defined in the file must match the file name without " "the trailing '.py'", "", ParamCateg)
Parameter.
Abstract class to represent a neural network.
Definition Network.H:212
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(outtransform, std::string, "Specification of a sequence of operations " "(reshape, transpose, split, merge, etc) to be applied to the output " "tensors. Useful to match a particular network's outputs to the " "tensor shapes expected by a particular post-processor. The sequence of " "operations is separated by semicolons, and applied from left to right. " "Operations specified here are applied after any de-quantization.", "", ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(url, std::string, "Optional URL for the network", "", ParamCateg)
Parameter.
virtual void load()=0
Load from disk.
bool ready()
Returns true when network is ready to run (loaded and initialized)
Definition Network.C:165
JEVOIS_DECLARE_PARAMETER(dequant, bool, "Dequantize output tensors to float32 from their native quantized type", true, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(spunum, size_t, "Hailo8 device number to use to run this model, typically 0 unless " "several Hailo8 accelerators are connected to the system", 0, ParamCateg)
Parameter.
std::vector< cv::Mat > process(std::vector< cv::Mat > const &blobs, std::vector< std::string > &info)
Process input blobs and obtain output blobs.
Definition Network.C:201
JEVOIS_DECLARE_PARAMETER(config, std::string, "Path to a text file that contains network configuration. " "Can have extension .prototxt (Caffe), .pbtxt (TensorFlow), or .cfg (Darknet). " "If path is relative, it will be prefixed by dataroot.", "", ParamCateg)
Parameter.
void onParamChange(network::outtransform const &param, std::string const &val) override
Definition Network.C:40
JEVOIS_DECLARE_PARAMETER(intensors, std::string, "Specification of input tensors", "", ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(target, Target, "OpenCV compute target to use. Changes will take effect " "next time you load a different model.", Target::CPU, Target_Values, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(model, std::string, "Path to a binary file of model contains trained weights. " "Can have extension .caffemodel (Caffe), .pb (TensorFlow), .t7 or .net (Torch), " ".tflite (TensorFlow Lite), or .weights (Darknet). If path is relative, it will be " "prefixed by dataroot.", "", ParamCateg)
Parameter.
void waitBeforeDestroy()
If network is currently loading, wait until that is done before destroying.
Definition Network.C:152
JEVOIS_DECLARE_PARAMETER(backend, Backend, "OpenCV compute backend to use. Default will use the inference " "engine if available, otherwise OpenCV (note that inference engine only works on Intel " "processors or MyriadX hardware, thus you should normally select OpenCV when running " "on JeVois-Pro Platform, unless you want to use an optional MyriadX accelerator). " "Changes will take effect next time you load a model.", JEVOIS_BACKEND_DEFAULT, Backend_Values, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(outtensors, std::string, "Specification of output tensors", "", ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(tpunum, size_t, "Coral EdgeTPU number to use to run this model, typically 0, or can be " "1 when using a dual-TPU add-on board, or more when using additional TPUs connected " "to USB ports", 0, ParamCateg)
Parameter.
virtual std::vector< vsi_nn_tensor_attr_t > outputShapes()=0
Get shapes of all output tensors.
virtual std::vector< vsi_nn_tensor_attr_t > inputShapes()=0
Get shapes of all input tensors.
JEVOIS_DECLARE_PARAMETER(extraintensors, std::string, "Specification of extra fixed input tensors that will be " "added after the regular intensors. Format is: " "<type>:<shape>:val1 val2 ... valN, <type>:<shape>:val1 ... valN. For example, for " "URetinex-Net: 32F:1x1x1:3.0", "", ParamCateg)
Parameter.
virtual std::vector< cv::Mat > doprocess(std::vector< cv::Mat > const &blobs, std::vector< std::string > &info)=0
Process input blobs and obtain output blobs.
JEVOIS_DECLARE_PARAMETER(comment, std::string, "Optional comment about the network", "", ParamCateg)
Parameter.
virtual ~Network()
Destructor.
Definition Network.C:28
JEVOIS_DEFINE_ENUM_CLASS(Target,(CPU)(OpenCL)(OpenCL_FP16)(Myriad)(NPU))
Enum.
JEVOIS_DEFINE_ENUM_CLASS(Backend,(OpenCV)(InferenceEngine)(TimVX))
Enum.
virtual void freeze(bool doit)
Freeze/unfreeze parameters that users should not change while running.
Definition Network.C:32
JEVOIS_DECLARE_PARAMETER(dataroot, std::string, "Root directory to use when config or model parameters " "are relative paths.", JEVOIS_SHARE_PATH, ParamCateg)
Parameter.
JEVOIS_DEFINE_ENUM_CLASS(CameraSensor,(any)(imx290)(os08a10)(ar0234))
Enum for different sensor models.
Main namespace for all JeVois classes and functions.
Definition Concepts.dox:2
A category to which multiple ParameterDef definitions can belong.