-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2019 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
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
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";
" 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" },
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>
DEFINE_string(lbl, "", labels_file_message);
+DEFINE_bool(convert_fc, false, convert_fc_message);
+
/**
* @brief This function shows a help message
*/
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);
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;
+ }
}
}
// ---------------------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) {
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) {
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;
"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";
}
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()) {
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();