Skip to content

Commit

Permalink
add prior_box and box_coder for paddle.vision.ops (#47282)
Browse files Browse the repository at this point in the history
  • Loading branch information
nemonameless committed Oct 24, 2022
1 parent 3a0690e commit 2e299ad
Show file tree
Hide file tree
Showing 4 changed files with 509 additions and 129 deletions.
149 changes: 23 additions & 126 deletions python/paddle/fluid/layers/detection.py
Expand Up @@ -996,63 +996,15 @@ def box_coder(
box_normalized=False,
axis=1)
"""
check_variable_and_dtype(
prior_box, 'prior_box', ['float32', 'float64'], 'box_coder'
)
check_variable_and_dtype(
target_box, 'target_box', ['float32', 'float64'], 'box_coder'
)
if in_dygraph_mode():
if isinstance(prior_box_var, Variable):
box_coder_op = _C_ops.box_coder(
prior_box,
prior_box_var,
target_box,
code_type,
box_normalized,
axis,
[],
)
elif isinstance(prior_box_var, list):
box_coder_op = _C_ops.box_coder(
prior_box,
None,
target_box,
code_type,
box_normalized,
axis,
prior_box_var,
)
else:
raise TypeError(
"Input variance of box_coder must be Variable or lisz"
)
return box_coder_op
helper = LayerHelper("box_coder", **locals())

output_box = helper.create_variable_for_type_inference(
dtype=prior_box.dtype
)

inputs = {"PriorBox": prior_box, "TargetBox": target_box}
attrs = {
"code_type": code_type,
"box_normalized": box_normalized,
"axis": axis,
}
if isinstance(prior_box_var, Variable):
inputs['PriorBoxVar'] = prior_box_var
elif isinstance(prior_box_var, list):
attrs['variance'] = prior_box_var
else:
raise TypeError("Input variance of box_coder must be Variable or lisz")
helper.append_op(
type="box_coder",
inputs=inputs,
attrs=attrs,
outputs={"OutputBox": output_box},
return paddle.vision.ops.box_coder(
prior_box=prior_box,
prior_box_var=prior_box_var,
target_box=target_box,
code_type=code_type,
box_normalized=box_normalized,
axis=axis,
name=name,
)
return output_box


@templatedoc()
Expand Down Expand Up @@ -1974,8 +1926,8 @@ def prior_box(
#declarative mode
import paddle.fluid as fluid
import numpy as np
import paddle
paddle.enable_static()
import paddle
paddle.enable_static()
input = fluid.data(name="input", shape=[None,3,6,9])
image = fluid.data(name="image", shape=[None,3,9,12])
box, var = fluid.layers.prior_box(
Expand Down Expand Up @@ -2021,75 +1973,20 @@ def prior_box(
# [6L, 9L, 1L, 4L]
"""

if in_dygraph_mode():
step_w, step_h = steps
if max_sizes == None:
max_sizes = []
return _C_ops.prior_box(
input,
image,
min_sizes,
aspect_ratios,
variance,
max_sizes,
flip,
clip,
step_w,
step_h,
offset,
min_max_aspect_ratios_order,
)
helper = LayerHelper("prior_box", **locals())
dtype = helper.input_dtype()
check_variable_and_dtype(
input, 'input', ['uint8', 'int8', 'float32', 'float64'], 'prior_box'
)

def _is_list_or_tuple_(data):
return isinstance(data, list) or isinstance(data, tuple)

if not _is_list_or_tuple_(min_sizes):
min_sizes = [min_sizes]
if not _is_list_or_tuple_(aspect_ratios):
aspect_ratios = [aspect_ratios]
if not (_is_list_or_tuple_(steps) and len(steps) == 2):
raise ValueError(
'steps should be a list or tuple ',
'with length 2, (step_width, step_height).',
)

min_sizes = list(map(float, min_sizes))
aspect_ratios = list(map(float, aspect_ratios))
steps = list(map(float, steps))

attrs = {
'min_sizes': min_sizes,
'aspect_ratios': aspect_ratios,
'variances': variance,
'flip': flip,
'clip': clip,
'step_w': steps[0],
'step_h': steps[1],
'offset': offset,
'min_max_aspect_ratios_order': min_max_aspect_ratios_order,
}
if max_sizes is not None and len(max_sizes) > 0 and max_sizes[0] > 0:
if not _is_list_or_tuple_(max_sizes):
max_sizes = [max_sizes]
attrs['max_sizes'] = max_sizes

box = helper.create_variable_for_type_inference(dtype)
var = helper.create_variable_for_type_inference(dtype)
helper.append_op(
type="prior_box",
inputs={"Input": input, "Image": image},
outputs={"Boxes": box, "Variances": var},
attrs=attrs,
return paddle.vision.ops.prior_box(
input=input,
image=image,
min_sizes=min_sizes,
max_sizes=max_sizes,
aspect_ratios=aspect_ratios,
variance=variance,
flip=flip,
clip=clip,
steps=steps,
offset=offset,
min_max_aspect_ratios_order=min_max_aspect_ratios_order,
name=name,
)
box.stop_gradient = True
var.stop_gradient = True
return box, var


def density_prior_box(
Expand Down
57 changes: 57 additions & 0 deletions python/paddle/fluid/tests/unittests/test_box_coder_op.py
Expand Up @@ -319,5 +319,62 @@ def run(place):
run(place)


class TestBoxCoderAPI(unittest.TestCase):
def setUp(self):
np.random.seed(678)
self.prior_box_np = np.random.random((80, 4)).astype('float32')
self.prior_box_var_np = np.random.random((80, 4)).astype('float32')
self.target_box_np = np.random.random((20, 80, 4)).astype('float32')

def test_dygraph_with_static(self):
paddle.enable_static()
prior_box = paddle.static.data(
name='prior_box', shape=[80, 4], dtype='float32'
)
prior_box_var = paddle.static.data(
name='prior_box_var', shape=[80, 4], dtype='float32'
)
target_box = paddle.static.data(
name='target_box', shape=[20, 80, 4], dtype='float32'
)

boxes = paddle.vision.ops.box_coder(
prior_box=prior_box,
prior_box_var=prior_box_var,
target_box=target_box,
code_type="decode_center_size",
box_normalized=False,
)

exe = paddle.static.Executor()
boxes_np = exe.run(
paddle.static.default_main_program(),
feed={
'prior_box': self.prior_box_np,
'prior_box_var': self.prior_box_var_np,
'target_box': self.target_box_np,
},
fetch_list=[boxes],
)

paddle.disable_static()
prior_box_dy = paddle.to_tensor(self.prior_box_np)
prior_box_var_dy = paddle.to_tensor(self.prior_box_var_np)
target_box_dy = paddle.to_tensor(self.target_box_np)

boxes_dy = paddle.vision.ops.box_coder(
prior_box=prior_box_dy,
prior_box_var=prior_box_var_dy,
target_box=target_box_dy,
code_type="decode_center_size",
box_normalized=False,
)
boxes_dy_np = boxes_dy.numpy()

np.testing.assert_allclose(boxes_np[0], boxes_dy_np)
paddle.enable_static()


if __name__ == '__main__':
paddle.enable_static()
unittest.main()
56 changes: 53 additions & 3 deletions python/paddle/fluid/tests/unittests/test_prior_box_op.py
Expand Up @@ -109,9 +109,6 @@ def init_test_params(self):
self.flip = True
self.set_min_max_aspect_ratios_order()
self.real_aspect_ratios = [1, 2.0, 1.0 / 2.0, 3.0, 1.0 / 3.0]
self.aspect_ratios = np.array(
self.aspect_ratios, dtype=np.float64
).flatten()
self.variances = [0.1, 0.1, 0.2, 0.2]
self.variances = np.array(self.variances, dtype=np.float64).flatten()

Expand Down Expand Up @@ -225,6 +222,59 @@ def set_min_max_aspect_ratios_order(self):
self.min_max_aspect_ratios_order = True


class TestPriorBoxAPI(unittest.TestCase):
def setUp(self):
np.random.seed(678)
self.input_np = np.random.rand(2, 10, 32, 32).astype('float32')
self.image_np = np.random.rand(2, 10, 40, 40).astype('float32')
self.min_sizes = [2.0, 4.0]

def test_dygraph_with_static(self):
paddle.enable_static()
input = paddle.static.data(
name='input', shape=[2, 10, 32, 32], dtype='float32'
)
image = paddle.static.data(
name='image', shape=[2, 10, 40, 40], dtype='float32'
)

box, var = paddle.vision.ops.prior_box(
input=input,
image=image,
min_sizes=self.min_sizes,
clip=True,
flip=True,
)

exe = paddle.static.Executor()
box_np, var_np = exe.run(
paddle.static.default_main_program(),
feed={
'input': self.input_np,
'image': self.image_np,
},
fetch_list=[box, var],
)

paddle.disable_static()
inputs_dy = paddle.to_tensor(self.input_np)
image_dy = paddle.to_tensor(self.image_np)

box_dy, var_dy = paddle.vision.ops.prior_box(
input=inputs_dy,
image=image_dy,
min_sizes=self.min_sizes,
clip=True,
flip=True,
)
box_dy_np = box_dy.numpy()
var_dy_np = var_dy.numpy()

np.testing.assert_allclose(box_np, box_dy_np)
np.testing.assert_allclose(var_np, var_dy_np)
paddle.enable_static()


if __name__ == '__main__':
paddle.enable_static()
unittest.main()

0 comments on commit 2e299ad

Please sign in to comment.