Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / samples / calibration_tool / main.cpp
index cd01014..90ee2b0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2019 Intel Corporation
 // SPDX-License-Identifier: Apache-2.0
 //
 
@@ -38,8 +38,6 @@ using namespace InferenceEngine::details;
 
 using InferenceEngine::details::InferenceEngineException;
 
-#define DEFAULT_PATH_P "./lib"
-
 /// @brief Message for help argument
 static const char help_message[] = "Print a help message";
 /// @brief Message for images argument
@@ -56,7 +54,7 @@ static const char model_message[] = "Required. Path to an .xml file with a train
 static const char plugin_message[] = "Plugin name. For example, CPU. If this parameter is passed, "
                                      "the sample looks for a specified plugin only.";
 /// @brief Message for assigning cnn calculation to device
-static const char target_device_message[] = "Target device to infer on: CPU (default), GPU, FPGA, or MYRIAD."
+static const char target_device_message[] = "Target device to infer on: CPU (default), GPU, FPGA, HDDL or MYRIAD."
                                             " The application looks for a suitable plugin for the specified device.";
 /// @brief Message for label argument
 static const char label_message[] = "Path to a file with labels for a model";
@@ -99,9 +97,12 @@ static const char zero_background_message[] = "\"Zero is a background\" flag. So
                                               " are enumerated from 1, but 0 is an undefined \"background\" class"
                                               " (which is never detected)";
 
-static const char stream_output_message[] = "Flag for printing progress as a plain text.When used, interactive progress"
+static const char stream_output_message[] = "Flag for printing progress as a plain text. When used, interactive progress"
                                             " bar is replaced with multiline output";
 
+static const char convert_fc_message[] = "Convert FullyConnected layers to Int8 or not (false by default)";
+
+
 /// @brief Network type options and their descriptions
 static const char* types_descriptions[][2] = {
     { "C", "calibrate Classification network and write the calibrated network to IR" },
@@ -139,7 +140,7 @@ DEFINE_string(p, "", plugin_message);
 DEFINE_string(OCl, "", label_message);
 /// @brief Define parameter for a path to plugins <br>
 /// Default is ./lib
-DEFINE_string(pp, DEFAULT_PATH_P, plugin_path_message);
+DEFINE_string(pp, "", plugin_path_message);
 /// @brief Define paraneter for a target device to infer on <br>
 DEFINE_string(d, "CPU", target_device_message);
 /// @brief Define parameter for batch size <br>
@@ -189,6 +190,8 @@ DEFINE_string(output, "", output_model_name);
 
 DEFINE_string(lbl, "", labels_file_message);
 
+DEFINE_bool(convert_fc, false, convert_fc_message);
+
 /**
  * @brief This function shows a help message
  */
@@ -250,7 +253,8 @@ std::string strtolower(const std::string& s) {
 void SaveCalibratedIR(const std::string &originalName,
                       const std::string &outModelName,
                       const std::map<std::string, bool>& layersToInt8,
-                      const InferenceEngine::NetworkStatsMap& statMap) {
+                      const InferenceEngine::NetworkStatsMap& statMap,
+                      bool convertFullyConnected) {
     slog::info << "Layers profile for Int8 quantization\n";
     CNNNetReader networkReader;
     networkReader.ReadNetwork(originalName);
@@ -271,6 +275,14 @@ void SaveCalibratedIR(const std::string &originalName,
                 layer->params["quantization_level"] = "I8";
                 std::cout << layer->name << ": " << "I8" << std::endl;
             }
+        } else if (CaselessEq<std::string>()(layer->type, "fullyconnected")) {
+            if (!convertFullyConnected) {
+                layer->params["quantization_level"] = "FP32";
+                std::cout << layer->name << ": " << "FP32" << std::endl;
+            } else {
+                layer->params["quantization_level"] = "I8";
+                std::cout << layer->name << ": " << "I8" << std::endl;
+            }
         }
     }
 
@@ -340,7 +352,7 @@ int main(int argc, char *argv[]) {
         // ---------------------Loading plugin for Inference Engine------------------------------------------------
         slog::info << "Loading plugin" << slog::endl;
         /** Loading the library with extensions if provided**/
-        InferencePlugin plugin = PluginDispatcher({ FLAGS_pp, "../../../lib/intel64", "" }).getPluginByDevice(FLAGS_d);
+        InferencePlugin plugin = PluginDispatcher({ FLAGS_pp }).getPluginByDevice(FLAGS_d);
 
         /** Loading default extensions **/
         if (FLAGS_d.find("CPU") != std::string::npos) {
@@ -436,7 +448,7 @@ int main(int argc, char *argv[]) {
             for (float threshold = 100.0f; threshold > 95.0f; threshold -= 0.5) {
                 std::cout << "Validate int8 accuracy, threshold for activation statistics = " << threshold << std::endl;
                 InferenceEngine::NetworkStatsMap tmpStatMap = calibrator->getStatistic(threshold);
-                calibrator->validateInt8Config(tmpStatMap, {});
+                calibrator->validateInt8Config(tmpStatMap, {}, FLAGS_convert_fc);
                 shared_ptr<Processor::InferenceMetrics> pIM_I8 = processor->Process(FLAGS_stream_output);
                 const CalibrationMetrics *mI8 = dynamic_cast<const CalibrationMetrics *>(pIM_I8.get());
                 if (maximalAccuracy < mI8->AccuracyResult) {
@@ -472,7 +484,7 @@ int main(int argc, char *argv[]) {
                 while (it != orderedLayersAccuracyDrop.crend() && bAccuracy == false) {
                     slog::info << "Returning of '" << it->second << "' to FP32 precision, start validation\n";
                     layersToInt8[it->second] = false;
-                    calibrator->validateInt8Config(statMap, layersToInt8);
+                    calibrator->validateInt8Config(statMap, layersToInt8, FLAGS_convert_fc);
                     pIM_I8 = processor->Process(FLAGS_stream_output);
                     mI8 = dynamic_cast<const CalibrationMetrics *>(pIM_I8.get());
                     maximalAccuracy = mI8->AccuracyResult;
@@ -494,7 +506,7 @@ int main(int argc, char *argv[]) {
                     "current Int8 configuration accuracy: " << OUTPUT_FLOATING(100.0 * maximalAccuracy) << "% " <<
                     "with threshold for activation statistic: " << bestThreshold << "%" << std::endl;
                 std::string outModelName = FLAGS_output.empty() ? fileNameNoExt(FLAGS_m) + "_i8" : fileNameNoExt(FLAGS_output);
-                SaveCalibratedIR(FLAGS_m, outModelName, layersToInt8, statMap);
+                SaveCalibratedIR(FLAGS_m, outModelName, layersToInt8, statMap, FLAGS_convert_fc);
             } else {
                 slog::info << "Required threshold of accuracy drop cannot be achieved with any int8 quantization\n";
             }
@@ -502,7 +514,7 @@ int main(int argc, char *argv[]) {
             std::cout << "Collected activation statistics, writing maximum values to IR" << std::endl;
             statMap = calibrator->getStatistic(100.0f);
             std::string outModelName = FLAGS_output.empty() ? fileNameNoExt(FLAGS_m) + "_i8" : fileNameNoExt(FLAGS_output);
-            SaveCalibratedIR(FLAGS_m, outModelName, layersToInt8, statMap);
+            SaveCalibratedIR(FLAGS_m, outModelName, layersToInt8, statMap, FLAGS_convert_fc);
         }
 
         if (dumper.dumpEnabled()) {
@@ -521,7 +533,6 @@ int main(int argc, char *argv[]) {
             showUsage();
             return ex.list().begin()->exitCode();
         } else {
-            const char* s = ex.what();
             slog::err << "Input problems: \n" << ex.what() << slog::endl;
             showUsage();
             return ex.list().begin()->exitCode();