blob: 0f6d2c07dceb998e44af42daeb5f4b2bcf3fbb39 [file] [log] [blame]
Narumol Prangnawarat6d302bf2019-02-04 11:46:26 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Sadik Armagana097d2a2021-11-24 15:47:28 +00008#include <CommonTestUtils.hpp>
Matteo Martincighf02e6cd2019-05-17 12:15:30 +01009
Narumol Prangnawarat6d302bf2019-02-04 11:46:26 +000010#include <armnn/INetwork.hpp>
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +010011#include <ResolveType.hpp>
Narumol Prangnawarat6d302bf2019-02-04 11:46:26 +000012
Sadik Armagan1625efc2021-06-10 18:24:34 +010013#include <doctest/doctest.h>
14
Narumol Prangnawarat6d302bf2019-02-04 11:46:26 +000015namespace{
16
17template<typename T>
18armnn::INetworkPtr CreateDetectionPostProcessNetwork(const armnn::TensorInfo& boxEncodingsInfo,
19 const armnn::TensorInfo& scoresInfo,
20 const armnn::TensorInfo& anchorsInfo,
21 const std::vector<T>& anchors,
22 bool useRegularNms)
23{
24 armnn::TensorInfo detectionBoxesInfo({ 1, 3, 4 }, armnn::DataType::Float32);
25 armnn::TensorInfo detectionScoresInfo({ 1, 3 }, armnn::DataType::Float32);
26 armnn::TensorInfo detectionClassesInfo({ 1, 3 }, armnn::DataType::Float32);
27 armnn::TensorInfo numDetectionInfo({ 1 }, armnn::DataType::Float32);
28
29 armnn::DetectionPostProcessDescriptor desc;
30 desc.m_UseRegularNms = useRegularNms;
31 desc.m_MaxDetections = 3;
32 desc.m_MaxClassesPerDetection = 1;
33 desc.m_DetectionsPerClass =1;
34 desc.m_NmsScoreThreshold = 0.0;
35 desc.m_NmsIouThreshold = 0.5;
36 desc.m_NumClasses = 2;
37 desc.m_ScaleY = 10.0;
38 desc.m_ScaleX = 10.0;
39 desc.m_ScaleH = 5.0;
40 desc.m_ScaleW = 5.0;
41
42 armnn::INetworkPtr net(armnn::INetwork::Create());
43
44 armnn::IConnectableLayer* boxesLayer = net->AddInputLayer(0);
45 armnn::IConnectableLayer* scoresLayer = net->AddInputLayer(1);
46 armnn::ConstTensor anchorsTensor(anchorsInfo, anchors.data());
47 armnn::IConnectableLayer* detectionLayer = net->AddDetectionPostProcessLayer(desc, anchorsTensor,
48 "DetectionPostProcess");
49 armnn::IConnectableLayer* detectionBoxesLayer = net->AddOutputLayer(0, "detectionBoxes");
50 armnn::IConnectableLayer* detectionClassesLayer = net->AddOutputLayer(1, "detectionClasses");
51 armnn::IConnectableLayer* detectionScoresLayer = net->AddOutputLayer(2, "detectionScores");
52 armnn::IConnectableLayer* numDetectionLayer = net->AddOutputLayer(3, "numDetection");
53 Connect(boxesLayer, detectionLayer, boxEncodingsInfo, 0, 0);
54 Connect(scoresLayer, detectionLayer, scoresInfo, 0, 1);
55 Connect(detectionLayer, detectionBoxesLayer, detectionBoxesInfo, 0, 0);
56 Connect(detectionLayer, detectionClassesLayer, detectionClassesInfo, 1, 0);
57 Connect(detectionLayer, detectionScoresLayer, detectionScoresInfo, 2, 0);
58 Connect(detectionLayer, numDetectionLayer, numDetectionInfo, 3, 0);
59
60 return net;
61}
62
63template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
64void DetectionPostProcessEndToEnd(const std::vector<BackendId>& backends, bool useRegularNms,
65 const std::vector<T>& boxEncodings,
66 const std::vector<T>& scores,
67 const std::vector<T>& anchors,
68 const std::vector<float>& expectedDetectionBoxes,
69 const std::vector<float>& expectedDetectionClasses,
70 const std::vector<float>& expectedDetectionScores,
71 const std::vector<float>& expectedNumDetections,
72 float boxScale = 1.0f,
73 int32_t boxOffset = 0,
74 float scoreScale = 1.0f,
75 int32_t scoreOffset = 0,
76 float anchorScale = 1.0f,
77 int32_t anchorOffset = 0)
78{
79 armnn::TensorInfo boxEncodingsInfo({ 1, 6, 4 }, ArmnnType);
80 armnn::TensorInfo scoresInfo({ 1, 6, 3}, ArmnnType);
81 armnn::TensorInfo anchorsInfo({ 6, 4 }, ArmnnType);
82
83 boxEncodingsInfo.SetQuantizationScale(boxScale);
84 boxEncodingsInfo.SetQuantizationOffset(boxOffset);
Cathal Corbett5b8093c2021-10-22 11:12:07 +010085 boxEncodingsInfo.SetConstant(true);
Narumol Prangnawarat6d302bf2019-02-04 11:46:26 +000086 scoresInfo.SetQuantizationScale(scoreScale);
87 scoresInfo.SetQuantizationOffset(scoreOffset);
Cathal Corbett5b8093c2021-10-22 11:12:07 +010088 scoresInfo.SetConstant(true);
Narumol Prangnawarat6d302bf2019-02-04 11:46:26 +000089 anchorsInfo.SetQuantizationScale(anchorScale);
90 anchorsInfo.SetQuantizationOffset(anchorOffset);
Cathal Corbett5b8093c2021-10-22 11:12:07 +010091 anchorsInfo.SetConstant(true);
Narumol Prangnawarat6d302bf2019-02-04 11:46:26 +000092
93 // Builds up the structure of the network
94 armnn::INetworkPtr net = CreateDetectionPostProcessNetwork<T>(boxEncodingsInfo, scoresInfo,
95 anchorsInfo, anchors, useRegularNms);
96
Sadik Armagan1625efc2021-06-10 18:24:34 +010097 CHECK(net);
Narumol Prangnawarat6d302bf2019-02-04 11:46:26 +000098
99 std::map<int, std::vector<T>> inputTensorData = {{ 0, boxEncodings }, { 1, scores }};
100 std::map<int, std::vector<float>> expectedOutputData = {{ 0, expectedDetectionBoxes },
101 { 1, expectedDetectionClasses },
102 { 2, expectedDetectionScores },
103 { 3, expectedNumDetections }};
104
105 EndToEndLayerTestImpl<ArmnnType, armnn::DataType::Float32>(
106 move(net), inputTensorData, expectedOutputData, backends);
107}
108
109template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
110void DetectionPostProcessRegularNmsEndToEnd(const std::vector<BackendId>& backends,
111 const std::vector<T>& boxEncodings,
112 const std::vector<T>& scores,
113 const std::vector<T>& anchors,
114 float boxScale = 1.0f,
115 int32_t boxOffset = 0,
116 float scoreScale = 1.0f,
117 int32_t scoreOffset = 0,
118 float anchorScale = 1.0f,
119 int32_t anchorOffset = 0)
120{
121 std::vector<float> expectedDetectionBoxes({
122 0.0f, 10.0f, 1.0f, 11.0f,
123 0.0f, 10.0f, 1.0f, 11.0f,
124 0.0f, 0.0f, 0.0f, 0.0f
125 });
126 std::vector<float> expectedDetectionScores({ 0.95f, 0.93f, 0.0f });
127 std::vector<float> expectedDetectionClasses({ 1.0f, 0.0f, 0.0f });
128 std::vector<float> expectedNumDetections({ 2.0f });
129
130 DetectionPostProcessEndToEnd<ArmnnType>(backends, true, boxEncodings, scores, anchors,
131 expectedDetectionBoxes, expectedDetectionClasses,
132 expectedDetectionScores, expectedNumDetections,
133 boxScale, boxOffset, scoreScale, scoreOffset,
134 anchorScale, anchorOffset);
135
136};
137
138
139template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
140void DetectionPostProcessFastNmsEndToEnd(const std::vector<BackendId>& backends,
141 const std::vector<T>& boxEncodings,
142 const std::vector<T>& scores,
143 const std::vector<T>& anchors,
144 float boxScale = 1.0f,
145 int32_t boxOffset = 0,
146 float scoreScale = 1.0f,
147 int32_t scoreOffset = 0,
148 float anchorScale = 1.0f,
149 int32_t anchorOffset = 0)
150{
151 std::vector<float> expectedDetectionBoxes({
152 0.0f, 10.0f, 1.0f, 11.0f,
153 0.0f, 0.0f, 1.0f, 1.0f,
154 0.0f, 100.0f, 1.0f, 101.0f
155 });
156 std::vector<float> expectedDetectionScores({ 0.95f, 0.9f, 0.3f });
157 std::vector<float> expectedDetectionClasses({ 1.0f, 0.0f, 0.0f });
158 std::vector<float> expectedNumDetections({ 3.0f });
159
160 DetectionPostProcessEndToEnd<ArmnnType>(backends, false, boxEncodings, scores, anchors,
161 expectedDetectionBoxes, expectedDetectionClasses,
162 expectedDetectionScores, expectedNumDetections,
163 boxScale, boxOffset, scoreScale, scoreOffset,
164 anchorScale, anchorOffset);
165
166};
167
168} // anonymous namespace