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