Revise PriorBoxClustered Op (#6525)

* Move type prop tests to separate file, add cases with exceptions thrown

* Add visitor test, add step to pbc attributes

* SLT for CPU, adjust GPU and SSLT to serve the step attr

* Add backend test

* Fix variance issue, verify by SLT

* Formatting fix

* Add another backend testcase

* Add PriorBoxClustered to trusted ops list

* Add step attr description, remove obsolete comments from ref impl

* Test multiple step values in SLT
This commit is contained in:
Bartosz Lesniewski
2021-07-15 06:27:51 +02:00
committed by GitHub
parent 864b3ba62f
commit c14edd4134
14 changed files with 377 additions and 34 deletions

View File

@@ -37,6 +37,10 @@ namespace {
0.0f, 1.5f
};
const std::vector<float> step = {
0.0f
};
const std::vector<float> offsets = {
0.5f
};
@@ -58,6 +62,7 @@ namespace {
::testing::ValuesIn(clips),
::testing::ValuesIn(step_widths),
::testing::ValuesIn(step_heights),
::testing::ValuesIn(step),
::testing::ValuesIn(offsets),
::testing::ValuesIn(variances));

View File

@@ -0,0 +1,80 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <vector>
#include "single_layer_tests/prior_box_clustered.hpp"
#include "common_test_utils/test_constants.hpp"
using namespace LayerTestsDefinitions;
using namespace ngraph::helpers;
namespace {
// Common params
const std::vector<InferenceEngine::Precision> netPrecisions = {
InferenceEngine::Precision::FP32,
InferenceEngine::Precision::FP16
};
const std::vector<std::vector<float>> widths = {
{ 5.12f, 14.6f, 13.5f },
{ 7.0f, 8.2f, 33.39f }
};
const std::vector<std::vector<float>> heights = {
{ 15.12f, 15.6f, 23.5f },
{ 10.0f, 16.2f, 36.2f }
};
const std::vector<float> step_widths = {
0.0f, 2.0f
};
const std::vector<float> step_heights = {
0.0f, 1.5f
};
const std::vector<float> step = {
0.0f, 1.0f, 1.5f
};
const std::vector<float> offsets = {
0.5f
};
const std::vector<std::vector<float>> variances = {
{0.1f, 0.1f, 0.2f, 0.2f},
{0.2f},
{}
};
const std::vector<bool> clips = {
true, false
};
const auto layerSpeficParams = ::testing::Combine(
::testing::ValuesIn(widths),
::testing::ValuesIn(heights),
::testing::ValuesIn(clips),
::testing::ValuesIn(step_widths),
::testing::ValuesIn(step_heights),
::testing::ValuesIn(step),
::testing::ValuesIn(offsets),
::testing::ValuesIn(variances)
);
INSTANTIATE_TEST_SUITE_P(smoke_PriorBoxClustered_Basic, PriorBoxClusteredLayerTest,
::testing::Combine(
layerSpeficParams,
::testing::ValuesIn(netPrecisions),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t>({ 4, 4 })),
::testing::Values(std::vector<size_t>({ 50, 50 })),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
PriorBoxClusteredLayerTest::getTestCaseName
);
} // namespace

View File

@@ -34,6 +34,10 @@ const std::vector<float> step_heights = {
0.0f, 1.5f
};
const std::vector<float> step = {
0.0f, 1.0f, 1.5f
};
const std::vector<float> offsets = {
0.5f
};
@@ -52,6 +56,7 @@ const auto layerSpeficParams = ::testing::Combine(
::testing::ValuesIn(clips),
::testing::ValuesIn(step_widths),
::testing::ValuesIn(step_heights),
::testing::ValuesIn(step),
::testing::ValuesIn(offsets),
::testing::ValuesIn(variances)
);

View File

@@ -34,6 +34,7 @@ typedef std::tuple<
bool, // clip
float, // step_width
float, // step_height
float, // step
float, // offset
std::vector<float>> priorBoxClusteredSpecificParams;
@@ -63,6 +64,7 @@ protected:
std::vector<float> variances;
float step_width;
float step_height;
float step;
float offset;
bool clip;

View File

@@ -20,13 +20,14 @@ std::string PriorBoxClusteredLayerTest::getTestCaseName(const testing::TestParam
targetDevice) = obj.param;
std::vector<float> widths, heights, variances;
float step_width, step_height, offset;
float step_width, step_height, step, offset;
bool clip;
std::tie(widths,
heights,
clip,
step_width,
step_height,
step,
offset,
variances) = specParams;
@@ -49,9 +50,10 @@ std::string PriorBoxClusteredLayerTest::getTestCaseName(const testing::TestParam
result << CommonTestUtils::vec2str(variances) << separator;
result << "stepWidth=" << step_width << separator;
result << "stepHeight=" << step_height << separator;
result << "step=" << step << separator;
result << "offset=" << offset << separator;
result << "clip=" << std::boolalpha << clip << separator;
result << "trgDev=" << targetDevice;
result << "clip=" << std::boolalpha << clip << separator;
result << "trgDev=" << targetDevice;
return result.str();
}
@@ -66,6 +68,7 @@ void PriorBoxClusteredLayerTest::SetUp() {
clip,
step_width,
step_height,
step,
offset,
variances) = specParams;
@@ -78,6 +81,7 @@ void PriorBoxClusteredLayerTest::SetUp() {
attributes.clip = clip;
attributes.step_widths = step_width;
attributes.step_heights = step_height;
attributes.step = step;
attributes.offset = offset;
attributes.variances = variances;

View File

@@ -64,6 +64,7 @@ VERIFIED_OP_REFERENCES = [
'NonZero-3',
'NormalizeL2-1',
'PriorBox-1',
'PriorBoxClustered-1',
'Proposal-1',
'Proposal-4',
'PSROIPooling-1',

View File

@@ -17,6 +17,7 @@ namespace ngraph
// clip Clip output to [0,1]
// step_widths Distance between prior box centers
// step_heights Distance between prior box centers
// step Distance between prior box centers (when step_w = step_h)
// offset Box offset relative to top center of image
// variances Values to adjust prior boxes with
std::vector<float> widths;
@@ -24,6 +25,7 @@ namespace ngraph
bool clip = true;
float step_widths = 0.0f;
float step_heights = 0.0f;
float step = 0.0f;
float offset = 0.0f;
std::vector<float> variances;
};

View File

@@ -27,6 +27,7 @@ namespace ngraph
size_t num_priors_ = attrs.widths.size();
auto variances = attrs.variances;
NGRAPH_CHECK(variances.size() == 1 || variances.size() == 4 || variances.empty());
if (variances.empty())
variances.push_back(0.1f);
@@ -37,17 +38,8 @@ namespace ngraph
int64_t img_width = img[1];
int64_t img_height = img[0];
// TODO: Uncomment after PriorBoxClustered is aligned with the specification.
// int img_width = img_w_ == 0 ? img[1] : img_w_;
// int img_height = img_h_ == 0 ? img[0] : img_h_;
// float step_w = attrs.step_widths == 0 ? step_ : attrs.step_widths;
// float step_h = attrs.step_heights == 0 ? step_ :
// attrs.step_heights;
float step_w = attrs.step_widths;
float step_h = attrs.step_heights;
float step_w = attrs.step_widths == 0 ? attrs.step : attrs.step_widths;
float step_h = attrs.step_heights == 0 ? attrs.step : attrs.step_heights;
if (step_w == 0 && step_h == 0)
{
@@ -92,9 +84,21 @@ namespace ngraph
dst_data[idx + 2] = xmax;
dst_data[idx + 3] = ymax;
idx = get_idx(var_size);
for (size_t j = 0; j < var_size; j++)
dst_data[idx + j + out_shape[1]] = variances[j];
idx = get_idx(4);
// At this point we have either:
// 1. A single variance value (to be repeated 4 times for each prior)
// 2. 4 variance values
if (var_size == 1)
{
for (size_t j = 0; j < 4; j++)
dst_data[idx + j + out_shape[1]] = variances[0];
}
else
{
for (size_t j = 0; j < var_size; j++)
dst_data[idx + j + out_shape[1]] = variances[j];
}
}
}
}

View File

@@ -52,9 +52,9 @@ void op::PriorBoxClustered::validate_and_infer_types()
NODE_VALIDATION_CHECK(this,
m_attrs.widths.size() == m_attrs.heights.size(),
"Size of heights vector",
m_attrs.widths.size(),
" doesn't match size of widths vector ",
"Size of heights vector: ",
m_attrs.heights.size(),
" doesn't match size of widths vector: ",
m_attrs.widths.size());
set_input_is_relevant_to_shape(0);

View File

@@ -176,6 +176,7 @@ set(SRC
type_prop/prior_box.cpp
type_prop/proposal.cpp
type_prop/psroi_pooling.cpp
type_prop/prior_box_clustered.cpp
type_prop/range.cpp
type_prop/read_value.cpp
type_prop/reduce_l1.cpp
@@ -277,6 +278,7 @@ set(SRC
visitors/op/pad.cpp
visitors/op/parameter.cpp
visitors/op/prior_box.cpp
visitors/op/prior_box_clustered.cpp
visitors/op/proposal.cpp
visitors/op/psroi_pooling.cpp
visitors/op/reduce_l1.cpp
@@ -456,6 +458,7 @@ set(MULTI_TEST_SRC
backend/parameter_as_output.in.cpp
backend/power.in.cpp
backend/prelu.in.cpp
backend/prior_box_clustered.in.cpp
backend/prior_box.in.cpp
backend/proposal.in.cpp
backend/psroi_pooling.in.cpp

View File

@@ -0,0 +1,71 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "ngraph/op/prior_box_clustered.hpp"
#include "util/engine/test_engines.hpp"
#include "util/test_case.hpp"
#include "util/test_control.hpp"
using namespace std;
using namespace ngraph;
static string s_manifest = "${MANIFEST}";
using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME});
NGRAPH_TEST(${BACKEND_NAME}, prior_box_clustered)
{
op::PriorBoxClusteredAttrs attrs;
attrs.widths = {3.0f};
attrs.heights = {3.0f};
attrs.clip = true;
Shape layer_shape_shape{2};
Shape image_shape_shape{2};
vector<int64_t> layer_shape{2, 2};
vector<int64_t> image_shape{10, 10};
auto LS = op::Constant::create(element::i64, layer_shape_shape, layer_shape);
auto IS = op::Constant::create(element::i64, image_shape_shape, image_shape);
auto f = make_shared<Function>(make_shared<op::PriorBoxClustered>(LS, IS, attrs), ParameterVector{});
const auto exp_shape = Shape{2, 16};
vector<float> out{0, 0, 0.15f, 0.15f, 0.34999f, 0, 0.64999f, 0.15f,
0, 0.34999f, 0.15f, 0.64999f, 0.34999f, 0.34999f, 0.64999f, 0.64999f,
0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f,
0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f};
auto test_case = test::TestCase<TestEngine>(f);
test_case.add_expected_output<float>(exp_shape, out);
test_case.run_with_tolerance_as_fp(1.0e-5f);
}
NGRAPH_TEST(${BACKEND_NAME}, prior_box_clustered_non_default_variances)
{
op::PriorBoxClusteredAttrs attrs;
attrs.widths = {3.0f};
attrs.heights = {3.0f};
attrs.clip = true;
attrs.variances = {0.1f, 0.2f, 0.3f, 0.4f};
Shape layer_shape_shape{2};
Shape image_shape_shape{2};
vector<int64_t> layer_shape{2, 2};
vector<int64_t> image_shape{10, 10};
auto LS = op::Constant::create(element::i64, layer_shape_shape, layer_shape);
auto IS = op::Constant::create(element::i64, image_shape_shape, image_shape);
auto f = make_shared<Function>(make_shared<op::PriorBoxClustered>(LS, IS, attrs), ParameterVector{});
const auto exp_shape = Shape{2, 16};
vector<float> out{0, 0, 0.15f, 0.15f, 0.34999f, 0, 0.64999f, 0.15f,
0, 0.34999f, 0.15f, 0.64999f, 0.34999f, 0.34999f, 0.64999f, 0.64999f,
0.1f, 0.2f, 0.3f, 0.4f, 0.1f, 0.2f, 0.3f, 0.4f,
0.1f, 0.2f, 0.3f, 0.4f, 0.1f, 0.2f, 0.3f, 0.4f};
auto test_case = test::TestCase<TestEngine>(f);
test_case.add_expected_output<float>(exp_shape, out);
test_case.run_with_tolerance_as_fp(1.0e-5f);
}

View File

@@ -0,0 +1,133 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "gtest/gtest.h"
#include "util/type_prop.hpp"
#include "ngraph/ngraph.hpp"
#include "ngraph/op/prior_box_clustered.hpp"
using namespace ngraph;
TEST(type_prop, prior_box_clustered)
{
op::PriorBoxClusteredAttrs attrs;
attrs.widths = {4.0f, 2.0f, 3.2f};
attrs.heights = {1.0f, 2.0f, 1.1f};
auto layer_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {19, 19});
auto image_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {300, 300});
auto pbc = std::make_shared<op::PriorBoxClustered>(layer_shape, image_shape, attrs);
// Output shape - 4 * 19 * 19 * 3 (attrs.widths.size())
ASSERT_EQ(pbc->get_shape(), (Shape{2, 4332}));
}
TEST(type_prop, prior_box_clustered_float_layer_shape)
{
op::PriorBoxClusteredAttrs attrs;
attrs.widths = {4.0f, 2.0f, 3.2f};
attrs.heights = {1.0f, 2.0f, 1.1f};
auto layer_shape = op::Constant::create<float>(element::f32, Shape{2}, {19, 19});
auto image_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {300, 300});
try
{
auto pbc = std::make_shared<op::PriorBoxClustered>(layer_shape, image_shape, attrs);
// Should have thrown, so fail if it didn't
FAIL() << "Incorrect prior_box_clustered value type exception not handled";
}
catch (const NodeValidationFailure& error)
{
EXPECT_HAS_SUBSTRING(
error.what(),
std::string("layer shape input must be an integral number"));
}
catch (...)
{
FAIL() << "Deduced type check failed for unexpected reason";
}
}
TEST(type_prop, prior_box_clustered_float_image_shape)
{
op::PriorBoxClusteredAttrs attrs;
attrs.widths = {4.0f, 2.0f, 3.2f};
attrs.heights = {1.0f, 2.0f, 1.1f};
auto layer_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {19, 19});
auto image_shape = op::Constant::create<float>(element::f32, Shape{2}, {300, 300});
try
{
auto pbc = std::make_shared<op::PriorBoxClustered>(layer_shape, image_shape, attrs);
// Should have thrown, so fail if it didn't
FAIL() << "Incorrect prior_box_clustered value type exception not handled";
}
catch (const NodeValidationFailure& error)
{
EXPECT_HAS_SUBSTRING(
error.what(),
std::string("image shape input must be an integral number"));
}
catch (...)
{
FAIL() << "Deduced type check failed for unexpected reason";
}
}
TEST(type_prop, prior_box_clustered_widths_heights_different)
{
op::PriorBoxClusteredAttrs attrs;
attrs.widths = {4.0f, 2.0f, 3.2f};
attrs.heights = {1.0f, 2.0f};
auto layer_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {19, 19});
auto image_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {300, 300});
try
{
auto pbc = std::make_shared<op::PriorBoxClustered>(layer_shape, image_shape, attrs);
// Should have thrown, so fail if it didn't
FAIL() << "Incorrect prior_box_clustered value type exception not handled";
}
catch (const NodeValidationFailure& error)
{
EXPECT_HAS_SUBSTRING(
error.what(),
std::string("Size of heights vector:"));
}
catch (...)
{
FAIL() << "Deduced type check failed for unexpected reason";
}
}
TEST(type_prop, prior_box_clustered_not_rank_2)
{
op::PriorBoxClusteredAttrs attrs;
attrs.widths = {4.0f, 2.0f, 3.2f};
attrs.heights = {1.0f, 2.0f, 1.1f};
auto layer_shape = op::Constant::create<int64_t>(element::i64, Shape{3}, {19, 19, 19});
auto image_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {300, 300});
try
{
auto pbc = std::make_shared<op::PriorBoxClustered>(layer_shape, image_shape, attrs);
// Should have thrown, so fail if it didn't
FAIL() << "Incorrect prior_box_clustered value type exception not handled";
}
catch (const NodeValidationFailure& error)
{
EXPECT_HAS_SUBSTRING(
error.what(),
std::string("Layer shape must have rank 2"));
}
catch (...)
{
FAIL() << "Deduced type check failed for unexpected reason";
}
}

View File

@@ -7,7 +7,6 @@
#include "ngraph/ngraph.hpp"
#include "ngraph/op/ctc_greedy_decoder.hpp"
#include "ngraph/op/interpolate.hpp"
#include "ngraph/op/prior_box_clustered.hpp"
#include "ngraph/op/region_yolo.hpp"
#include "ngraph/op/reorg_yolo.hpp"
#include "ngraph/op/roi_pooling.hpp"
@@ -45,19 +44,6 @@ TEST(type_prop_layers, interpolate)
.same_scheme(PartialShape{2, 2, Dimension::dynamic(), Dimension::dynamic()}));
}
TEST(type_prop_layers, prior_box_clustered)
{
op::PriorBoxClusteredAttrs attrs;
attrs.widths = {4.0f, 2.0f, 3.2f};
attrs.heights = {1.0f, 2.0f, 1.1f};
auto layer_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {19, 19});
auto image_shape = op::Constant::create<int64_t>(element::i64, Shape{2}, {300, 300});
auto pbc = make_shared<op::PriorBoxClustered>(layer_shape, image_shape, attrs);
// Output shape - 4 * 19 * 19 * 3 (attrs.widths.size())
ASSERT_EQ(pbc->get_shape(), (Shape{2, 4332}));
}
TEST(type_prop_layers, region_yolo1)
{
auto inputs = make_shared<op::Parameter>(element::f32, Shape{1, 125, 13, 13});

View File

@@ -0,0 +1,47 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "util/visitor.hpp"
#include "ngraph/opsets/opset1.hpp"
using namespace std;
using namespace ngraph;
using ngraph::test::NodeBuilder;
using ngraph::test::ValueMap;
TEST(attributes, prior_box_clustered_op)
{
NodeBuilder::get_ops().register_factory<opset1::PriorBoxClustered>();
const auto layer_shape = make_shared<op::Parameter>(element::i64, Shape{32, 32});
const auto image_shape = make_shared<op::Parameter>(element::i64, Shape{300, 300});
op::PriorBoxClusteredAttrs attrs;
attrs.heights = {2.0f, 3.0f};
attrs.widths = {2.0f, 3.0f};
attrs.clip = true;
attrs.step_widths = 0.0f;
attrs.step_heights = 0.0f;
attrs.step = 0.0f;
attrs.offset = 0.0f;
attrs.variances = {0.1f};
auto pbc = make_shared<opset1::PriorBoxClustered>(layer_shape, image_shape, attrs);
NodeBuilder builder(pbc);
auto g_pbc = as_type_ptr<opset1::PriorBoxClustered>(builder.create());
const auto pbc_attrs = pbc->get_attrs();
const auto g_pbc_attrs = g_pbc->get_attrs();
const auto expected_attr_count = 8;
EXPECT_EQ(builder.get_value_map_size(), expected_attr_count);
EXPECT_EQ(g_pbc_attrs.heights, pbc_attrs.heights);
EXPECT_EQ(g_pbc_attrs.widths, pbc_attrs.widths);
EXPECT_EQ(g_pbc_attrs.clip, pbc_attrs.clip);
EXPECT_EQ(g_pbc_attrs.step_widths, pbc_attrs.step_widths);
EXPECT_EQ(g_pbc_attrs.step_heights, pbc_attrs.step_heights);
EXPECT_EQ(g_pbc_attrs.offset, pbc_attrs.offset);
EXPECT_EQ(g_pbc_attrs.variances, pbc_attrs.variances);
}