Line data Source code
1 : // SPDX-License-Identifier: Apache-2.0
2 : /**
3 : * Copyright (C) 2020 Parichay Kapoor <pk.kapoor@samsung.com>
4 : *
5 : * @file model.h
6 : * @date 14 October 2020
7 : * @see https://github.com/nnstreamer/nntrainer
8 : * @author Jijoong Moon <jijoong.moon@samsung.com>
9 : * @author Parichay Kapoor <pk.kapoor@samsung.com>
10 : * @bug No known bugs except for NYI items
11 : * @brief This is model interface for c++ API
12 : *
13 : * @note This is experimental API and not stable.
14 : */
15 :
16 : #ifndef __ML_TRAIN_MODEL_H__
17 : #define __ML_TRAIN_MODEL_H__
18 :
19 : #if __cplusplus >= MIN_CPP_VERSION
20 :
21 : #include <string>
22 : #include <type_traits>
23 : #include <vector>
24 :
25 : #include <common.h>
26 :
27 : #include <dataset.h>
28 : #include <layer.h>
29 : #include <optimizer.h>
30 : #include <tensor_dim.h>
31 :
32 : namespace nntrainer {
33 : class RunLayerContext;
34 : }
35 : /** Define more aliases for the model in the API */
36 : namespace ml {
37 : namespace train {
38 :
39 : /**
40 : * @brief Statistics from running or training a model
41 : */
42 : struct RunStats {
43 : float accuracy; /** accuracy of the model */
44 : float loss; /** loss of the model */
45 : int num_iterations; /** number of iterations done on this stat */
46 : int max_epoch;
47 : int epoch_idx;
48 : unsigned int
49 : num_correct_predictions; /** number of right sample on this run */
50 :
51 : /**
52 : * @brief Initializer of RunStats
53 : */
54 836 : RunStats() :
55 836 : accuracy(0),
56 836 : loss(0),
57 836 : num_iterations(0),
58 836 : max_epoch(0),
59 836 : epoch_idx(0),
60 836 : num_correct_predictions(0) {}
61 : };
62 :
63 : /**
64 : * @brief Enumeration of Network Type
65 : */
66 : enum class ModelType {
67 : KNN, /** k Nearest Neighbor */
68 : NEURAL_NET, /** Neural Network */
69 : UNKNOWN /** Unknown */
70 : };
71 :
72 : /**
73 : * @brief Enumeration to state type of reference of layers
74 : */
75 : enum class ReferenceLayersType {
76 : BACKBONE, /** backbone */
77 : RECURRENT, /** recurrent */
78 : };
79 :
80 : /**
81 : * @brief Model saving options
82 : *
83 : */
84 : enum class ModelFormat {
85 : MODEL_FORMAT_BIN =
86 : ML_TRAIN_MODEL_FORMAT_BIN, /**< raw bin file saves model weights required
87 : for inference and training without any configurations*/
88 : MODEL_FORMAT_INI = ML_TRAIN_MODEL_FORMAT_INI, /**< ini file */
89 : MODEL_FORMAT_INI_WITH_BIN =
90 : ML_TRAIN_MODEL_FORMAT_INI_WITH_BIN, /**< ini file with save_path defined
91 : where the binary will be saved */
92 : MODEL_FORMAT_FLATBUFFER =
93 : ML_TRAIN_MODEL_FORMAT_FLATBUFFER, /**< flatbuffer file */
94 : MODEL_FORMAT_ONNX = ML_TRAIN_MODEL_FORMAT_ONNX, /**< ONNX file */
95 :
96 : MODEL_FORMAT_QNN = ML_TRAIN_MODEL_FORMAT_QNN /**< qnn binary file */
97 : };
98 :
99 : /**
100 : * @class Model Class
101 : * @brief Model Class containing configuration, layers, optimizer and dataset
102 : */
103 : class Model {
104 : public:
105 : /**
106 : * @brief Destructor of Model Class
107 : */
108 : virtual ~Model() = default;
109 :
110 : /**
111 : * @brief Create and load the Network with ini configuration file.
112 : * @param[in] config config file path
113 : * @retval #ML_ERROR_NONE Successful.
114 : * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
115 : */
116 : virtual int loadFromConfig(const std::string &config) = 0;
117 :
118 : /**
119 : * @brief Minimal set of properties that must be supported by the model
120 : * @details The minimal properties:
121 : - loss_type
122 : - batch_size
123 : - epochs
124 : - save_path
125 : - continue_train
126 : */
127 : /**
128 : * @brief set Property of Network
129 : * @param[in] values values of property
130 : * @retval #ML_ERROR_NONE Successful.
131 : * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
132 : * @details This function accepts vector of properties in the format -
133 : * { std::string property_name, void * property_val, ...}
134 : */
135 : virtual void setProperty(const std::vector<std::string> &values) = 0;
136 :
137 : /**
138 : * @brief Compile Network. This should be called before initialize
139 : * @retval #ML_ERROR_NONE Successful.
140 : * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
141 : */
142 : virtual int compile(ExecutionMode exec_mode_ = ExecutionMode::TRAIN) = 0;
143 :
144 : /**
145 : * @brief Initialize Network. This should be called after setting the
146 : * property and compiling.
147 : * @retval #ML_ERROR_NONE Successful.
148 : * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
149 : */
150 : virtual int initialize(ExecutionMode exec_mode_ = ExecutionMode::TRAIN) = 0;
151 :
152 : /**
153 : * @brief Reinitialize Network. This should be called after initialize
154 : * @retval #ML_ERROR_NONE Successful.
155 : * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
156 : */
157 : virtual int reinitialize() = 0;
158 :
159 : /**
160 : * @brief save model states and training parameters from a file
161 : * @param file_path file_path to save the model, if full path is not
162 : * given, it should be saved inside working directory
163 : * @param format format to save parameters
164 : */
165 : virtual void save(const std::string &file_path,
166 : ModelFormat format = ModelFormat::MODEL_FORMAT_BIN) = 0;
167 :
168 : /**
169 : * @brief load model with regard to the format
170 : * @param file_path file_path to save the model, if full path is not
171 : * given, it should be saved inside working directory
172 : * @param format format to save parameters
173 : */
174 : virtual void load(const std::string &file_path,
175 : ModelFormat format = ModelFormat::MODEL_FORMAT_BIN) = 0;
176 :
177 : /**
178 : * @brief Run Model training and validation
179 : * @param[in] values hyper parameters
180 : * @param[in] stop_cb callback function to decide stop training or not
181 : * ~~~~~
182 : * @a stop_user_data user_data to be used in stop_cb
183 : * @a bool true if stop the training
184 : * ~~~~~
185 : * @param[in] epoch_complete_cb Called the end of an epoch
186 : * ~~~~~
187 : * @a epoch_user_data user_data to be used in epoch_complete_cb
188 : * ~~~~~
189 : * @retval #ML_ERROR_NONE Successful.
190 : * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
191 : * @details This function accepts vector of properties in the format -
192 : * { std::string property_name, void * property_val, ...}
193 : */
194 : virtual int train(
195 : const std::vector<std::string> &values = {},
196 : std::function<bool(void *)> stop_cb =
197 : [](void *stop_user_data) { return false; },
198 : void *stop_user_data = nullptr,
199 : std::function<void(void *)> epoch_complete_cb =
200 : [](void *epoch_user_data) { return false; },
201 : void *epoch_user_data = nullptr) = 0;
202 :
203 : /**
204 : * @brief Run Model train with callback function by user
205 : * @param[in] mode mode of the dataset
206 : * @param[in] dataset set the dataset
207 : * @retval #ML_ERROR_NONE Successful.
208 : * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
209 : */
210 : virtual int setDataset(const ml::train::DatasetModeType &mode,
211 : std::shared_ptr<Dataset> dataset) = 0;
212 :
213 : /**
214 : * @brief add layer into neural network model
215 : * @retval #ML_ERROR_NONE Successful.
216 : * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
217 : */
218 : virtual int addLayer(std::shared_ptr<Layer> layer) = 0;
219 :
220 : /**
221 : * @brief add referring to reference layers.
222 : * @note This method does add the provided layers itself but adds a deep copy
223 : * of the passed layers to the model. The layers passed to this function can
224 : * be reused later.
225 : * @note @a reference is a set of layers connected each other to form a part
226 : * or whole graph which can be loaded to a model and can be run.
227 : * More specifically, the graph with a non cyclic, directed graph with all
228 : * node has either incoming or outgoing connection defined when considering
229 : * non-input layer is directly connected to the previous layer. 'input
230 : * layer' is defined as a layer that has no incoming connection and
231 : * (identified as @a start_layers or input shape is specified explicitly).
232 : *
233 : * @param reference a group of layers being referred to.
234 : * @param type type of reference layers
235 : * @param scope scope of added layers, identifier will be added
236 : * @param input_layers input layers which will be used to connect input layers
237 : * @param start_layers start layers which will be used to specify start of the
238 : * layers inside @a reference
239 : * @param end_layers end layers which will be used to specify end of the
240 : * layers inside @a reference
241 : * @param type_properties type dependent properties
242 : */
243 : virtual void addWithReferenceLayers(
244 : const std::vector<std::shared_ptr<Layer>> &reference,
245 : const std::string &scope, const std::vector<std::string> &input_layers,
246 : const std::vector<std::string> &start_layers,
247 : const std::vector<std::string> &end_layers, ReferenceLayersType type,
248 : const std::vector<std::string> &type_properties = {}) = 0;
249 :
250 : /**
251 : * @brief Visit each layer inside model
252 : * @param fn function to be called for each layer
253 : * - call param
254 : * @param layer layer the call back is visiting
255 : * @param rc run layer context reference clubbed with layer
256 : * @param user_data user data passed along the function
257 : * @param user_data user data to pass along the callback
258 : */
259 : virtual void
260 : forEachLayer(std::function<void(Layer & /**< layer */,
261 : nntrainer::RunLayerContext & /**< rc */,
262 : void * /**< user_data */)>
263 : fn,
264 : void *user_data = nullptr) = 0;
265 :
266 : /**
267 : * @brief set optimizer for the neural network model
268 : * @retval #ML_ERROR_NONE Successful.
269 : * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
270 : */
271 : virtual int setOptimizer(std::shared_ptr<Optimizer> optimizer) = 0;
272 :
273 : /**
274 : * @brief get layer by name from neural network model
275 : * @param[in] name name of the layer to get
276 : * @param[out] layer shared_ptr to hold the layer to get
277 : * @retval #ML_ERROR_NONE Successful.
278 : * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
279 : */
280 : virtual int getLayer(const char *name, std::shared_ptr<Layer> *layer) = 0;
281 :
282 : /**
283 : * @brief get input dimension of a model
284 : * @retval std::vector<ml::train::TensorDim> input dimension
285 : */
286 : virtual std::vector<ml::train::TensorDim> getInputDimension() = 0;
287 :
288 : /**
289 : * @brief get output dimension of a model
290 : * @retval std::vector<ml::train::TensorDim> output dimension
291 : */
292 : virtual std::vector<ml::train::TensorDim> getOutputDimension() = 0;
293 :
294 : /**
295 : * @brief Run the inference of the model
296 : * @param[in] batch batch size of current input
297 : * @param[in] input inputs as a list of each input data
298 : * @param[in] label labels as a list of each label data
299 : * @retval list of output as float *
300 : * @note The output memory must not be freed by the caller
301 : */
302 : virtual std::vector<float *>
303 : inference(unsigned int batch, const std::vector<float *> &input,
304 : const std::vector<float *> &label = std::vector<float *>()) = 0;
305 :
306 : /**
307 : * @brief Run the incremental inference of the model
308 : * @param[in] batch batch size of current input
309 : * @param[in] input inputs as a list of each input data
310 : * @param[in] label labels as a list of each label data
311 : * @param[in] init_seq_len initial sequence length
312 : * @param[in] from current working step index
313 : * @param[in] to next working step index
314 : * @param[in] output_hidden_state return last hidden state if true else return
315 : * all hidden state
316 : * @retval list of output as float *
317 : * @note The output memory must not be freed by the caller
318 : */
319 : virtual std::vector<float *>
320 : incremental_inference(unsigned int batch, const std::vector<float *> &input,
321 : const std::vector<float *> &label,
322 : unsigned int init_seq_len, unsigned int from,
323 : unsigned int to, bool output_hidden_state = false) = 0;
324 :
325 : /**
326 : * @brief reset input dimensions of a model
327 : * @param[in] dims input dimensions
328 : * @note Similar to reinitialize, the resetInputDimension API is used for
329 : * modifying input dimensions after model initialization. The reinitialize
330 : * function should be the officially called API when changing input
331 : * dimensions, as it properly recalculates weights, tensors, and outputs for
332 : * each layer. On the other hand, resetInputDimension is a specialized API
333 : * created to modify only specific dimensions (specifically height values)
334 : * within input/output dimensions. Since this API uniformly adjusts the height
335 : * across all model layers, developers must verify that every layer in their
336 : * model architecture can safely accommodate such height modifications.
337 : */
338 : virtual void resetInputDimension(std::vector<ml::train::TensorDim> dims) = 0;
339 :
340 : /**
341 : * @brief Summarize the model
342 : * @param out std::ostream to get the model summary
343 : * @param verbosity verbosity of the summary
344 : */
345 : virtual void summarize(std::ostream &out,
346 : ml_train_summary_type_e verbosity) = 0;
347 :
348 : /**
349 : * @brief Get current epoch_idx
350 : * @retval epoch_idx
351 : */
352 : virtual unsigned int getCurrentEpoch() = 0;
353 :
354 : /**
355 : * @brief Get Loss
356 : * @retval loss value
357 : */
358 : virtual float getLoss() = 0;
359 :
360 : /**
361 : * @brief returns compilation state of a network
362 : * @retval initialized value
363 : */
364 : virtual bool getCompiled() const = 0;
365 :
366 : /**
367 : * @brief returns initialization state of a network
368 : * @retval initialized value
369 : */
370 : virtual bool getInitialized() const = 0;
371 :
372 : /**
373 : * @brief returns loadedFromConfig state of a network
374 : * @retval loadedFromConfig value
375 : */
376 : virtual bool getLoadedFromConfig() const = 0;
377 :
378 : /**
379 : * @brief Get Loss from the previous epoch of training data
380 : * @retval loss value
381 : */
382 : virtual float getTrainingLoss() = 0;
383 :
384 : /**
385 : * @brief Get Loss from the previous epoch of validation data
386 : * @retval loss value
387 : */
388 : virtual float getValidationLoss() = 0;
389 :
390 : /**
391 : * @brief Get training statstics
392 : * @retval training statstics
393 : */
394 : virtual RunStats getTrainingStats() = 0;
395 :
396 : /**
397 : * @brief Get validation statstics
398 : * @retval validation statstics
399 : */
400 : virtual RunStats getValidStats() = 0;
401 :
402 : /**
403 : * @brief Get test statstics
404 : * @retval test statstics
405 : */
406 : virtual RunStats getTestStats() = 0;
407 :
408 : /**
409 : * @brief allocate tensor according to execution mode
410 : */
411 : virtual int allocate(ExecutionMode mode = ExecutionMode::TRAIN) = 0;
412 :
413 : /**
414 : * @brief export the model according to given export method
415 : * @param method export method
416 : * @param file_path path to be serialized
417 : */
418 : virtual void exports(const ExportMethods &method,
419 : const std::string file_path) = 0;
420 : };
421 :
422 : /**
423 : * @brief Factory creator with constructor for optimizer
424 : */
425 : std::unique_ptr<Model>
426 : createModel(ModelType type = ml::train::ModelType::NEURAL_NET,
427 : const std::vector<std::string> &properties = {});
428 :
429 : /**
430 : * @brief creator by copying the configuration of other model
431 : */
432 : std::unique_ptr<Model> copyConfiguration(Model &from);
433 :
434 : } // namespace train
435 : } // namespace ml
436 :
437 : #else
438 : #error "CPP versions c++17 or over are only supported"
439 : #endif // __cpluscplus
440 : #endif // __ML_TRAIN_MODEL_H__
|