1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
9 #include "inference_engine.hpp"
10 #include "ClassificationProcessor.hpp"
11 #include "SSDObjectDetectionProcessor.hpp"
12 #include "data_stats.h"
17 * Calibrator class representing unified stages for calibration of any kind of networks
19 class Int8Calibrator {
22 * Intermediate structure storing of data for measurements of by-layer statistic of accuracy drop
24 struct SingleLayerData {
25 InferenceEngine::InferRequest _request;
26 std::string _outputName;
27 std::string _outputI8Name;
28 std::vector<float> _int8Accuracy;
32 * Initializes state to collect accuracy of FP32 network and collect statistic
33 * of activations. The statistic of activations is stored in _statData and has all max/min for all
34 * layers and for all pictures
35 * The inference of all pictures and real collect of the statistic happen during call of
36 * Processor::Process()
38 void collectFP32Statistic();
41 * Initializes a state to collect intermediate numeric accuracy drop happening during quantization of
42 * certain layer to int8. The numeric accuracy drop is measured using NRMSD metric.
44 * For this purpose it creates dedicated network for certain layer, initializes this
45 * network by statistic that cause execute dedicated network in int8 mode.
47 * In addition to original network we create full original network executed in FP32 mode, and
48 * register all layers as output ones.
49 * Information from these layers is used as
50 * a) input to dedicated layer networks
51 * b) comparison for NRMSD algorithm between I8 and FP32 calc
53 * The inference of all pictures and real collect of the drop happen during call of
54 * Processor::Process()
57 void collectByLayerStatistic(const InferenceEngine::NetworkStatsMap &stat);
60 * Initialize state to collect accuracy drop in int8 mode to be compared later vs FP32 accuracy
63 * The inference of all pictures and real collect of the accuracy happen during call of
64 * Processor::Process()
66 * @param stat - The statistic for normalization
67 * @param layersToInt8 - list of layers planned to be executed in int8. if layer is absent in this
68 * map, it is assumed that it will be executed in int8
69 * @param convertFullyConnected - should the FullyConnected layers be converted into Int8 or not
71 void validateInt8Config(const InferenceEngine::NetworkStatsMap &stat,
72 const std::map<std::string, bool>& layersToInt8,
73 bool convertFullyConnected);
76 * Statistic collected in the collectFP32Statistic is processed with threshold passed as a parameter
77 * for this method. All values for each layers and for all pictures are sorted and number of min/max
78 * values which exceed threshold is thrown off
79 * @param threshold - parameter for thrown off outliers in activation statistic
80 * @return InferenceEngine::NetworkStatsMap - mapping of layer name to NetworkNodeStatsPtr
82 InferenceEngine::NetworkStatsMap getStatistic(float threshold);
85 * returns by-layer accuracy drop container
87 std::map<std::string, float> layersAccuracyDrop();
91 * This function should be called from final callibrator after and each Infer for each picture
92 * It calculates by layer accuracy drop and as well it also collect activation values statistic
94 void collectCalibrationStatistic(size_t pics);
97 * This function should be called from calibration class after Infer of all picture
98 * It calculates average NRMSD based accuracy drop for each layer and fills _layersAccuracyDrop
100 void calculateLayersAccuracyDrop();
102 bool _collectByLayer = false;
103 bool _collectStatistic = true;
104 InferencePlugin _pluginI8C;
105 std::string _modelFileNameI8C;
106 InferenceEngine::CNNNetReader networkReaderC;
107 InferenceEngine::InferRequest _inferRequestI8C;
114 * helper function for getting statistic for input layers. For getting statistic for them, we are
115 * adding scalshift just after the input with scale == 1 and shift == 0
117 CNNLayerPtr addScaleShiftBeforeLayer(std::string name, InferenceEngine::CNNLayer::Ptr beforeLayer,
118 size_t port, std::vector<float> scale);
121 * Returns Normalized root-mean-square deviation metric for two blobs passed to the function
123 float compare_NRMSD(InferenceEngine::Blob::Ptr res, InferenceEngine::Blob::Ptr ref);
126 * Creates dedicated i8 network around selected layer. Currently this network beside layer itself
127 * has to have ReLU and ScaleShift layers.
128 * Since Inference Engine API mostly directed to the loading of network from IR, we need to create
129 * such IR first, read through stream and modify network to correspond required parameters
131 InferenceEngine::CNNNetwork createICNNNetworkForLayer(InferenceEngine::CNNLayer::Ptr layerToClone,
134 std::map<std::string, float> _layersAccuracyDrop;
135 std::vector<InferenceEngine::ExecutableNetwork> _singleLayerNetworks;
136 std::map<std::string, SingleLayerData> _singleLayerRequests;
137 std::map<std::string, std::string> _inputsFromLayers;
138 AggregatedDataStats _statData;
142 * This class represents the only one generalized metric which will be used for comparison of
145 struct CalibrationMetrics : public ClassificationProcessor::InferenceMetrics {
147 float AccuracyResult = 0;
151 * Сalibration class for classification networks.
152 * Responsible for proper post processing of results and calculate of Top1 metric which is used as
153 * universal metric for accuracy and particiapted in verification of accuracy drop
155 class ClassificationCalibrator : public ClassificationProcessor, public Int8Calibrator {
157 ClassificationCalibrator(int nPictures, const std::string &flags_m, const std::string &flags_d,
158 const std::string &flags_i, int flags_b,
159 InferenceEngine::InferencePlugin plugin, CsvDumper &dumper, const std::string &flags_l,
160 PreprocessingOptions preprocessingOptions, bool zeroBackground);
162 shared_ptr<InferenceMetrics> Process(bool stream_output = false) override;
167 * Calibration class for SSD object detection networks.
168 * Responsible for proper post processing of results and calculate of mAP metric which is used as
169 * universal metric for accuracy and participated in verification of accuracy drop
171 class SSDObjectDetectionCalibrator : public SSDObjectDetectionProcessor, public Int8Calibrator {
173 SSDObjectDetectionCalibrator(int nPictures, const std::string &flags_m, const std::string &flags_d,
174 const std::string &flags_i, const std::string &subdir, int flags_b,
176 InferencePlugin plugin, CsvDumper &dumper,
177 const std::string &flags_a, const std::string &classes_list_file);
179 shared_ptr<InferenceMetrics> Process(bool stream_output = false) override;