aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAron Virginas-Tar <Aron.Virginas-Tar@arm.com>2019-06-21 15:25:19 +0100
committerÁron Virginás-Tar <aron.virginas-tar@arm.com>2019-06-21 16:08:15 +0000
commit389aa70c8a24fa2faf33df5f8cd9a99b0fabe971 (patch)
tree23794e376c15e5a7cd79bec95a23028944c8f9dc
parent5e1b0cf8a7519afb49874a83429ef9939a249f0d (diff)
downloadarmnn-experimental/transpose_conv2d.tar.gz
IVGCVSW-3322 Add Quantizer support for TransposeConvolution2DLayerexperimental/transpose_conv2d
Signed-off-by: Aron Virginas-Tar <Aron.Virginas-Tar@arm.com> Change-Id: I26997d7770585055b2b3256baad2800a4c5ed7e8
-rw-r--r--src/armnn/QuantizerVisitor.cpp28
-rw-r--r--src/armnn/QuantizerVisitor.hpp6
-rw-r--r--src/armnn/test/QuantizerTest.cpp77
3 files changed, 111 insertions, 0 deletions
diff --git a/src/armnn/QuantizerVisitor.cpp b/src/armnn/QuantizerVisitor.cpp
index ef6b068145..292924c8e4 100644
--- a/src/armnn/QuantizerVisitor.cpp
+++ b/src/armnn/QuantizerVisitor.cpp
@@ -446,4 +446,32 @@ void QuantizerVisitor::VisitSubtractionLayer(const IConnectableLayer* layer,
SetQuantizedInputConnections(layer, newLayer);
}
+void QuantizerVisitor::VisitTransposeConvolution2dLayer(const IConnectableLayer* layer,
+ const TransposeConvolution2dDescriptor& descriptor,
+ const ConstTensor& weights,
+ const Optional<ConstTensor>& biases,
+ const char* name)
+{
+ // quantize weights
+ std::vector<uint8_t> weightsBacking;
+ ConstTensor qWeights = CreateQuantizedConst(weights, weightsBacking);
+
+ // quantize biases
+ std::vector<int32_t> biasesBacking;
+ Optional<ConstTensor> optionalQBiases;
+ if (biases.has_value())
+ {
+ ConstTensor qBiases = CreateQuantizedBias(layer, qWeights, biases, biasesBacking);
+ optionalQBiases = Optional<ConstTensor>(qBiases);
+ }
+
+ IConnectableLayer* newLayer = m_QuantizedNetwork->AddTransposeConvolution2dLayer(descriptor,
+ qWeights,
+ optionalQBiases,
+ name);
+
+ RecordLayer(layer, newLayer);
+ SetQuantizedInputConnections(layer, newLayer);
+}
+
} //namespace armnn
diff --git a/src/armnn/QuantizerVisitor.hpp b/src/armnn/QuantizerVisitor.hpp
index ca9f6940a6..c3a2eaffcb 100644
--- a/src/armnn/QuantizerVisitor.hpp
+++ b/src/armnn/QuantizerVisitor.hpp
@@ -140,6 +140,12 @@ public:
void VisitSubtractionLayer(const IConnectableLayer* layer,
const char* name = nullptr) override;
+ void VisitTransposeConvolution2dLayer(const IConnectableLayer* layer,
+ const TransposeConvolution2dDescriptor& descriptor,
+ const ConstTensor& weights,
+ const Optional<ConstTensor>& biases,
+ const char* name = nullptr) override;
+
/// Extract the quantized network
INetworkPtr RetrieveFinalNetwork() { return std::move(m_QuantizedNetwork); }
diff --git a/src/armnn/test/QuantizerTest.cpp b/src/armnn/test/QuantizerTest.cpp
index 2792d5c483..4732da393f 100644
--- a/src/armnn/test/QuantizerTest.cpp
+++ b/src/armnn/test/QuantizerTest.cpp
@@ -1715,6 +1715,83 @@ BOOST_AUTO_TEST_CASE(QuantizePrelu)
VisitLayersTopologically(quantizedNetworkQSymm16.get(), validatorQSymm16);
}
+void TestQuantizeTransposeConvolution2d(bool useBiases)
+{
+ class TestTransposeConvolution2dQuantization : public TestQuantization
+ {
+ public:
+ TestTransposeConvolution2dQuantization(const TensorShape& inputShape, const TensorShape& outputShape) :
+ TestQuantization(inputShape, outputShape)
+ {}
+
+ TestTransposeConvolution2dQuantization(const QuantizerOptions& options,
+ const TensorShape& inputShape,
+ const TensorShape& outputShape) :
+ TestQuantization(options, inputShape, outputShape)
+ {}
+
+ void VisitTransposeConvolution2dLayer(const IConnectableLayer *layer,
+ const TransposeConvolution2dDescriptor& descriptor,
+ const ConstTensor& weights,
+ const Optional<ConstTensor>& biases,
+ const char *name = nullptr) override
+ {
+ TestQuantizationOnLayersWithBiases(layer, weights, biases);
+ }
+ };
+
+ INetworkPtr network = INetwork::Create();
+
+ TensorShape shape{ 3 };
+ TensorInfo info(shape, DataType::Float32);
+
+ std::initializer_list<float> floatData{ -1.0f, 1.5f, 2.0f };
+ std::vector<float> weightsData(floatData);
+ ConstTensor weights(info, weightsData);
+
+ TransposeConvolution2dDescriptor descriptor;
+ descriptor.m_BiasEnabled = useBiases;
+
+ // construct network
+ IConnectableLayer* input = network->AddInputLayer(0);
+ Optional<ConstTensor> optionalBiases;
+ std::vector<float> biasesData(floatData);
+ if (useBiases)
+ {
+ ConstTensor biases(info, biasesData);
+ optionalBiases = Optional<ConstTensor>(biases);
+ }
+ IConnectableLayer* transposeConv2d = network->AddTransposeConvolution2dLayer(descriptor, weights, optionalBiases);
+ IConnectableLayer* output = network->AddOutputLayer(1);
+
+ input->GetOutputSlot(0).Connect(transposeConv2d->GetInputSlot(0));
+ transposeConv2d->GetOutputSlot(0).Connect(output->GetInputSlot(0));
+
+ input->GetOutputSlot(0).SetTensorInfo(info);
+ transposeConv2d->GetOutputSlot(0).SetTensorInfo(info);
+
+ // test QAsymm8 quantization
+ INetworkPtr quantizedNetworkQAsymm8 = INetworkQuantizer::Create(network.get())->ExportNetwork();
+ TestTransposeConvolution2dQuantization validatorQAsymm8(shape, shape);
+ VisitLayersTopologically(quantizedNetworkQAsymm8.get(), validatorQAsymm8);
+
+ // test QSymm16 quantization
+ const QuantizerOptions options(DataType::QuantisedSymm16);
+ INetworkPtr quantizedNetworkQSymm16 = INetworkQuantizer::Create(network.get(), options)->ExportNetwork();
+ TestTransposeConvolution2dQuantization validatorQSymm16(options, shape, shape);
+ VisitLayersTopologically(quantizedNetworkQSymm16.get(), validatorQSymm16);
+}
+
+BOOST_AUTO_TEST_CASE(QuantizeTransposeConvolution2d)
+{
+ TestQuantizeTransposeConvolution2d(false);
+}
+
+BOOST_AUTO_TEST_CASE(QuantizeTransposeConvolution2dWithBiases)
+{
+ TestQuantizeTransposeConvolution2d(true);
+}
+
std::vector<uint8_t> SetupQuantize(float value)
{
armnn::TensorInfo inputInfo({ 1, 2, 2 }, armnn::DataType::Float32);