From: Narumol Prangnawarat Date: Mon, 4 Feb 2019 19:05:27 +0000 (+0000) Subject: IVGCVSW-2557 Add layer tests for Ref Detection PostProcess X-Git-Tag: submit/tizen/20200316.035456~884 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e0a4ad8a8e6ef271883e8029985eeab16d838972;p=platform%2Fupstream%2Farmnn.git IVGCVSW-2557 Add layer tests for Ref Detection PostProcess Change-Id: Ia2e512c0ed035bc6ee46cd67df5e619da9770900 Signed-off-by: Narumol Prangnawarat --- diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt index 4a1d467..124d8f2 100644 --- a/src/backends/backendsCommon/test/CMakeLists.txt +++ b/src/backends/backendsCommon/test/CMakeLists.txt @@ -14,6 +14,7 @@ list(APPEND armnnBackendsCommonUnitTests_sources ConvertFp16ToFp32TestImpl.hpp ConvertFp32ToFp16TestImpl.hpp DebugTestImpl.hpp + DetectionPostProcessLayerTestImpl.hpp DetectionPostProcessTestImpl.hpp EndToEndTestImpl.hpp FullyConnectedTestImpl.hpp diff --git a/src/backends/backendsCommon/test/DetectionPostProcessLayerTestImpl.hpp b/src/backends/backendsCommon/test/DetectionPostProcessLayerTestImpl.hpp new file mode 100644 index 0000000..2a2c1f9 --- /dev/null +++ b/src/backends/backendsCommon/test/DetectionPostProcessLayerTestImpl.hpp @@ -0,0 +1,363 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "TensorCopyUtils.hpp" +#include "TypeUtils.hpp" +#include "WorkloadTestUtils.hpp" + +#include +#include +#include +#include +#include +#include + +template > +void DetectionPostProcessImpl(const armnn::TensorInfo& boxEncodingsInfo, + const armnn::TensorInfo& scoresInfo, + const armnn::TensorInfo& anchorsInfo, + const std::vector& boxEncodingsData, + const std::vector& scoresData, + const std::vector& anchorsData, + const std::vector& expectedDetectionBoxes, + const std::vector& expectedDetectionClasses, + const std::vector& expectedDetectionScores, + const std::vector& expectedNumDetections, + bool useRegularNms) +{ + std::unique_ptr profiler = std::make_unique(); + armnn::ProfilerManager::GetInstance().RegisterProfiler(profiler.get()); + + auto memoryManager = WorkloadFactoryHelper::GetMemoryManager(); + FactoryType workloadFactory = WorkloadFactoryHelper::GetFactory(memoryManager); + + auto boxEncodings = MakeTensor(boxEncodingsInfo, boxEncodingsData); + auto scores = MakeTensor(scoresInfo, scoresData); + auto anchors = MakeTensor(anchorsInfo, anchorsData); + + armnn::TensorInfo detectionBoxesInfo({ 1, 3, 4 }, armnn::DataType::Float32); + armnn::TensorInfo detectionScoresInfo({ 1, 3 }, armnn::DataType::Float32); + armnn::TensorInfo detectionClassesInfo({ 1, 3 }, armnn::DataType::Float32); + armnn::TensorInfo numDetectionInfo({ 1 }, armnn::DataType::Float32); + + LayerTestResult detectionBoxesResult(detectionBoxesInfo); + detectionBoxesResult.outputExpected = MakeTensor(detectionBoxesInfo, expectedDetectionBoxes); + LayerTestResult detectionClassesResult(detectionClassesInfo); + detectionClassesResult.outputExpected = MakeTensor(detectionClassesInfo, expectedDetectionClasses); + LayerTestResult detectionScoresResult(detectionScoresInfo); + detectionScoresResult.outputExpected = MakeTensor(detectionScoresInfo, expectedDetectionScores); + LayerTestResult numDetectionsResult(numDetectionInfo); + numDetectionsResult.outputExpected = MakeTensor(numDetectionInfo, expectedNumDetections); + + std::unique_ptr boxedHandle = workloadFactory.CreateTensorHandle(boxEncodingsInfo); + std::unique_ptr scoreshandle = workloadFactory.CreateTensorHandle(scoresInfo); + std::unique_ptr anchorsHandle = workloadFactory.CreateTensorHandle(anchorsInfo); + std::unique_ptr outputBoxesHandle = workloadFactory.CreateTensorHandle(detectionBoxesInfo); + std::unique_ptr classesHandle = workloadFactory.CreateTensorHandle(detectionClassesInfo); + std::unique_ptr outputScoresHandle = workloadFactory.CreateTensorHandle(detectionScoresInfo); + std::unique_ptr numDetectionHandle = workloadFactory.CreateTensorHandle(numDetectionInfo); + + armnn::ScopedCpuTensorHandle anchorsTensor(anchorsInfo); + AllocateAndCopyDataToITensorHandle(&anchorsTensor, &anchors[0][0]); + + armnn::DetectionPostProcessQueueDescriptor data; + data.m_Parameters.m_UseRegularNms = useRegularNms; + data.m_Parameters.m_MaxDetections = 3; + data.m_Parameters.m_MaxClassesPerDetection = 1; + data.m_Parameters.m_DetectionsPerClass =1; + data.m_Parameters.m_NmsScoreThreshold = 0.0; + data.m_Parameters.m_NmsIouThreshold = 0.5; + data.m_Parameters.m_NumClasses = 2; + data.m_Parameters.m_ScaleY = 10.0; + data.m_Parameters.m_ScaleX = 10.0; + data.m_Parameters.m_ScaleH = 5.0; + data.m_Parameters.m_ScaleW = 5.0; + data.m_Anchors = &anchorsTensor; + + armnn::WorkloadInfo info; + AddInputToWorkload(data, info, boxEncodingsInfo, boxedHandle.get()); + AddInputToWorkload(data, info, scoresInfo, scoreshandle.get()); + AddOutputToWorkload(data, info, detectionBoxesInfo, outputBoxesHandle.get()); + AddOutputToWorkload(data, info, detectionClassesInfo, classesHandle.get()); + AddOutputToWorkload(data, info, detectionScoresInfo, outputScoresHandle.get()); + AddOutputToWorkload(data, info, numDetectionInfo, numDetectionHandle.get()); + + std::unique_ptr workload = workloadFactory.CreateDetectionPostProcess(data, info); + + boxedHandle->Allocate(); + scoreshandle->Allocate(); + outputBoxesHandle->Allocate(); + classesHandle->Allocate(); + outputScoresHandle->Allocate(); + numDetectionHandle->Allocate(); + + CopyDataToITensorHandle(boxedHandle.get(), boxEncodings.origin()); + CopyDataToITensorHandle(scoreshandle.get(), scores.origin()); + + workload->Execute(); + + CopyDataFromITensorHandle(detectionBoxesResult.output.origin(), outputBoxesHandle.get()); + CopyDataFromITensorHandle(detectionClassesResult.output.origin(), classesHandle.get()); + CopyDataFromITensorHandle(detectionScoresResult.output.origin(), outputScoresHandle.get()); + CopyDataFromITensorHandle(numDetectionsResult.output.origin(), numDetectionHandle.get()); + + BOOST_TEST(CompareTensors(detectionBoxesResult.output, detectionBoxesResult.outputExpected)); + BOOST_TEST(CompareTensors(detectionClassesResult.output, detectionClassesResult.outputExpected)); + BOOST_TEST(CompareTensors(detectionScoresResult.output, detectionScoresResult.outputExpected)); + BOOST_TEST(CompareTensors(numDetectionsResult.output, numDetectionsResult.outputExpected)); +} + +inline void QuantizeData(uint8_t* quant, const float* dequant, const armnn::TensorInfo& info) +{ + for (size_t i = 0; i < info.GetNumElements(); i++) + { + quant[i] = armnn::Quantize(dequant[i], info.GetQuantizationScale(), info.GetQuantizationOffset()); + } +} + +template +void DetectionPostProcessRegularNmsFloatTest() +{ + armnn::TensorInfo boxEncodingsInfo({ 1, 6, 4 }, armnn::DataType::Float32); + armnn::TensorInfo scoresInfo({ 1, 6, 3}, armnn::DataType::Float32); + armnn::TensorInfo anchorsInfo({ 6, 4 }, armnn::DataType::Float32); + + std::vector boxEncodingsData({ + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f + }); + std::vector scoresData({ + 0.0f, 0.9f, 0.8f, + 0.0f, 0.75f, 0.72f, + 0.0f, 0.6f, 0.5f, + 0.0f, 0.93f, 0.95f, + 0.0f, 0.5f, 0.4f, + 0.0f, 0.3f, 0.2f + }); + std::vector anchorsData({ + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 10.5f, 1.0f, 1.0f, + 0.5f, 10.5f, 1.0f, 1.0f, + 0.5f, 100.5f, 1.0f, 1.0f + }); + + std::vector expectedDetectionBoxes({ + 0.0f, 10.0f, 1.0f, 11.0f, + 0.0f, 10.0f, 1.0f, 11.0f, + 0.0f, 0.0f, 0.0f, 0.0f + }); + std::vector expectedDetectionScores({ 0.95f, 0.93f, 0.0f }); + std::vector expectedDetectionClasses({ 1.0f, 0.0f, 0.0f }); + std::vector expectedNumDetections({ 2.0f }); + + return DetectionPostProcessImpl(boxEncodingsInfo, + scoresInfo, + anchorsInfo, + boxEncodingsData, + scoresData, + anchorsData, + expectedDetectionBoxes, + expectedDetectionClasses, + expectedDetectionScores, + expectedNumDetections, + true); +} + +template +void DetectionPostProcessRegularNmsUint8Test() +{ + armnn::TensorInfo boxEncodingsInfo({ 1, 6, 4 }, armnn::DataType::QuantisedAsymm8); + armnn::TensorInfo scoresInfo({ 1, 6, 3 }, armnn::DataType::QuantisedAsymm8); + armnn::TensorInfo anchorsInfo({ 6, 4 }, armnn::DataType::QuantisedAsymm8); + + boxEncodingsInfo.SetQuantizationScale(1.0f); + boxEncodingsInfo.SetQuantizationOffset(1); + scoresInfo.SetQuantizationScale(0.01f); + scoresInfo.SetQuantizationOffset(0); + anchorsInfo.SetQuantizationScale(0.5f); + anchorsInfo.SetQuantizationOffset(0); + + std::vector boxEncodings({ + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f + }); + std::vector scores({ + 0.0f, 0.9f, 0.8f, + 0.0f, 0.75f, 0.72f, + 0.0f, 0.6f, 0.5f, + 0.0f, 0.93f, 0.95f, + 0.0f, 0.5f, 0.4f, + 0.0f, 0.3f, 0.2f + }); + std::vector anchors({ + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 10.5f, 1.0f, 1.0f, + 0.5f, 10.5f, 1.0f, 1.0f, + 0.5f, 100.5f, 1.0f, 1.0f + }); + + std::vector boxEncodingsData(boxEncodings.size(), 0); + std::vector scoresData(scores.size(), 0); + std::vector anchorsData(anchors.size(), 0); + QuantizeData(boxEncodingsData.data(), boxEncodings.data(), boxEncodingsInfo); + QuantizeData(scoresData.data(), scores.data(), scoresInfo); + QuantizeData(anchorsData.data(), anchors.data(), anchorsInfo); + + std::vector expectedDetectionBoxes({ + 0.0f, 10.0f, 1.0f, 11.0f, + 0.0f, 10.0f, 1.0f, 11.0f, + 0.0f, 0.0f, 0.0f, 0.0f + }); + std::vector expectedDetectionScores({ 0.95f, 0.93f, 0.0f }); + std::vector expectedDetectionClasses({ 1.0f, 0.0f, 0.0f }); + std::vector expectedNumDetections({ 2.0f }); + + return DetectionPostProcessImpl(boxEncodingsInfo, + scoresInfo, + anchorsInfo, + boxEncodingsData, + scoresData, + anchorsData, + expectedDetectionBoxes, + expectedDetectionClasses, + expectedDetectionScores, + expectedNumDetections, + true); +} + +template +void DetectionPostProcessFastNmsFloatTest() +{ + armnn::TensorInfo boxEncodingsInfo({ 1, 6, 4 }, armnn::DataType::Float32); + armnn::TensorInfo scoresInfo({ 1, 6, 3}, armnn::DataType::Float32); + armnn::TensorInfo anchorsInfo({ 6, 4 }, armnn::DataType::Float32); + + std::vector boxEncodingsData({ + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f + }); + std::vector scoresData({ + 0.0f, 0.9f, 0.8f, + 0.0f, 0.75f, 0.72f, + 0.0f, 0.6f, 0.5f, + 0.0f, 0.93f, 0.95f, + 0.0f, 0.5f, 0.4f, + 0.0f, 0.3f, 0.2f + }); + std::vector anchorsData({ + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 10.5f, 1.0f, 1.0f, + 0.5f, 10.5f, 1.0f, 1.0f, + 0.5f, 100.5f, 1.0f, 1.0f + }); + + std::vector expectedDetectionBoxes({ + 0.0f, 10.0f, 1.0f, 11.0f, + 0.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 100.0f, 1.0f, 101.0f + }); + std::vector expectedDetectionScores({ 0.95f, 0.9f, 0.3f }); + std::vector expectedDetectionClasses({ 1.0f, 0.0f, 0.0f }); + std::vector expectedNumDetections({ 3.0f }); + + return DetectionPostProcessImpl(boxEncodingsInfo, + scoresInfo, + anchorsInfo, + boxEncodingsData, + scoresData, + anchorsData, + expectedDetectionBoxes, + expectedDetectionClasses, + expectedDetectionScores, + expectedNumDetections, + false); +} + +template +void DetectionPostProcessFastNmsUint8Test() +{ + armnn::TensorInfo boxEncodingsInfo({ 1, 6, 4 }, armnn::DataType::QuantisedAsymm8); + armnn::TensorInfo scoresInfo({ 1, 6, 3 }, armnn::DataType::QuantisedAsymm8); + armnn::TensorInfo anchorsInfo({ 6, 4 }, armnn::DataType::QuantisedAsymm8); + + boxEncodingsInfo.SetQuantizationScale(1.0f); + boxEncodingsInfo.SetQuantizationOffset(1); + scoresInfo.SetQuantizationScale(0.01f); + scoresInfo.SetQuantizationOffset(0); + anchorsInfo.SetQuantizationScale(0.5f); + anchorsInfo.SetQuantizationOffset(0); + + std::vector boxEncodings({ + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f + }); + std::vector scores({ + 0.0f, 0.9f, 0.8f, + 0.0f, 0.75f, 0.72f, + 0.0f, 0.6f, 0.5f, + 0.0f, 0.93f, 0.95f, + 0.0f, 0.5f, 0.4f, + 0.0f, 0.3f, 0.2f + }); + std::vector anchors({ + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 10.5f, 1.0f, 1.0f, + 0.5f, 10.5f, 1.0f, 1.0f, + 0.5f, 100.5f, 1.0f, 1.0f + }); + + std::vector boxEncodingsData(boxEncodings.size(), 0); + std::vector scoresData(scores.size(), 0); + std::vector anchorsData(anchors.size(), 0); + QuantizeData(boxEncodingsData.data(), boxEncodings.data(), boxEncodingsInfo); + QuantizeData(scoresData.data(), scores.data(), scoresInfo); + QuantizeData(anchorsData.data(), anchors.data(), anchorsInfo); + + std::vector expectedDetectionBoxes({ + 0.0f, 10.0f, 1.0f, 11.0f, + 0.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 100.0f, 1.0f, 101.0f + }); + std::vector expectedDetectionScores({ 0.95f, 0.9f, 0.3f }); + std::vector expectedDetectionClasses({ 1.0f, 0.0f, 0.0f }); + std::vector expectedNumDetections({ 3.0f }); + + return DetectionPostProcessImpl(boxEncodingsInfo, + scoresInfo, + anchorsInfo, + boxEncodingsData, + scoresData, + anchorsData, + expectedDetectionBoxes, + expectedDetectionClasses, + expectedDetectionScores, + expectedNumDetections, + false); +} diff --git a/src/backends/reference/test/RefLayerTests.cpp b/src/backends/reference/test/RefLayerTests.cpp index cfe02e6..b4ef85a 100644 --- a/src/backends/reference/test/RefLayerTests.cpp +++ b/src/backends/reference/test/RefLayerTests.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -500,4 +501,23 @@ ARMNN_AUTO_TEST_CASE(GatherMultiDimParamsUint8, GatherMultiDimParamsUint8Test) ARMNN_AUTO_TEST_CASE(GatherMultiDimParamsMultiDimIndicesFloat, GatherMultiDimParamsMultiDimIndicesFloatTest) ARMNN_AUTO_TEST_CASE(GatherMultiDimParamsMultiDimIndicesUint8, GatherMultiDimParamsMultiDimIndicesUint8Test) +// Detection PostProcess +BOOST_AUTO_TEST_CASE(DetectionPostProcessRegularNmsFloat) +{ + DetectionPostProcessRegularNmsFloatTest(); +} +BOOST_AUTO_TEST_CASE(DetectionPostProcessFastNmsFloat) +{ + DetectionPostProcessFastNmsFloatTest(); +} +BOOST_AUTO_TEST_CASE(DetectionPostProcessRegularNmsUint8) +{ + DetectionPostProcessRegularNmsUint8Test(); +} +BOOST_AUTO_TEST_CASE(DetectionPostProcessFastNmsUint8) +{ + DetectionPostProcessFastNmsUint8Test(); +} + + BOOST_AUTO_TEST_SUITE_END()