Deformable Convolution v8: transformations (#6533)
* add DeformableConv8to1 transformation * update deformable conv v8 to v1 transformation * Update inference-engine/src/transformations/src/transformations/op_conversions/convert_deformable_conv_v8_to_v1.cpp Co-authored-by: Gleb Kazantaev <gleb.nnstu@gmail.com> Co-authored-by: Gleb Kazantaev <gleb.nnstu@gmail.com>
This commit is contained in:
co-authored by
Gleb Kazantaev
parent
79f26cea7a
commit
85a5e9beb0
@@ -61,6 +61,7 @@
|
|||||||
#include <transformations/op_conversions/convert_nms_to_nms_ie_internal.hpp>
|
#include <transformations/op_conversions/convert_nms_to_nms_ie_internal.hpp>
|
||||||
#include <transformations/op_conversions/convert_interpolate1_to_interpolate4.hpp>
|
#include <transformations/op_conversions/convert_interpolate1_to_interpolate4.hpp>
|
||||||
#include <transformations/op_conversions/convert_gather_0d.hpp>
|
#include <transformations/op_conversions/convert_gather_0d.hpp>
|
||||||
|
#include <transformations/op_conversions/convert_deformable_conv_v8_to_v1.hpp>
|
||||||
#include <transformations/op_conversions/simplify_ctc_greedy_decoder_seq_len.hpp>
|
#include <transformations/op_conversions/simplify_ctc_greedy_decoder_seq_len.hpp>
|
||||||
#include <transformations/convert_precision.hpp>
|
#include <transformations/convert_precision.hpp>
|
||||||
#include <transformations/init_node_info.hpp>
|
#include <transformations/init_node_info.hpp>
|
||||||
@@ -191,6 +192,7 @@ InferenceEngine::CNNNetwork clDNNEngine::CloneAndTransformNetwork(const Inferenc
|
|||||||
manager.register_pass<ngraph::pass::ConvertNMS4ToNMS5>();
|
manager.register_pass<ngraph::pass::ConvertNMS4ToNMS5>();
|
||||||
manager.register_pass<ngraph::pass::ConvertNMSToNMSIEInternal>();
|
manager.register_pass<ngraph::pass::ConvertNMSToNMSIEInternal>();
|
||||||
manager.register_pass<ngraph::pass::ConvertGather0D>();
|
manager.register_pass<ngraph::pass::ConvertGather0D>();
|
||||||
|
manager.register_pass<ngraph::pass::ConvertDeformableConv8To1>();
|
||||||
|
|
||||||
static const precisions_array convert_precision_list {
|
static const precisions_array convert_precision_list {
|
||||||
{ngraph::element::i64, ngraph::element::i32},
|
{ngraph::element::i64, ngraph::element::i32},
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// Copyright (C) 2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <transformations_visibility.hpp>
|
||||||
|
|
||||||
|
#include <ngraph/pass/graph_rewrite.hpp>
|
||||||
|
|
||||||
|
namespace ngraph {
|
||||||
|
namespace pass {
|
||||||
|
|
||||||
|
class TRANSFORMATIONS_API ConvertDeformableConv8To1;
|
||||||
|
|
||||||
|
} // namespace pass
|
||||||
|
} // namespace ngraph
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup ie_transformation_common_api
|
||||||
|
* @brief ConvertDeformableConv8To1 converts v8::DeformableConvolution into v1::DeformableConvolution.
|
||||||
|
*/
|
||||||
|
class ngraph::pass::ConvertDeformableConv8To1 : public ngraph::pass::MatcherPass {
|
||||||
|
public:
|
||||||
|
NGRAPH_RTTI_DECLARATION;
|
||||||
|
ConvertDeformableConv8To1();
|
||||||
|
};
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
// Copyright (C) 2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "transformations/op_conversions/convert_deformable_conv_v8_to_v1.hpp"
|
||||||
|
#include <ngraph/opsets/opset1.hpp>
|
||||||
|
#include <ngraph/opsets/opset8.hpp>
|
||||||
|
#include <ngraph/rt_info.hpp>
|
||||||
|
#include <ngraph/pattern/op/wrap_type.hpp>
|
||||||
|
|
||||||
|
#include "itt.hpp"
|
||||||
|
|
||||||
|
NGRAPH_RTTI_DEFINITION(ngraph::pass::ConvertDeformableConv8To1, "ConvertDeformableConv8To1", 0);
|
||||||
|
|
||||||
|
ngraph::pass::ConvertDeformableConv8To1::ConvertDeformableConv8To1() {
|
||||||
|
MATCHER_SCOPE(ConvertDeformableConv8To1);
|
||||||
|
|
||||||
|
auto deformable_conv_v8 = pattern::wrap_type<ngraph::opset8::DeformableConvolution>();
|
||||||
|
|
||||||
|
ngraph::matcher_pass_callback callback = [=](pattern::Matcher& m) {
|
||||||
|
auto deformable_conv_v8_node = std::dynamic_pointer_cast<ngraph::opset8::DeformableConvolution>(m.get_match_root());
|
||||||
|
if (!deformable_conv_v8_node)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (deformable_conv_v8_node->get_input_size() != 3
|
||||||
|
|| deformable_conv_v8_node->get_bilinear_interpolation_pad())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto arg = deformable_conv_v8_node->input_value(0);
|
||||||
|
auto offsets = deformable_conv_v8_node->input_value(1);
|
||||||
|
auto filters = deformable_conv_v8_node->input_value(2);
|
||||||
|
|
||||||
|
auto deformable_conv_v1 =
|
||||||
|
std::make_shared<ngraph::opset1::DeformableConvolution>(arg,
|
||||||
|
offsets,
|
||||||
|
filters,
|
||||||
|
deformable_conv_v8_node->get_strides(),
|
||||||
|
deformable_conv_v8_node->get_pads_begin(),
|
||||||
|
deformable_conv_v8_node->get_pads_end(),
|
||||||
|
deformable_conv_v8_node->get_dilations(),
|
||||||
|
deformable_conv_v8_node->get_auto_pad(),
|
||||||
|
deformable_conv_v8_node->get_group(),
|
||||||
|
deformable_conv_v8_node->get_deformable_group());
|
||||||
|
deformable_conv_v1->set_friendly_name(deformable_conv_v8_node->get_friendly_name());
|
||||||
|
ngraph::copy_runtime_info(deformable_conv_v8_node, deformable_conv_v1);
|
||||||
|
ngraph::replace_node(deformable_conv_v8_node, deformable_conv_v1);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto m = std::make_shared<pattern::Matcher>(deformable_conv_v8, matcher_name);
|
||||||
|
register_matcher(m, callback);
|
||||||
|
}
|
||||||
+160
@@ -0,0 +1,160 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <ngraph/function.hpp>
|
||||||
|
#include <ngraph/opsets/opset1.hpp>
|
||||||
|
#include <ngraph/opsets/opset8.hpp>
|
||||||
|
#include <ngraph/pass/manager.hpp>
|
||||||
|
#include <transformations/op_conversions/convert_deformable_conv_v8_to_v1.hpp>
|
||||||
|
#include <transformations/init_node_info.hpp>
|
||||||
|
|
||||||
|
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||||
|
|
||||||
|
using namespace testing;
|
||||||
|
using namespace ngraph;
|
||||||
|
|
||||||
|
TEST(TransformationTests, ConvertDeformableConv8to1) {
|
||||||
|
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
|
||||||
|
{
|
||||||
|
const Strides strides{1, 1};
|
||||||
|
const CoordinateDiff padding{0, 0};
|
||||||
|
const Strides dilations{1, 1};
|
||||||
|
|
||||||
|
const Shape input_shape{1, 1, 4, 4};
|
||||||
|
const Shape filter_shape{1, 1, 2, 2};
|
||||||
|
const Shape offsets_shape{1, 8, 3, 3};
|
||||||
|
|
||||||
|
auto data = std::make_shared<opset8::Parameter>(element::f32, input_shape);
|
||||||
|
auto filter = std::make_shared<opset8::Parameter>(element::f32, filter_shape);
|
||||||
|
auto offsets = std::make_shared<opset8::Parameter>(element::f32, offsets_shape);
|
||||||
|
|
||||||
|
auto deformable_conv = std::make_shared<opset8::DeformableConvolution>(data,
|
||||||
|
offsets,
|
||||||
|
filter,
|
||||||
|
strides,
|
||||||
|
padding,
|
||||||
|
padding,
|
||||||
|
dilations);
|
||||||
|
|
||||||
|
f = std::make_shared<Function>(NodeVector{deformable_conv}, ParameterVector{data, filter, offsets});
|
||||||
|
|
||||||
|
pass::Manager manager;
|
||||||
|
manager.register_pass<pass::InitNodeInfo>();
|
||||||
|
manager.register_pass<pass::ConvertDeformableConv8To1>();
|
||||||
|
manager.run_passes(f);
|
||||||
|
ASSERT_NO_THROW(check_rt_info(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const Strides strides{1, 1};
|
||||||
|
const CoordinateDiff padding{0, 0};
|
||||||
|
const Strides dilations{1, 1};
|
||||||
|
|
||||||
|
const Shape input_shape{1, 1, 4, 4};
|
||||||
|
const Shape filter_shape{1, 1, 2, 2};
|
||||||
|
const Shape offsets_shape{1, 8, 3, 3};
|
||||||
|
|
||||||
|
auto data = std::make_shared<opset1::Parameter>(element::f32, input_shape);
|
||||||
|
auto filter = std::make_shared<opset1::Parameter>(element::f32, filter_shape);
|
||||||
|
auto offsets = std::make_shared<opset1::Parameter>(element::f32, offsets_shape);
|
||||||
|
|
||||||
|
auto deformable_conv = std::make_shared<opset1::DeformableConvolution>(data,
|
||||||
|
offsets,
|
||||||
|
filter,
|
||||||
|
strides,
|
||||||
|
padding,
|
||||||
|
padding,
|
||||||
|
dilations);
|
||||||
|
|
||||||
|
f_ref = std::make_shared<Function>(NodeVector{deformable_conv}, ParameterVector{data, filter, offsets});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = compare_functions(f, f_ref);
|
||||||
|
ASSERT_TRUE(res.first) << res.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TransformationTests, ConvertDeformableConv8to1_mask) {
|
||||||
|
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
|
||||||
|
{
|
||||||
|
const Strides strides{1, 1};
|
||||||
|
const CoordinateDiff padding{0, 0};
|
||||||
|
const Strides dilations{1, 1};
|
||||||
|
|
||||||
|
const Shape input_shape{1, 1, 4, 4};
|
||||||
|
const Shape filter_shape{1, 1, 2, 2};
|
||||||
|
const Shape offsets_shape{1, 8, 3, 3};
|
||||||
|
const Shape mask_shape{1, 4, 3, 3};
|
||||||
|
|
||||||
|
auto data = std::make_shared<opset8::Parameter>(element::f32, input_shape);
|
||||||
|
auto filter = std::make_shared<opset8::Parameter>(element::f32, filter_shape);
|
||||||
|
auto offsets = std::make_shared<opset8::Parameter>(element::f32, offsets_shape);
|
||||||
|
auto mask = std::make_shared<opset8::Parameter>(element::f32, mask_shape);
|
||||||
|
|
||||||
|
auto deformable_conv = std::make_shared<opset8::DeformableConvolution>(data,
|
||||||
|
offsets,
|
||||||
|
filter,
|
||||||
|
mask,
|
||||||
|
strides,
|
||||||
|
padding,
|
||||||
|
padding,
|
||||||
|
dilations);
|
||||||
|
|
||||||
|
f = std::make_shared<Function>(NodeVector{deformable_conv}, ParameterVector{data, filter,
|
||||||
|
mask, offsets});
|
||||||
|
|
||||||
|
pass::Manager manager;
|
||||||
|
manager.register_pass<pass::InitNodeInfo>();
|
||||||
|
manager.register_pass<pass::ConvertDeformableConv8To1>();
|
||||||
|
manager.run_passes(f);
|
||||||
|
ASSERT_NO_THROW(check_rt_info(f));
|
||||||
|
}
|
||||||
|
// mask input is provided, DeformableConvolution-8 must remain
|
||||||
|
ASSERT_EQ(count_ops_of_type<opset1::DeformableConvolution>(f), 0);
|
||||||
|
ASSERT_EQ(count_ops_of_type<opset8::DeformableConvolution>(f), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TransformationTests, ConvertDeformableConv8to1_bilinear_interpolation_padding) {
|
||||||
|
std::shared_ptr<Function> f(nullptr), f_ref(nullptr);
|
||||||
|
{
|
||||||
|
const Strides strides{1, 1};
|
||||||
|
const CoordinateDiff padding{0, 0};
|
||||||
|
const Strides dilations{1, 1};
|
||||||
|
|
||||||
|
const Shape input_shape{1, 1, 4, 4};
|
||||||
|
const Shape filter_shape{1, 1, 2, 2};
|
||||||
|
const Shape offsets_shape{1, 8, 3, 3};
|
||||||
|
|
||||||
|
auto data = std::make_shared<opset8::Parameter>(element::f32, input_shape);
|
||||||
|
auto filter = std::make_shared<opset8::Parameter>(element::f32, filter_shape);
|
||||||
|
auto offsets = std::make_shared<opset8::Parameter>(element::f32, offsets_shape);
|
||||||
|
|
||||||
|
auto deformable_conv = std::make_shared<opset8::DeformableConvolution>(data,
|
||||||
|
offsets,
|
||||||
|
filter,
|
||||||
|
strides,
|
||||||
|
padding,
|
||||||
|
padding,
|
||||||
|
dilations,
|
||||||
|
op::PadType::EXPLICIT,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
true);
|
||||||
|
|
||||||
|
f = std::make_shared<Function>(NodeVector{deformable_conv}, ParameterVector{data, filter, offsets});
|
||||||
|
|
||||||
|
pass::Manager manager;
|
||||||
|
manager.register_pass<pass::InitNodeInfo>();
|
||||||
|
manager.register_pass<pass::ConvertDeformableConv8To1>();
|
||||||
|
manager.run_passes(f);
|
||||||
|
ASSERT_NO_THROW(check_rt_info(f));
|
||||||
|
}
|
||||||
|
// use_bilinear_interpolation_padding is true, DeformableConvolution-8 must remain
|
||||||
|
ASSERT_EQ(count_ops_of_type<opset1::DeformableConvolution>(f), 0);
|
||||||
|
ASSERT_EQ(count_ops_of_type<opset8::DeformableConvolution>(f), 1);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user