[LPT] FuseFakeQuantizeAndScaleShift transformation for last layer fix (#1291)
* [LPT] FuseFakeQuantizeAndScaleShift transformation for last layer fix * [LPT] refactoring * [LPT] FuseFakeQuantizeAndScaleShift test: last layer name validation was added
This commit is contained in:
parent
0607b7b0f7
commit
d791962464
@ -38,6 +38,7 @@ void FuseFakeQuantizeAndScaleShiftTransformation::transform(
|
||||
}
|
||||
|
||||
auto dScaleShift = dScaleShiftsVector[0];
|
||||
|
||||
const Blob::Ptr scalesBlob = CNNNetworkHelper::getBlob(dScaleShift, "weights");
|
||||
auto scalesBufferPtr = CNNNetworkHelper::getFloatData(scalesBlob);
|
||||
|
||||
@ -55,9 +56,21 @@ void FuseFakeQuantizeAndScaleShiftTransformation::transform(
|
||||
return;
|
||||
}
|
||||
|
||||
OutputsDataMap outputs;
|
||||
context.network.getOutputsInfo(outputs);
|
||||
const bool dScaleShiftIsLastLayer = outputs.find(dScaleShift->name) != outputs.end();
|
||||
if (dScaleShiftIsLastLayer && (dScaleShiftsVector.size() > 1ul)) {
|
||||
// not possible to fuse ScaleShifts if at least one is output
|
||||
return;
|
||||
}
|
||||
|
||||
// All ScaleShifts must be equal
|
||||
for (size_t i = 1lu; i < dScaleShiftsVector.size(); i++) {
|
||||
auto ssLayer = dScaleShiftsVector[i];
|
||||
if (outputs.find(ssLayer->name) != outputs.end()) {
|
||||
// not possible to fuse ScaleShifts if at least one is output
|
||||
return;
|
||||
}
|
||||
|
||||
const Blob::Ptr scBlob = CNNNetworkHelper::getBlob(ssLayer, "weights");
|
||||
auto scBufferPtr = CNNNetworkHelper::getFloatData(scBlob);
|
||||
@ -144,4 +157,9 @@ void FuseFakeQuantizeAndScaleShiftTransformation::transform(
|
||||
auto ssPrecision = dScaleShiftsVector[0]->outData[0]->getPrecision();
|
||||
fakeQuantizeLayer.outData[0]->setPrecision(ssPrecision);
|
||||
}
|
||||
|
||||
|
||||
if (dScaleShiftIsLastLayer) {
|
||||
CNNNetworkHelper::renameLayer(context.network, fakeQuantizeLayer.name, dScaleShift->name);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "low_precision_transformations/fuse_fake_quantize_and_scale_shift_transformation.hpp"
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
#include "ngraph_functions/low_precision_transformations/fuse_fake_quantize_and_scale_shift_function.hpp"
|
||||
|
||||
using namespace LayerTestsDefinitions;
|
||||
using namespace InferenceEngine::details;
|
||||
|
||||
namespace {
|
||||
const std::vector<InferenceEngine::Precision> netPrecisions = {
|
||||
InferenceEngine::Precision::FP32
|
||||
};
|
||||
|
||||
const std::vector<LayerTransformation::Params> trasformationParamValues = {
|
||||
LayerTestsUtils::LayerTransformationParamsFactory::createParamsU8I8()
|
||||
};
|
||||
|
||||
const std::vector<ngraph::builder::subgraph::FakeQuantizeOnData> fakeQuantizeOnDataValues = {
|
||||
{ 256ul, {}, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||
{
|
||||
256ul,
|
||||
{ 1ul, 3ul, 1ul, 1ul },
|
||||
{ 0.f, 0.f, 0.f },
|
||||
{ 2.55f / 10.f, 2.55f / 5.f, 2.55f / 2.f },
|
||||
{ 0.f, 0.f, 0.f },
|
||||
{ 2.55f / 10.f, 2.55f / 5.f, 2.55f / 2.f }
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(LPT, FuseFakeQuantizeAndScaleShiftTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(InferenceEngine::SizeVector({ 1, 3, 9, 9 })),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(fakeQuantizeOnDataValues)),
|
||||
FuseFakeQuantizeAndScaleShiftTransformation::getTestCaseName);
|
||||
} // namespace
|
@ -21,7 +21,7 @@ std::vector<std::string> disabledTestPatterns() {
|
||||
R"(.*(QuantGroupConv2D).*)",
|
||||
R"(.*(QuantGroupConv3D).*)",
|
||||
// TODO: Issue 31845
|
||||
R"(.*(FakeQuantize).*)",
|
||||
R"(.*(FakeQuantizeLayerTest).*)",
|
||||
R"(.*(EltwiseLayerTest).*IS=\(.*\..*\..*\..*\..*\).*secondaryInputType=PARAMETER.*opType=SCALAR.*)",
|
||||
// TODO: Issue 32756
|
||||
R"(.*Transpose.*inputOrder=\(\).*)",
|
||||
|
@ -0,0 +1,43 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "low_precision_transformations/fuse_fake_quantize_and_scale_shift_transformation.hpp"
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
#include "ngraph_functions/low_precision_transformations/fuse_fake_quantize_and_scale_shift_function.hpp"
|
||||
|
||||
using namespace LayerTestsDefinitions;
|
||||
using namespace InferenceEngine::details;
|
||||
|
||||
namespace {
|
||||
const std::vector<InferenceEngine::Precision> netPrecisions = {
|
||||
InferenceEngine::Precision::FP32
|
||||
};
|
||||
|
||||
const std::vector<LayerTransformation::Params> trasformationParamValues = {
|
||||
LayerTestsUtils::LayerTransformationParamsFactory::createParamsU8I8()
|
||||
};
|
||||
|
||||
const std::vector<ngraph::builder::subgraph::FakeQuantizeOnData> fakeQuantizeOnDataValues = {
|
||||
{ 256ul, {}, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||
{
|
||||
256ul,
|
||||
{ 1ul, 3ul, 1ul, 1ul },
|
||||
{ 0.f, 0.f, 0.f },
|
||||
{ 2.55f / 10.f, 2.55f / 5.f, 2.55f / 2.f },
|
||||
{ 0.f, 0.f, 0.f },
|
||||
{ 2.55f / 10.f, 2.55f / 5.f, 2.55f / 2.f }
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(LPT, FuseFakeQuantizeAndScaleShiftTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(InferenceEngine::SizeVector({ 1, 3, 9, 9 })),
|
||||
::testing::Values(CommonTestUtils::DEVICE_GPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(fakeQuantizeOnDataValues)),
|
||||
FuseFakeQuantizeAndScaleShiftTransformation::getTestCaseName);
|
||||
} // namespace
|
@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "ngraph_functions/low_precision_transformations/fuse_fake_quantize_and_scale_shift_function.hpp"
|
||||
#include "functional_test_utils/low_precision_transformations/layer_transformation.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
typedef std::tuple<
|
||||
InferenceEngine::Precision,
|
||||
InferenceEngine::SizeVector,
|
||||
std::string,
|
||||
InferenceEngine::details::LayerTransformation::Params,
|
||||
ngraph::builder::subgraph::FakeQuantizeOnData> FuseFakeQuantizeAndScaleShiftTransformationParams;
|
||||
|
||||
class FuseFakeQuantizeAndScaleShiftTransformation :
|
||||
public testing::WithParamInterface<FuseFakeQuantizeAndScaleShiftTransformationParams>,
|
||||
public LayerTestsUtils::LayerTransformation {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<FuseFakeQuantizeAndScaleShiftTransformationParams> obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
|
||||
private:
|
||||
void validate(const std::string& referenceOutputLayerName);
|
||||
};
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
@ -0,0 +1,79 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "low_precision_transformations/fuse_fake_quantize_and_scale_shift_transformation.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <ie_core.hpp>
|
||||
|
||||
#include <transformations/init_node_info.hpp>
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
std::string FuseFakeQuantizeAndScaleShiftTransformation::getTestCaseName(testing::TestParamInfo<FuseFakeQuantizeAndScaleShiftTransformationParams> obj) {
|
||||
InferenceEngine::Precision netPrecision;
|
||||
InferenceEngine::SizeVector inputShapes;
|
||||
std::string targetDevice;
|
||||
InferenceEngine::details::LayerTransformation::Params params;
|
||||
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantizeOnData;
|
||||
std::tie(netPrecision, inputShapes, targetDevice, params, fakeQuantizeOnData) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
result << netPrecision << "_" << targetDevice << "_" << fakeQuantizeOnData;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void FuseFakeQuantizeAndScaleShiftTransformation::SetUp() {
|
||||
InferenceEngine::SizeVector inputShape;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
InferenceEngine::details::LayerTransformation::Params params;
|
||||
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantizeOnData;
|
||||
std::tie(netPrecision, inputShape, targetDevice, params, fakeQuantizeOnData) = this->GetParam();
|
||||
|
||||
function = ngraph::builder::subgraph::FuseFakeQuantizeAndScaleShiftFunction::getOriginal(
|
||||
FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision),
|
||||
inputShape,
|
||||
fakeQuantizeOnData);
|
||||
|
||||
ngraph::pass::InitNodeInfo().run_on_function(function);
|
||||
|
||||
EXPECT_EQ(1ul, function->get_output_size());
|
||||
EXPECT_EQ(1ul, function->get_output_op(0)->get_input_size());
|
||||
const std::string referenceOutputLayerName = function->get_output_op(0)->get_input_node_ptr(0)->get_friendly_name();
|
||||
|
||||
validate(referenceOutputLayerName);
|
||||
}
|
||||
|
||||
void FuseFakeQuantizeAndScaleShiftTransformation::validate(const std::string& referenceOutputLayerName) {
|
||||
InferenceEngine::SizeVector inputShape;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
InferenceEngine::details::LayerTransformation::Params params;
|
||||
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantizeOnData;
|
||||
std::tie(netPrecision, inputShape, targetDevice, params, fakeQuantizeOnData) = this->GetParam();
|
||||
|
||||
auto transformations = getLowPrecisionTransformations(params);
|
||||
const InferenceEngine::CNNNetwork network = transform(transformations);
|
||||
|
||||
IE_SUPPRESS_DEPRECATED_START
|
||||
|
||||
InferenceEngine::OutputsDataMap outputs = network.getOutputsInfo();
|
||||
EXPECT_EQ(1, outputs.size());
|
||||
|
||||
std::map<std::string, InferenceEngine::DataPtr>::iterator it = outputs.begin();
|
||||
const InferenceEngine::CNNLayerPtr outputLayer = getCreatorLayer(it->second).lock();
|
||||
EXPECT_TRUE(outputLayer != nullptr);
|
||||
EXPECT_EQ("FakeQuantize", outputLayer->type);
|
||||
EXPECT_EQ(referenceOutputLayerName, outputLayer->name);
|
||||
|
||||
IE_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
|
||||
TEST_P(FuseFakeQuantizeAndScaleShiftTransformation, CompareWithRefImpl) {
|
||||
Run();
|
||||
};
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <ngraph/ngraph.hpp>
|
||||
#include "common/fake_quantize_on_data.hpp"
|
||||
|
||||
namespace ngraph {
|
||||
namespace builder {
|
||||
namespace subgraph {
|
||||
|
||||
class FuseFakeQuantizeAndScaleShiftFunction {
|
||||
public:
|
||||
static std::shared_ptr<ngraph::Function> getOriginal(
|
||||
const ngraph::element::Type precision,
|
||||
const ngraph::Shape& inputShape,
|
||||
const FakeQuantizeOnData& fakeQuantizeOnData);
|
||||
};
|
||||
|
||||
} // namespace subgraph
|
||||
} // namespace builder
|
||||
} // namespace ngraph
|
@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "ngraph_functions/low_precision_transformations/fuse_fake_quantize_and_scale_shift_function.hpp"
|
||||
|
||||
#include <ngraph/opsets/opset1.hpp>
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
|
||||
namespace ngraph {
|
||||
namespace builder {
|
||||
namespace subgraph {
|
||||
|
||||
using namespace ngraph::pass;
|
||||
|
||||
std::shared_ptr<ngraph::Function> FuseFakeQuantizeAndScaleShiftFunction::getOriginal(
|
||||
const ngraph::element::Type precision,
|
||||
const ngraph::Shape& inputShape,
|
||||
const FakeQuantizeOnData& fakeQuantizeOnData) {
|
||||
const auto input = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
|
||||
input->set_friendly_name("input");
|
||||
|
||||
const std::shared_ptr<Node> fakeQuantize = ngraph::builder::makeFakeQuantize(
|
||||
input, precision, fakeQuantizeOnData.quantizationLevel, fakeQuantizeOnData.constantShape,
|
||||
fakeQuantizeOnData.inputLowValues, fakeQuantizeOnData.inputHighValues, fakeQuantizeOnData.outputLowValues, fakeQuantizeOnData.outputHighValues);
|
||||
fakeQuantize->set_friendly_name("fakeQuantize");
|
||||
|
||||
const std::shared_ptr<Node> multiply = std::make_shared<ngraph::opset1::Multiply>(
|
||||
fakeQuantize,
|
||||
std::make_shared<ngraph::opset1::Constant>(precision, Shape{ 1, 1, 1, 1 }, std::vector<float>({ 150 })));
|
||||
|
||||
const std::shared_ptr<Node> add = std::make_shared<ngraph::opset1::Add>(
|
||||
multiply,
|
||||
std::make_shared<ngraph::opset1::Constant>(precision, Shape{ 1, 1, 1, 1 }, std::vector<float>({ 127.5 })));
|
||||
|
||||
const ngraph::ResultVector results{ std::make_shared<ngraph::opset1::Result>(add) };
|
||||
return std::make_shared<ngraph::Function>(results, ngraph::ParameterVector{ input }, "FuseFakeQuantizeAndScaleShiftFunction");
|
||||
}
|
||||
|
||||
} // namespace subgraph
|
||||
} // namespace builder
|
||||
} // namespace ngraph
|
Loading…
Reference in New Issue
Block a user