DefromablePSROIPooling shape inference update (#4897)

* Test dynamic interval batch dim propagation

* Fix interval batch dim propagation

* Additional shape and attributes checks

* Update type_prop tests

* Comment update

* Update ngraph_reader test

* Revert group_size dims check

* Update class docs

* Fix mode init value

* Add new ngraph reader test with correct pooling mode

* Comments update

* Update error messages

* Update rank checks to use compatible

* Add newline at EOF

* Update ngraphReader test names
This commit is contained in:
Katarzyna Mitrus 2021-04-03 19:19:28 +02:00 committed by GitHub
parent 4120344d11
commit 69cd2deb2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 298 additions and 69 deletions

View File

@ -1582,7 +1582,7 @@ InferenceEngine::details::CNNLayerCreator::CNNLayerCreator(const std::shared_ptr
auto res = std::make_shared<InferenceEngine::CNNLayer>(attrs);
res->params = params;
res->params["no_trans"] = node->get_input_size() == 2 ? "1" : "0";
// temporary workaround due to incorrect usage of group_size in the nGraph operation for the DeformablePSROIPooling
// v1::DeformablePRSOIPooling treats group_size attribute as pooled sizes
res->params["pooled_height"] = params.at("group_size");
res->params["pooled_width"] = params.at("group_size");
return res;

View File

@ -5,7 +5,7 @@
#include <string>
#include "ngraph_reader_tests.hpp"
TEST_F(NGraphReaderTests, ReadDeformablePSROIPoolingNetwork) {
TEST_F(NGraphReaderTests, ReadDeformablePSROIPoolingNetwork_incorrect_mode) {
std::string model = R"V0G0N(
<net name="DeformablePSROIPooling" version="10">
<layers>
@ -29,7 +29,7 @@ TEST_F(NGraphReaderTests, ReadDeformablePSROIPoolingNetwork) {
</port>
</output>
</layer>
<layer id="2" name="DeformablePSROIPooling" type="DeformablePSROIPooling" type="PSROIPooling" version="opset2">
<layer id="2" name="DeformablePSROIPooling" type="DeformablePSROIPooling" version="opset2">
<data group_size="6" mode="bilinear" no_trans="1" output_dim="360" spatial_bins_x="3" spatial_bins_y="3" spatial_scale="1"/>
<input>
<port id="0">
@ -121,5 +121,124 @@ TEST_F(NGraphReaderTests, ReadDeformablePSROIPoolingNetwork) {
</edges>
</net>
)V0G0N";
compareIRs(model, modelV7, 117600);
}
compareIRs(model, modelV7);
}
TEST_F(NGraphReaderTests, ReadDeformablePSROIPoolingNetwork) {
std::string model = R"V0G0N(
<net name="DeformablePSROIPooling" version="10">
<layers>
<layer id="0" name="port_0" type="Parameter" version="opset1">
<data shape="1,3240,38,38" element_type="f32"/>
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>3240</dim>
<dim>38</dim>
<dim>38</dim>
</port>
</output>
</layer>
<layer id="1" name="port_1" type="Parameter" version="opset1">
<data shape="100,5" element_type="f32"/>
<output>
<port id="0" precision="FP32">
<dim>100</dim>
<dim>5</dim>
</port>
</output>
</layer>
<layer id="2" name="DeformablePSROIPooling" type="DeformablePSROIPooling" version="opset1">
<data group_size="3" mode="bilinear_deformable" no_trans="1" part_size="1" pooled_height="3" pooled_width="3" trans_std="1" output_dim="360" spatial_bins_x="3" spatial_bins_y="3" spatial_scale="1"/>
<input>
<port id="0">
<dim>1</dim>
<dim>3240</dim>
<dim>38</dim>
<dim>38</dim>
</port>
<port id="1">
<dim>100</dim>
<dim>5</dim>
</port>
</input>
<output>
<port id="2" precision="FP32">
<dim>100</dim>
<dim>360</dim>
<dim>3</dim>
<dim>3</dim>
</port>
</output>
</layer>
<layer id="3" name="sink_port_0" type="Result" version="opset1">
<input>
<port id="0">
<dim>100</dim>
<dim>360</dim>
<dim>3</dim>
<dim>3</dim>
</port>
</input>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="2" to-port="0"/>
<edge from-layer="1" from-port="0" to-layer="2" to-port="1"/>
<edge from-layer="2" from-port="2" to-layer="3" to-port="0"/>
</edges>
</net>
)V0G0N";
std::string modelV7 = R"V0G0N(
<net name="DeformablePSROIPooling" version="7">
<layers>
<layer id="0" name="port_0" type="Input" version="opset1">
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>3240</dim>
<dim>38</dim>
<dim>38</dim>
</port>
</output>
</layer>
<layer id="1" name="port_1" type="Input" version="opset1">
<output>
<port id="0" precision="FP32">
<dim>100</dim>
<dim>5</dim>
</port>
</output>
</layer>
<layer id="2" name="DeformablePSROIPooling" type="PSROIPooling" version="opset2">
<data group_size="3" mode="bilinear_deformable" no_trans="1" part_size="1" pooled_height="3" pooled_width="3" trans_std="1" output_dim="360" spatial_bins_x="3" spatial_bins_y="3" spatial_scale="1"/>
<input>
<port id="0">
<dim>1</dim>
<dim>3240</dim>
<dim>38</dim>
<dim>38</dim>
</port>
<port id="1">
<dim>100</dim>
<dim>5</dim>
</port>
</input>
<output>
<port id="2" precision="FP32">
<dim>100</dim>
<dim>360</dim>
<dim>3</dim>
<dim>3</dim>
</port>
</output>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="2" to-port="0"/>
<edge from-layer="1" from-port="0" to-layer="2" to-port="1"/>
</edges>
</net>
)V0G0N";
compareIRs(model, modelV7);
}

View File

@ -20,20 +20,21 @@ namespace ngraph
DeformablePSROIPooling() = default;
/// \brief Constructs a DeformablePSROIPooling operation
///
/// \param input Input tensor with feature maps
/// \param coords Input tensor describing box consisting
/// of five element tuples
/// \param offsets Input blob with transformation values
/// \param input Input tensor with position sensitive score maps
/// \param coords Input tensor with list of five element tuples
/// describing ROI coordinates
/// \param offsets Input tensor with transformation values
/// \param output_dim Pooled output channel number
/// \param group_size Number of groups to encode position-sensitive score maps
/// \param group_size Number of horizontal bins per row to divide ROI area,
/// it defines output width and height
/// \param spatial_scale Multiplicative spatial scale factor to translate ROI
/// coordinates from their input scale to the scale used when
/// pooling
/// \param mode Specifies mode for pooling.
/// \param spatial_bins_x Specifies numbers of bins to divide the input feature
/// maps over width
/// \param spatial_bins_y Specifies numbers of bins to divide the input feature
/// maps over height
/// \param spatial_bins_x Specifies numbers of bins to divide ROI single
/// bin over width
/// \param spatial_bins_y Specifies numbers of bins to divide ROI single
/// bin over height
/// \param no_trans The flag that specifies whenever third input exists
/// and contains transformation (offset) values
/// \param trans_std The value that all transformation (offset) values are
@ -84,7 +85,7 @@ namespace ngraph
int64_t m_output_dim;
float m_spatial_scale;
int64_t m_group_size = 1;
std::string m_mode = "bilinear";
std::string m_mode = "bilinear_deformable";
int64_t m_spatial_bins_x = 1;
int64_t m_spatial_bins_y = 1;
float m_trans_std = 1.f;

View File

@ -80,32 +80,34 @@ void op::v1::DeformablePSROIPooling::validate_and_infer_types()
const auto& box_coords_pshape = get_input_partial_shape(1);
NODE_VALIDATION_CHECK(this,
input_pshape.rank().is_dynamic() || input_pshape.rank().get_length() == 4,
"Feature map input rank must equal to 4 (input rank: ",
input_pshape.rank().get_length(),
input_pshape.rank().compatible(4),
"First input rank must be compatible with 4 (input rank: ",
input_pshape.rank(),
")");
NODE_VALIDATION_CHECK(this,
box_coords_pshape.rank().is_dynamic() ||
box_coords_pshape.rank().get_length() == 2,
"Box coordinates input rank must equal to 2 (input rank: ",
box_coords_pshape.rank().get_length(),
box_coords_pshape.rank().compatible(2),
"Second input rank must be compatible with 2 (input rank: ",
box_coords_pshape.rank(),
")");
if (get_input_size() == 3) // offsets input is provided
{
const auto& offsets_pshape = get_input_partial_shape(2);
NODE_VALIDATION_CHECK(this,
offsets_pshape.rank().is_dynamic() ||
offsets_pshape.rank().get_length() == 4,
"Offsets input rank must equal to 4 (input rank: ",
offsets_pshape.rank().get_length(),
offsets_pshape.rank().compatible(4),
"Third input rank must be compatible with 4 (input rank: ",
offsets_pshape.rank(),
")");
}
NODE_VALIDATION_CHECK(
this, m_group_size > 0, "Value of `group_size` attribute has to be greater than 0 ");
int64_t output_rank = 4;
std::vector<Dimension> output_dim_vec(output_rank, Dimension::dynamic());
if (box_coords_pshape[0].is_static())
if (box_coords_pshape.rank().is_static())
{
output_dim_vec[0] = box_coords_pshape.to_shape()[0];
output_dim_vec[0] = box_coords_pshape[0]; // Number of ROIs
}
output_dim_vec[1] = m_output_dim;
for (int i = 2; i < output_rank; ++i)

View File

@ -9,55 +9,154 @@
using namespace std;
using namespace ngraph;
TEST(type_prop, deformable_psroi_pooling_output_shape)
TEST(type_prop, deformable_psroi_pooling_no_offsets_group_size_3)
{
auto input = make_shared<op::Parameter>(element::f32, Shape{1, 1024, 63, 38});
auto coords = make_shared<op::Parameter>(element::f32, Shape{300, 5});
auto offsets = make_shared<op::Parameter>(element::f32, Shape{1, 2, 3, 4});
const int64_t output_dim = 882;
const float spatial_scale = 0.0625;
const int64_t output_dim = 882;
const int64_t group_size = 3;
auto def_psroi_pool = make_shared<op::v1::DeformablePSROIPooling>(
input, coords, offsets, output_dim, spatial_scale, group_size);
const auto rois_dim = 300;
ASSERT_EQ(def_psroi_pool->get_output_shape(0), (Shape{300, 882, 3, 3}));
auto input_data = make_shared<op::Parameter>(element::f32, PartialShape{2, 7938, 63, 38});
auto input_coords = make_shared<op::Parameter>(element::f32, PartialShape{rois_dim, 5});
auto def_psroi_pool = make_shared<op::v1::DeformablePSROIPooling>(
input_data, input_coords, output_dim, spatial_scale, group_size);
const PartialShape expected_output{rois_dim, output_dim, group_size, group_size};
ASSERT_EQ(def_psroi_pool->get_output_partial_shape(0), expected_output);
}
TEST(type_prop, deformable_psroi_pooling_output_shape_2)
TEST(type_prop, deformable_psroi_pooling_group_size_3)
{
auto input = make_shared<op::Parameter>(element::f32, Shape{1, 7938, 38, 38});
auto coords = make_shared<op::Parameter>(element::f32, Shape{300, 5});
auto offsets = make_shared<op::Parameter>(element::f32, Shape{1, 2, 3, 4});
const int64_t output_dim = 162;
const float spatial_scale = 0.0625;
const int64_t group_size = 7;
const int64_t output_dim = 882;
const int64_t group_size = 3;
const int64_t part_size = 3;
const double spatial_bins = 4;
const auto rois_dim = 300;
auto input_data = make_shared<op::Parameter>(element::f32, PartialShape{2, 7938, 63, 38});
auto input_coords = make_shared<op::Parameter>(element::f32, PartialShape{rois_dim, 5});
auto input_offsets = make_shared<op::Parameter>(element::f32, PartialShape{rois_dim, 2, part_size, part_size});
auto def_psroi_pool = make_shared<op::v1::DeformablePSROIPooling>(
input, coords, offsets, output_dim, spatial_scale, group_size);
input_data, input_coords, input_offsets, output_dim, spatial_scale, group_size, "bilinear_deformable", spatial_bins, spatial_bins, 0.1, part_size);
ASSERT_EQ(def_psroi_pool->get_output_shape(0), (Shape{300, 162, 7, 7}));
const PartialShape expected_output{rois_dim, output_dim, group_size, group_size};
ASSERT_EQ(def_psroi_pool->get_output_partial_shape(0), expected_output);
}
TEST(type_prop, deformable_psroi_pooling_invalid_input_rank)
TEST(type_prop, deformable_psroi_pooling_group_size_7)
{
auto input = make_shared<op::Parameter>(element::f32, Shape{1, 2, 3});
auto coords = make_shared<op::Parameter>(element::f32, Shape{1, 2});
auto offsets = make_shared<op::Parameter>(element::f32, Shape{1, 2, 3, 4});
const int64_t output_dim = 4;
const float spatial_scale = 0.9;
const float spatial_scale = 0.0625;
const int64_t output_dim = 162;
const int64_t group_size = 7;
const int64_t part_size = 7;
const double spatial_bins = 4;
const auto rois_dim = 300;
auto input_data = make_shared<op::Parameter>(element::f32, PartialShape{2, 7938, 63, 38});
auto input_coords = make_shared<op::Parameter>(element::f32, PartialShape{rois_dim, 5});
auto input_offsets = make_shared<op::Parameter>(element::f32, PartialShape{rois_dim, 2, part_size, part_size});
auto def_psroi_pool = make_shared<op::v1::DeformablePSROIPooling>(
input_data, input_coords, input_offsets, output_dim, spatial_scale, group_size, "bilinear_deformable", spatial_bins, spatial_bins, 0.1, part_size);
const PartialShape expected_output{rois_dim, output_dim, group_size, group_size};
ASSERT_EQ(def_psroi_pool->get_output_partial_shape(0), expected_output);
}
TEST(type_prop, deformable_psroi_pooling_dynamic_rois)
{
const float spatial_scale = 0.0625;
const int64_t output_dim = 882;
const int64_t group_size = 3;
const auto rois_dim = Dimension(100, 200);
auto input_data = make_shared<op::Parameter>(element::f32, PartialShape{2, 7938, 63, 38});
auto input_coords = make_shared<op::Parameter>(element::f32, PartialShape{rois_dim, 5});
auto def_psroi_pool = make_shared<op::v1::DeformablePSROIPooling>(
input_data, input_coords, output_dim, spatial_scale, group_size);
const PartialShape expected_output{rois_dim, output_dim, group_size, group_size};
ASSERT_EQ(def_psroi_pool->get_output_partial_shape(0), expected_output);
}
TEST(type_prop, deformable_psroi_pooling_fully_dynamic)
{
const float spatial_scale = 0.0625;
const int64_t output_dim = 882;
const int64_t group_size = 3;
const auto rois_dim = Dimension::dynamic();
auto input_data = make_shared<op::Parameter>(element::f32, PartialShape::dynamic());
auto input_coords = make_shared<op::Parameter>(element::f32, PartialShape::dynamic());
auto def_psroi_pool = make_shared<op::v1::DeformablePSROIPooling>(
input_data, input_coords, output_dim, spatial_scale, group_size);
const PartialShape expected_output{rois_dim, output_dim, group_size, group_size};
ASSERT_EQ(def_psroi_pool->get_output_partial_shape(0), expected_output);
}
TEST(type_prop, deformable_psroi_pooling_invalid_group_size)
{
const float spatial_scale = 0.0625;
const int64_t output_dim = 882;
const auto rois_dim = 300;
try
{
const int64_t group_size = 0;
auto input_data = make_shared<op::Parameter>(element::f32, PartialShape{2, 7938, 63, 38});
auto input_coords = make_shared<op::Parameter>(element::f32, PartialShape{rois_dim, 5});
auto def_psroi_pool = make_shared<op::v1::DeformablePSROIPooling>(
input, coords, offsets, output_dim, spatial_scale, group_size);
input_data, input_coords, output_dim, spatial_scale, group_size);
FAIL() << "Invalid group_size not detected";
}
catch (const NodeValidationFailure& error)
{
EXPECT_HAS_SUBSTRING(error.what(), std::string("Value of `group_size` attribute has to be greater than 0"));
}
catch (...)
{
FAIL() << "Unknown exception was thrown";
}
}
TEST(type_prop, deformable_psroi_pooling_invalid_data_input_rank)
{
const float spatial_scale = 0.0625;
const int64_t output_dim = 162;
const int64_t group_size = 7;
const int64_t part_size = 7;
const double spatial_bins = 4;
const auto rois_dim = 300;
auto input_data = make_shared<op::Parameter>(element::f32, PartialShape{7938, 63, 38});
auto input_coords = make_shared<op::Parameter>(element::f32, PartialShape{rois_dim, 5});
auto input_offsets = make_shared<op::Parameter>(element::f32, PartialShape{rois_dim, 2, part_size, part_size});
try
{
auto def_psroi_pool = make_shared<op::v1::DeformablePSROIPooling>(
input_data, input_coords, input_offsets, output_dim, spatial_scale, group_size, "bilinear_deformable", spatial_bins, spatial_bins, 0.1, part_size);
// Should have thrown, so fail if it didn't
FAIL() << "Ivalid feature map input rank not detected";
FAIL() << "Invalid first input rank not detected";
}
catch (const NodeValidationFailure& error)
{
EXPECT_HAS_SUBSTRING(error.what(),
std::string("Feature map input rank must equal to 4 (input rank: 3)"));
std::string("First input rank must be compatible with 4 (input rank: 3)"));
}
catch (...)
{
@ -67,24 +166,26 @@ TEST(type_prop, deformable_psroi_pooling_invalid_input_rank)
TEST(type_prop, deformable_psroi_pooling_invalid_box_coordinates_rank)
{
auto input = make_shared<op::Parameter>(element::f32, Shape{1, 2, 3, 4});
auto coords = make_shared<op::Parameter>(element::f32, Shape{1, 2, 3});
auto offsets = make_shared<op::Parameter>(element::f32, Shape{1, 2, 3, 4});
const int64_t output_dim = 4;
const float spatial_scale = 0.9;
const int64_t group_size = 7;
const auto rois_dim = 300;
auto input_data = make_shared<op::Parameter>(element::f32, PartialShape{2, 7938, 63, 38});
auto input_coords = make_shared<op::Parameter>(element::f32, PartialShape{2, rois_dim, 5});
try
{
auto def_psroi_pool = make_shared<op::v1::DeformablePSROIPooling>(
input, coords, offsets, output_dim, spatial_scale, group_size);
input_data, input_coords, output_dim, spatial_scale, group_size);
// Should have thrown, so fail if it didn't
FAIL() << "Ivalid box coordinates input rank not detected";
FAIL() << "Invalid second input rank not detected";
}
catch (const NodeValidationFailure& error)
{
EXPECT_HAS_SUBSTRING(
error.what(),
std::string("Box coordinates input rank must equal to 2 (input rank: 3)"));
std::string("Second input rank must be compatible with 2 (input rank: 3)"));
}
catch (...)
{
@ -94,23 +195,29 @@ TEST(type_prop, deformable_psroi_pooling_invalid_box_coordinates_rank)
TEST(type_prop, deformable_psroi_pooling_invalid_offstes_rank)
{
auto input = make_shared<op::Parameter>(element::f32, Shape{1, 2, 3, 4});
auto coords = make_shared<op::Parameter>(element::f32, Shape{1, 2});
auto offsets = make_shared<op::Parameter>(element::f32, Shape{1, 2, 3, 4, 5});
const int64_t output_dim = 4;
const float spatial_scale = 0.9;
const float spatial_scale = 0.0625;
const int64_t output_dim = 162;
const int64_t group_size = 7;
const int64_t part_size = 7;
const double spatial_bins = 4;
const auto rois_dim = 300;
auto input_data = make_shared<op::Parameter>(element::f32, PartialShape{2, 7938, 63, 38});
auto input_coords = make_shared<op::Parameter>(element::f32, PartialShape{rois_dim, 5});
auto input_offsets = make_shared<op::Parameter>(element::f32, PartialShape{2, rois_dim, 2, part_size, part_size});
try
{
auto def_psroi_pool = make_shared<op::v1::DeformablePSROIPooling>(
input, coords, offsets, output_dim, spatial_scale, group_size);
// Should have thrown, so fail if it didn't
FAIL() << "Offsets input rank not detected";
auto def_psroi_pool = make_shared<op::v1::DeformablePSROIPooling>(
input_data, input_coords, input_offsets, output_dim, spatial_scale, group_size, "bilinear_deformable", spatial_bins, spatial_bins, 0.1, part_size);
// Should have thrown, so fail if it didn't
FAIL() << "Invalid third input rank not detected";
}
catch (const NodeValidationFailure& error)
{
EXPECT_HAS_SUBSTRING(error.what(),
std::string("Offsets input rank must equal to 4 (input rank: 5)"));
std::string("Third input rank must be compatible with 4 (input rank: 5)"));
}
catch (...)
{