diff --git a/inference-engine/src/legacy_api/src/convert_function_to_cnn_network.cpp b/inference-engine/src/legacy_api/src/convert_function_to_cnn_network.cpp index c40c76f69c3..0b66531044a 100644 --- a/inference-engine/src/legacy_api/src/convert_function_to_cnn_network.cpp +++ b/inference-engine/src/legacy_api/src/convert_function_to_cnn_network.cpp @@ -1582,7 +1582,7 @@ InferenceEngine::details::CNNLayerCreator::CNNLayerCreator(const std::shared_ptr auto res = std::make_shared(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; diff --git a/inference-engine/tests/functional/inference_engine/ngraph_reader/deformable_psroi_pooling_tests.cpp b/inference-engine/tests/functional/inference_engine/ngraph_reader/deformable_psroi_pooling_tests.cpp index 33690d29f25..69f6313e3a5 100644 --- a/inference-engine/tests/functional/inference_engine/ngraph_reader/deformable_psroi_pooling_tests.cpp +++ b/inference-engine/tests/functional/inference_engine/ngraph_reader/deformable_psroi_pooling_tests.cpp @@ -5,7 +5,7 @@ #include #include "ngraph_reader_tests.hpp" -TEST_F(NGraphReaderTests, ReadDeformablePSROIPoolingNetwork) { +TEST_F(NGraphReaderTests, ReadDeformablePSROIPoolingNetwork_incorrect_mode) { std::string model = R"V0G0N( @@ -29,7 +29,7 @@ TEST_F(NGraphReaderTests, ReadDeformablePSROIPoolingNetwork) { - + @@ -121,5 +121,124 @@ TEST_F(NGraphReaderTests, ReadDeformablePSROIPoolingNetwork) { )V0G0N"; - compareIRs(model, modelV7, 117600); -} \ No newline at end of file + compareIRs(model, modelV7); +} + +TEST_F(NGraphReaderTests, ReadDeformablePSROIPoolingNetwork) { + std::string model = R"V0G0N( + + + + + + + 1 + 3240 + 38 + 38 + + + + + + + + 100 + 5 + + + + + + + + 1 + 3240 + 38 + 38 + + + 100 + 5 + + + + + 100 + 360 + 3 + 3 + + + + + + + 100 + 360 + 3 + 3 + + + + + + + + + + +)V0G0N"; + std::string modelV7 = R"V0G0N( + + + + + + 1 + 3240 + 38 + 38 + + + + + + + 100 + 5 + + + + + + + + 1 + 3240 + 38 + 38 + + + 100 + 5 + + + + + 100 + 360 + 3 + 3 + + + + + + + + + +)V0G0N"; + compareIRs(model, modelV7); +} diff --git a/ngraph/core/include/ngraph/op/deformable_psroi_pooling.hpp b/ngraph/core/include/ngraph/op/deformable_psroi_pooling.hpp index 88c37e817e1..120ef942086 100644 --- a/ngraph/core/include/ngraph/op/deformable_psroi_pooling.hpp +++ b/ngraph/core/include/ngraph/op/deformable_psroi_pooling.hpp @@ -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; diff --git a/ngraph/core/src/op/deformable_psroi_pooling.cpp b/ngraph/core/src/op/deformable_psroi_pooling.cpp index d1220c932e6..01fd57610d9 100644 --- a/ngraph/core/src/op/deformable_psroi_pooling.cpp +++ b/ngraph/core/src/op/deformable_psroi_pooling.cpp @@ -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 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) diff --git a/ngraph/test/type_prop/deformable_psroi_pooling.cpp b/ngraph/test/type_prop/deformable_psroi_pooling.cpp index 3c1509f2518..61474d800a5 100644 --- a/ngraph/test/type_prop/deformable_psroi_pooling.cpp +++ b/ngraph/test/type_prop/deformable_psroi_pooling.cpp @@ -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(element::f32, Shape{1, 1024, 63, 38}); - auto coords = make_shared(element::f32, Shape{300, 5}); - auto offsets = make_shared(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( - 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(element::f32, PartialShape{2, 7938, 63, 38}); + auto input_coords = make_shared(element::f32, PartialShape{rois_dim, 5}); + + auto def_psroi_pool = make_shared( + 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(element::f32, Shape{1, 7938, 38, 38}); - auto coords = make_shared(element::f32, Shape{300, 5}); - auto offsets = make_shared(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(element::f32, PartialShape{2, 7938, 63, 38}); + auto input_coords = make_shared(element::f32, PartialShape{rois_dim, 5}); + auto input_offsets = make_shared(element::f32, PartialShape{rois_dim, 2, part_size, part_size}); auto def_psroi_pool = make_shared( - 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(element::f32, Shape{1, 2, 3}); - auto coords = make_shared(element::f32, Shape{1, 2}); - auto offsets = make_shared(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(element::f32, PartialShape{2, 7938, 63, 38}); + auto input_coords = make_shared(element::f32, PartialShape{rois_dim, 5}); + auto input_offsets = make_shared(element::f32, PartialShape{rois_dim, 2, part_size, part_size}); + + auto def_psroi_pool = make_shared( + 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(element::f32, PartialShape{2, 7938, 63, 38}); + auto input_coords = make_shared(element::f32, PartialShape{rois_dim, 5}); + + auto def_psroi_pool = make_shared( + 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(element::f32, PartialShape::dynamic()); + auto input_coords = make_shared(element::f32, PartialShape::dynamic()); + + auto def_psroi_pool = make_shared( + 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(element::f32, PartialShape{2, 7938, 63, 38}); + auto input_coords = make_shared(element::f32, PartialShape{rois_dim, 5}); auto def_psroi_pool = make_shared( - 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(element::f32, PartialShape{7938, 63, 38}); + auto input_coords = make_shared(element::f32, PartialShape{rois_dim, 5}); + auto input_offsets = make_shared(element::f32, PartialShape{rois_dim, 2, part_size, part_size}); + + try + { + auto def_psroi_pool = make_shared( + 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(element::f32, Shape{1, 2, 3, 4}); - auto coords = make_shared(element::f32, Shape{1, 2, 3}); - auto offsets = make_shared(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(element::f32, PartialShape{2, 7938, 63, 38}); + auto input_coords = make_shared(element::f32, PartialShape{2, rois_dim, 5}); try { auto def_psroi_pool = make_shared( - 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(element::f32, Shape{1, 2, 3, 4}); - auto coords = make_shared(element::f32, Shape{1, 2}); - auto offsets = make_shared(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(element::f32, PartialShape{2, 7938, 63, 38}); + auto input_coords = make_shared(element::f32, PartialShape{rois_dim, 5}); + auto input_offsets = make_shared(element::f32, PartialShape{2, rois_dim, 2, part_size, part_size}); try { - auto def_psroi_pool = make_shared( - 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( + 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 (...) {