DeformableConvolution v8: ngraph python API (#6520)

* Python API for DeformableConvolution op

* python codestyle

* fix python codestyle

* resolve review remarks

* fix python codestyle
This commit is contained in:
Ivan Tikhonov 2021-07-09 09:41:43 +03:00 committed by GitHub
parent 2a970a56d3
commit de8c57e034
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 110 additions and 1 deletions

View File

@ -33,7 +33,7 @@ from ngraph.opset6.ops import ctc_greedy_decoder_seq_len
from ngraph.opset4.ops import ctc_loss
from ngraph.opset3.ops import cum_sum
from ngraph.opset3.ops import cum_sum as cumsum
from ngraph.opset1.ops import deformable_convolution
from ngraph.opset8.ops import deformable_convolution
from ngraph.opset1.ops import deformable_psroi_pooling
from ngraph.opset1.ops import depth_to_space
from ngraph.opset1.ops import detection_output

View File

@ -43,3 +43,59 @@ _get_node_factory_opset8 = partial(_get_node_factory, "opset8")
# -------------------------------------------- ops ------------------------------------------------
@nameable_op
def deformable_convolution(
data: NodeInput,
offsets: NodeInput,
filters: NodeInput,
strides: List[int],
pads_begin: List[int],
pads_end: List[int],
dilations: List[int],
mask: Optional[NodeInput] = None,
auto_pad: str = "EXPLICIT",
group: int = 1,
deformable_group: int = 1,
bilinear_interpolation_pad: bool = False,
name: Optional[str] = None,
) -> Node:
"""Return a node which performs deformable convolution operation.
@param data: The node providing data batch tensor.
@param offsets: The node providing offset tensor.
@param filters: The node providing filters tensor.
@param strides: The distance (in pixels) to slide the filter on the feature map over the axes.
@param pads_begin: The number of pixels to add to the beginning along each axis.
@param pads_end: The number of pixels to add to the end along each axis.
@param dilations: The distance in width and height between elements (weights) in the filter.
@param mask: The node providing modulation scalar (mask) tensor.
@param auto_pad: The type of padding. Range of values: explicit, same_upper, same_lower, valid.
@param group: The number of groups which both output and input should be split into.
@param deformable_group: The number of groups which deformable values and output should be split
into along the channel axis.
@param bilinear_interpolation_pad: The flag that determines the mode of bilinear interpolation
execution.
@param name: The optional new name for output node.
@return New node performing deformable convolution operation.
"""
if mask is None:
inputs = as_nodes(data, offsets, filters)
else:
inputs = as_nodes(data, offsets, filters, mask)
return _get_node_factory_opset8().create(
"DeformableConvolution",
inputs,
{
"strides": strides,
"pads_begin": pads_begin,
"pads_end": pads_end,
"dilations": dilations,
"auto_pad": auto_pad,
"group": group,
"deformable_group": deformable_group,
"bilinear_interpolation_pad": bilinear_interpolation_pad
},
)

View File

@ -104,6 +104,31 @@ def test_ctc_greedy_decoder_seq_len(fp_dtype, int_dtype, int_ci, int_sl, merge_r
assert list(node.get_output_shape(0)) == expected_shape
@pytest.mark.parametrize("dtype", np_types)
def test_deformable_convolution_opset1(dtype):
strides = np.array([1, 1])
pads_begin = np.array([0, 0])
pads_end = np.array([0, 0])
dilations = np.array([1, 1])
input0_shape = [1, 1, 9, 9]
input1_shape = [1, 18, 7, 7]
input2_shape = [1, 1, 3, 3]
expected_shape = [1, 1, 7, 7]
parameter_input0 = ng.parameter(input0_shape, name="Input0", dtype=dtype)
parameter_input1 = ng.parameter(input1_shape, name="Input1", dtype=dtype)
parameter_input2 = ng.parameter(input2_shape, name="Input2", dtype=dtype)
node = ng_opset1.deformable_convolution(
parameter_input0, parameter_input1, parameter_input2, strides, pads_begin, pads_end, dilations,
)
assert node.get_type_name() == "DeformableConvolution"
assert node.get_output_size() == 1
assert list(node.get_output_shape(0)) == expected_shape
@pytest.mark.parametrize("dtype", np_types)
def test_deformable_convolution(dtype):
strides = np.array([1, 1])
@ -129,6 +154,34 @@ def test_deformable_convolution(dtype):
assert list(node.get_output_shape(0)) == expected_shape
@pytest.mark.parametrize("dtype", np_types)
def test_deformable_convolution_mask(dtype):
strides = np.array([1, 1])
pads_begin = np.array([0, 0])
pads_end = np.array([0, 0])
dilations = np.array([1, 1])
input0_shape = [1, 1, 9, 9]
input1_shape = [1, 18, 7, 7]
input2_shape = [1, 1, 3, 3]
input3_shape = [1, 9, 7, 7]
expected_shape = [1, 1, 7, 7]
parameter_input0 = ng.parameter(input0_shape, name="Input0", dtype=dtype)
parameter_input1 = ng.parameter(input1_shape, name="Input1", dtype=dtype)
parameter_input2 = ng.parameter(input2_shape, name="Input2", dtype=dtype)
parameter_input3 = ng.parameter(input3_shape, name="Input3", dtype=dtype)
node = ng.deformable_convolution(
parameter_input0, parameter_input1, parameter_input2, strides,
pads_begin, pads_end, dilations, parameter_input3
)
assert node.get_type_name() == "DeformableConvolution"
assert node.get_output_size() == 1
assert list(node.get_output_shape(0)) == expected_shape
@pytest.mark.parametrize("dtype", np_types)
def test_deformable_psroi_pooling(dtype):
output_dim = 8