未验证 提交 af3fabf9 编写于 作者: Y yunyaoXYY 提交者: GitHub

[Clean fluid] Clean fluid roi_pool,roi_align,psroi_pool and prroi_pool (#48393)

* Clean fluid resize_linear API

* Clean fluid image_resize_short API

* add image_resize back

* Clean psroi_pool and prroo_pool

* Clean roi_pool and roi_align

* delete test_trt_roi_align_op.py
上级 a0930484
...@@ -97,8 +97,6 @@ __all__ = [ ...@@ -97,8 +97,6 @@ __all__ = [
'lod_reset', 'lod_reset',
'lod_append', 'lod_append',
'pad', 'pad',
'roi_pool',
'roi_align',
'image_resize', 'image_resize',
'resize_bilinear', 'resize_bilinear',
'resize_trilinear', 'resize_trilinear',
...@@ -136,8 +134,6 @@ __all__ = [ ...@@ -136,8 +134,6 @@ __all__ = [
'get_tensor_from_selected_rows', 'get_tensor_from_selected_rows',
'temporal_shift', 'temporal_shift',
'py_func', 'py_func',
'psroi_pool',
'prroi_pool',
'pixel_shuffle', 'pixel_shuffle',
'fsp_matrix', 'fsp_matrix',
'continuous_value_model', 'continuous_value_model',
...@@ -4979,240 +4975,6 @@ def pad(x, paddings, pad_value=0.0, name=None): ...@@ -4979,240 +4975,6 @@ def pad(x, paddings, pad_value=0.0, name=None):
return out return out
@templatedoc()
def roi_pool(
input,
rois,
pooled_height=1,
pooled_width=1,
spatial_scale=1.0,
rois_num=None,
name=None,
):
"""
This operator implements the roi_pooling layer.
Region of interest pooling (also known as RoI pooling) is to perform max pooling on inputs of nonuniform sizes to obtain fixed-size feature maps (e.g. 7*7).
The operator has three steps:
1. Dividing each region proposal into equal-sized sections with the pooled_width and pooled_height;
2. Finding the largest value in each section;
3. Copying these max values to the output buffer.
For more information, please refer to https://stackoverflow.com/questions/43430056/what-is-roi-layer-in-fast-rcnn
Args:
input (Variable): Input feature, 4D-Tensor with the shape of [N,C,H,W], where N is the batch size, C is the input channel, H is Height, W is weight. The data type is float32 or float64.
rois (Variable): ROIs (Regions of Interest) to pool over. 2D-LoDTensor with the shape of [num_rois,4], the lod level is 1. Given as [[x1, y1, x2, y2], ...], (x1, y1) is the top left coordinates, and (x2, y2) is the bottom right coordinates.
pooled_height (int, optional): The pooled output height, data type is int32. Default: 1
pooled_width (int, optional): The pooled output height, data type is int32. Default: 1
spatial_scale (float, optional): Multiplicative spatial scale factor to translate ROI coords from their input scale to the scale used when pooling. Default: 1.0
rois_num (Tensor): The number of RoIs in each image. Default: None
name(str, optional): For detailed information, please refer
to :ref:`api_guide_Name`. Usually name is no need to set and
None by default.
Returns:
Variable: The pooled feature, 4D-Tensor with the shape of [num_rois, C, pooled_height, pooled_width].
Examples:
.. code-block:: python
import paddle.fluid as fluid
import numpy as np
import paddle
paddle.enable_static()
DATATYPE='float32'
place = fluid.CPUPlace()
#place = fluid.CUDAPlace(0)
input_data = np.array([i for i in range(1,17)]).reshape(1,1,4,4).astype(DATATYPE)
roi_data =fluid.create_lod_tensor(np.array([[1., 1., 2., 2.], [1.5, 1.5, 3., 3.]]).astype(DATATYPE),[[2]], place)
rois_num_data = np.array([2]).astype('int32')
x = fluid.data(name='input', shape=[None,1,4,4], dtype=DATATYPE)
rois = fluid.data(name='roi', shape=[None,4], dtype=DATATYPE)
rois_num = fluid.data(name='rois_num', shape=[None], dtype='int32')
pool_out = fluid.layers.roi_pool(
input=x,
rois=rois,
pooled_height=1,
pooled_width=1,
spatial_scale=1.0,
rois_num=rois_num)
exe = fluid.Executor(place)
out, = exe.run(feed={'input':input_data ,'roi':roi_data, 'rois_num': rois_num_data}, fetch_list=[pool_out.name])
print(out) #array([[[[11.]]], [[[16.]]]], dtype=float32)
print(np.array(out).shape) # (2, 1, 1, 1)
"""
if _non_static_mode():
assert (
rois_num is not None
), "rois_num should not be None in dygraph mode."
pool_out, argmaxes = _legacy_C_ops.roi_pool(
input,
rois,
rois_num,
"pooled_height",
pooled_height,
"pooled_width",
pooled_width,
"spatial_scale",
spatial_scale,
)
return pool_out, argmaxes
check_variable_and_dtype(input, 'input', ['float32'], 'roi_pool')
check_variable_and_dtype(rois, 'rois', ['float32'], 'roi_pool')
helper = LayerHelper('roi_pool', **locals())
dtype = helper.input_dtype()
pool_out = helper.create_variable_for_type_inference(dtype)
argmaxes = helper.create_variable_for_type_inference(dtype='int32')
inputs = {
"X": input,
"ROIs": rois,
}
if rois_num is not None:
inputs['RoisNum'] = rois_num
helper.append_op(
type="roi_pool",
inputs=inputs,
outputs={"Out": pool_out, "Argmax": argmaxes},
attrs={
"pooled_height": pooled_height,
"pooled_width": pooled_width,
"spatial_scale": spatial_scale,
},
)
return pool_out
@templatedoc()
def roi_align(
input,
rois,
pooled_height=1,
pooled_width=1,
spatial_scale=1.0,
sampling_ratio=-1,
rois_num=None,
name=None,
):
"""
${comment}
Args:
input (Variable): ${x_comment}
rois (Variable): ROIs (Regions of Interest) to pool over.It should be
a 2-D LoDTensor of shape (num_rois, 4), the lod level is 1. The
data type is float32 or float64. Given as [[x1, y1, x2, y2], ...],
(x1, y1) is the top left coordinates, and (x2, y2) is the bottom
right coordinates.
pooled_height (int32, optional): ${pooled_height_comment} Default: 1
pooled_width (int32, optional): ${pooled_width_comment} Default: 1
spatial_scale (float32, optional): ${spatial_scale_comment} Default: 1.0
sampling_ratio(int32, optional): ${sampling_ratio_comment} Default: -1
rois_num (Tensor): The number of RoIs in each image. Default: None
name(str, optional): For detailed information, please refer
to :ref:`api_guide_Name`. Usually name is no need to set and
None by default.
Returns:
Variable:
Output: ${out_comment}.
Examples:
.. code-block:: python
import paddle.fluid as fluid
import paddle
paddle.enable_static()
x = fluid.data(
name='data', shape=[None, 256, 32, 32], dtype='float32')
rois = fluid.data(
name='rois', shape=[None, 4], dtype='float32')
rois_num = fluid.data(name='rois_num', shape=[None], dtype='int32')
align_out = fluid.layers.roi_align(input=x,
rois=rois,
pooled_height=7,
pooled_width=7,
spatial_scale=0.5,
sampling_ratio=-1,
rois_num=rois_num)
"""
if in_dygraph_mode():
assert (
rois_num is not None
), "rois_num should not be None in dygraph mode."
return _C_ops.roi_align(
input,
rois,
rois_num,
pooled_height,
pooled_width,
spatial_scale,
sampling_ratio,
False,
)
if _in_legacy_dygraph():
assert (
rois_num is not None
), "rois_num should not be None in dygraph mode."
align_out = _legacy_C_ops.roi_align(
input,
rois,
rois_num,
"pooled_height",
pooled_height,
"pooled_width",
pooled_width,
"spatial_scale",
spatial_scale,
"sampling_ratio",
sampling_ratio,
)
return align_out
check_variable_and_dtype(
input, 'input', ['float32', 'float64'], 'roi_align'
)
check_variable_and_dtype(rois, 'rois', ['float32', 'float64'], 'roi_align')
helper = LayerHelper('roi_align', **locals())
dtype = helper.input_dtype()
align_out = helper.create_variable_for_type_inference(dtype)
inputs = {
"X": input,
"ROIs": rois,
}
if rois_num is not None:
inputs['RoisNum'] = rois_num
helper.append_op(
type="roi_align",
inputs=inputs,
outputs={"Out": align_out},
attrs={
"pooled_height": pooled_height,
"pooled_width": pooled_width,
"spatial_scale": spatial_scale,
"sampling_ratio": sampling_ratio,
},
)
return align_out
def image_resize( def image_resize(
input, input,
out_shape=None, out_shape=None,
...@@ -9097,162 +8859,6 @@ py_func.registered_func = PyFuncRegistry.registered_func ...@@ -9097,162 +8859,6 @@ py_func.registered_func = PyFuncRegistry.registered_func
py_func.registered_func_num = PyFuncRegistry.registered_func_num py_func.registered_func_num = PyFuncRegistry.registered_func_num
@templatedoc()
def psroi_pool(
input,
rois,
output_channels,
spatial_scale,
pooled_height,
pooled_width,
name=None,
):
"""
${comment}
Parameters:
input (Variable): ${x_comment}
rois (Variable): LoDTensor, ROIs (Regions of Interest) to pool over.It should be
a 2-D LoDTensor of shape (num_rois, 4), the lod level
is 1. Given as [[x1, y1, x2, y2], ...], (x1, y1) is
the top left coordinates, and (x2, y2) is the bottom
right coordinates. The data type is the same as `input`
output_channels (int): ${output_channels_comment}
spatial_scale (float): ${spatial_scale_comment} Default: 1.0
pooled_height (int): ${pooled_height_comment} Default: 1
pooled_width (int): ${pooled_width_comment} Default: 1
name(str, optional): The default value is None.
Normally there is no need for user to set this property.
For more information, please refer to :ref:`api_guide_Name`
Returns:
${out_comment}.
Return Type:
Variable
Examples:
.. code-block:: python
import paddle.fluid as fluid
import paddle
paddle.enable_static()
x = fluid.data(name='x', shape=[100, 490, 28, 28], dtype='float32')
rois = fluid.data(name='rois', shape=[None, 4], lod_level=1, dtype='float32')
pool_out = fluid.layers.psroi_pool(x, rois, 10, 1.0, 7, 7)
"""
helper = LayerHelper('psroi_pool', **locals())
# check attrs
if not isinstance(output_channels, int):
raise TypeError("output_channels must be int type")
if not isinstance(spatial_scale, float):
raise TypeError("spatial_scale must be float type")
if not isinstance(pooled_height, int):
raise TypeError("pooled_height must be int type")
if not isinstance(pooled_width, int):
raise TypeError("pooled_width must be int type")
dtype = helper.input_dtype()
out = helper.create_variable_for_type_inference(dtype)
helper.append_op(
type='psroi_pool',
inputs={'X': input, 'ROIs': rois},
outputs={'Out': out},
attrs={
'output_channels': output_channels,
'spatial_scale': spatial_scale,
'pooled_height': pooled_height,
'pooled_width': pooled_width,
},
)
return out
@templatedoc()
def prroi_pool(
input,
rois,
spatial_scale=1.0,
pooled_height=1,
pooled_width=1,
batch_roi_nums=None,
name=None,
):
"""
The precise roi pooling implementation for paddle. Reference: https://arxiv.org/pdf/1807.11590.pdf
Args:
input (Variable):The input of precise roi pooliing.The shape of input tensor is
[N,C,H,W]. Where N is batch size,C is number of input channels,H
is height of the feature, and W is the width of the feature.
rois (Variable): ROIs (Regions of Interest) to pool over.It should be
a 2-D LoDTensor or Tensor of shape (num_rois, 4), the lod level
is 1 when it is LoDTensor. The LoD include the rois's batch index
information. If rois is Tensor, its batch index information should
be provided by batch_index.
Given as [[x1, y1, x2, y2], ...], (x1, y1) is
the top left coordinates, and (x2, y2) is the bottom
right coordinates.
spatial_scale (float): Ratio of input feature map height (or width) to raw image height (or width).
Equals the reciprocal of total stride in convolutional layers, Default: 1.0.
pooled_height (integer): The pooled output height. Default: 1.
pooled_width (integer): The pooled output width. Default: 1.
batch_roi_nums (Variable): The number of roi for each image in batch. It
should be 1-D Tensor, with shape [N] and dtype int64,
where N is the batch size. Default: None. Be note: The lod of input should be
empty when batch_roi_nums has values;
name (str, default None): The name of this operation.
Returns:
Variable(Tensor):The shape of the returned Tensor is (N, C, pooled_height, pooled_width), with value type float32,float16. N, C denote batch_size and channels of input respectively.
Examples:
.. code-block:: python
## prroi_pool without batch_roi_num
import paddle.fluid as fluid
x = fluid.data(name='x', shape=[None, 490, 28, 28], dtype='float32')
rois = fluid.data(name='rois', shape=[None, 4], lod_level=1, dtype='float32')
pool_out = fluid.layers.prroi_pool(x, rois, 1.0, 7, 7)
## prroi_pool with batch_roi_num
batchsize=4
x2 = fluid.data(name='x2', shape=[batchsize, 490, 28, 28], dtype='float32')
rois2 = fluid.data(name='rois2', shape=[batchsize, 4], dtype='float32')
batch_rois_num = fluid.data(name='rois_nums', shape=[batchsize], dtype='int64')
pool_out2 = fluid.layers.prroi_pool(x2, rois2, 1.0, 7, 7, batch_roi_nums=batch_rois_num)
"""
check_variable_and_dtype(input, 'input', ['float32'], 'prroi_pool')
check_variable_and_dtype(rois, 'rois', ['float32'], 'prroi_pool')
helper = LayerHelper('prroi_pool', **locals())
# check attrs
if not isinstance(spatial_scale, float):
raise TypeError("spatial_scale must be float type")
if not isinstance(pooled_height, int):
raise TypeError("pooled_height must be int type")
if not isinstance(pooled_width, int):
raise TypeError("pooled_width must be int type")
dtype = helper.input_dtype()
out = helper.create_variable_for_type_inference(dtype)
inputs_op = {'X': input, 'ROIs': rois}
if batch_roi_nums is not None:
inputs_op['BatchRoINums'] = batch_roi_nums
helper.append_op(
type='prroi_pool',
inputs=inputs_op,
outputs={'Out': out},
attrs={
'spatial_scale': spatial_scale,
'pooled_height': pooled_height,
'pooled_width': pooled_width,
},
)
return out
def pixel_shuffle(x, upscale_factor): def pixel_shuffle(x, upscale_factor):
""" """
......
...@@ -1090,7 +1090,6 @@ set_tests_properties(test_parallel_executor_mnist PROPERTIES TIMEOUT 120) ...@@ -1090,7 +1090,6 @@ set_tests_properties(test_parallel_executor_mnist PROPERTIES TIMEOUT 120)
set_tests_properties(test_imperative_ptb_rnn PROPERTIES TIMEOUT 120) set_tests_properties(test_imperative_ptb_rnn PROPERTIES TIMEOUT 120)
set_tests_properties(test_imperative_save_load_v2 PROPERTIES TIMEOUT 120) set_tests_properties(test_imperative_save_load_v2 PROPERTIES TIMEOUT 120)
set_tests_properties(test_conv2d_transpose_op PROPERTIES TIMEOUT 120) set_tests_properties(test_conv2d_transpose_op PROPERTIES TIMEOUT 120)
set_tests_properties(test_prroi_pool_op PROPERTIES TIMEOUT 120)
set_tests_properties(test_multiprocess_dataloader_iterable_dataset_static set_tests_properties(test_multiprocess_dataloader_iterable_dataset_static
PROPERTIES TIMEOUT 120) PROPERTIES TIMEOUT 120)
set_tests_properties(test_lstm_cudnn_op PROPERTIES TIMEOUT 120) set_tests_properties(test_lstm_cudnn_op PROPERTIES TIMEOUT 120)
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import numpy as np
from inference_pass_test import InferencePassTest
import paddle.fluid as fluid
import paddle.fluid.core as core
from paddle.fluid.core import AnalysisConfig, PassVersionChecker
class TRTRoiAlignTest(InferencePassTest):
def setUp(self):
self.bs = 2
self.num_rois = 4
self.channel = 8
self.height = 16
self.width = 16
self.precision = AnalysisConfig.Precision.Float32
self.serialize = False
self.enable_trt = True
def build(self):
self.trt_parameters = TRTRoiAlignTest.TensorRTParam(
1 << 30,
self.bs * self.num_rois,
1,
self.precision,
self.serialize,
False,
)
with fluid.program_guard(self.main_program, self.startup_program):
data_shape = [-1, self.channel, self.height, self.width]
data = fluid.data(name='data', shape=data_shape, dtype='float32')
rois = fluid.data(
name='rois', shape=[-1, 4], dtype='float32', lod_level=1
)
roi_align_out = fluid.layers.roi_align(data, rois)
out = fluid.layers.batch_norm(roi_align_out, is_test=True)
rois_lod = fluid.create_lod_tensor(
np.random.random([self.bs * self.num_rois, 4]).astype('float32'),
[[self.num_rois, self.num_rois]],
fluid.CPUPlace(),
)
data_shape[0] = self.bs
self.feeds = {
'data': np.random.random(data_shape).astype('float32'),
'rois': rois_lod,
}
self.fetch_list = [out]
def check_output(self):
if core.is_compiled_with_cuda():
use_gpu = True
atol = 1e-5
if self.trt_parameters.precision == AnalysisConfig.Precision.Half:
atol = 1e-3
self.check_output_with_option(use_gpu, atol, flatten=True)
self.assertTrue(
PassVersionChecker.IsCompatible('tensorrt_subgraph_pass')
)
def set_dynamic(self):
min_shape_spec = dict()
max_shape_spec = dict()
opt_shape_spec = dict()
min_shape_spec['data'] = [
self.bs,
self.channel,
self.height // 2,
self.width // 2,
]
min_shape_spec['rois'] = [1, 4]
max_shape_spec['data'] = [
self.bs,
self.channel,
self.height * 2,
self.width * 2,
]
max_shape_spec['rois'] = [self.bs * self.num_rois, 4]
opt_shape_spec['data'] = [
self.bs,
self.channel,
self.height,
self.width,
]
opt_shape_spec['rois'] = [self.bs * self.num_rois, 4]
self.dynamic_shape_params = InferencePassTest.DynamicShapeParam(
min_shape_spec, max_shape_spec, opt_shape_spec, False
)
def run_test(self):
self.build()
self.check_output()
def test_base(self):
self.run_test()
def test_fp16(self):
self.precision = AnalysisConfig.Precision.Half
self.run_test()
def test_serialize(self):
self.serialize = True
self.run_test()
def test_dynamic(self):
self.set_dynamic()
self.run_test()
def test_dynamic_fp16(self):
self.set_dynamic()
self.precision = AnalysisConfig.Precision.Half
self.run_test()
def test_dynamic_serialize(self):
self.set_dynamic()
self.serialize = True
self.run_test()
if __name__ == "__main__":
unittest.main()
...@@ -3841,16 +3841,6 @@ class TestBook(LayerTest): ...@@ -3841,16 +3841,6 @@ class TestBook(LayerTest):
) )
return out return out
def test_psroi_pool(self):
# TODO(minqiyang): dygraph do not support lod now
with self.static_graph():
x = layers.data(name="x", shape=[245, 30, 30], dtype="float32")
rois = layers.data(
name="rois", shape=[4], dtype="float32", lod_level=1
)
output = layers.psroi_pool(x, rois, 5, 0.25, 7, 7)
return output
def test_sequence_expand(self): def test_sequence_expand(self):
# TODO(minqiyang): dygraph do not support lod now # TODO(minqiyang): dygraph do not support lod now
with self.static_graph(): with self.static_graph():
...@@ -3990,82 +3980,12 @@ class TestBook(LayerTest): ...@@ -3990,82 +3980,12 @@ class TestBook(LayerTest):
) )
return out return out
def test_roi_pool(self):
x_np = np.random.rand(2, 3, 8, 8).astype('float32')
rois_np = np.random.rand(3, 4).astype('float32')
rois_num_np = np.array([1, 2]).astype('int32')
with self.static_graph():
x = layers.data(name="x", shape=[3, 8, 8], dtype="float32")
rois = layers.data(name="rois", shape=[4], dtype="float32")
rois_num = fluid.data(name="rois_num", shape=[None], dtype="int32")
output = layers.roi_pool(x, rois, 4, 4, 0.5, rois_num=rois_num)
static_res = self.get_static_graph_result(
feed={'x': x_np, 'rois': rois_np, 'rois_num': rois_num_np},
fetch_list=[output],
)[0]
with self.dynamic_graph():
with _test_eager_guard():
x_dy = base.to_variable(x_np)
rois_dy = base.to_variable(rois_np)
rois_num_dy = base.to_variable(rois_num_np)
dy_eager_res = layers.roi_pool(
x_dy, rois_dy, 4, 4, 0.5, rois_num=rois_num_dy
)
dy_eager_res_value = dy_eager_res[0].numpy()
x_dy = base.to_variable(x_np)
rois_dy = base.to_variable(rois_np)
rois_num_dy = base.to_variable(rois_num_np)
dy_res = layers.roi_pool(
x_dy, rois_dy, 4, 4, 0.5, rois_num=rois_num_dy
)
dy_res_value = dy_res[0].numpy()
np.testing.assert_array_equal(static_res, dy_res_value)
np.testing.assert_array_equal(static_res, dy_eager_res_value)
def test_sequence_enumerate(self): def test_sequence_enumerate(self):
# TODO(minqiyang): dygraph do not support lod now # TODO(minqiyang): dygraph do not support lod now
with self.static_graph(): with self.static_graph():
x = layers.data(name="input", shape=[1], dtype='int32', lod_level=1) x = layers.data(name="input", shape=[1], dtype='int32', lod_level=1)
out = layers.sequence_enumerate(input=x, win_size=2, pad_value=0) out = layers.sequence_enumerate(input=x, win_size=2, pad_value=0)
def test_roi_align(self):
x_np = np.random.rand(2, 3, 8, 8).astype('float32')
rois_np = np.random.rand(3, 4).astype('float32')
rois_num_np = np.array([1, 2]).astype('int32')
with self.static_graph():
x = layers.data(name="x", shape=[3, 8, 8], dtype="float32")
rois = layers.data(name="rois", shape=[4], dtype="float32")
rois_num = fluid.data(name="rois_num", shape=[None], dtype="int32")
output = layers.roi_align(x, rois, 4, 4, 0.5, 2, rois_num=rois_num)
static_res = self.get_static_graph_result(
feed={'x': x_np, 'rois': rois_np, 'rois_num': rois_num_np},
fetch_list=[output],
)[0]
with self.dynamic_graph():
with _test_eager_guard():
x_dy = base.to_variable(x_np)
rois_dy = base.to_variable(rois_np)
rois_num_dy = base.to_variable(rois_num_np)
dy_eager_res = layers.roi_align(
x_dy, rois_dy, 4, 4, 0.5, 2, rois_num=rois_num_dy
)
dy_eager_res_value = dy_eager_res.numpy()
x_dy = base.to_variable(x_np)
rois_dy = base.to_variable(rois_np)
rois_num_dy = base.to_variable(rois_num_np)
dy_res = layers.roi_align(
x_dy, rois_dy, 4, 4, 0.5, 2, rois_num=rois_num_dy
)
dy_res_value = dy_res.numpy()
np.testing.assert_array_equal(static_res, dy_eager_res_value)
np.testing.assert_array_equal(static_res, dy_res_value)
def test_roi_perspective_transform(self): def test_roi_perspective_transform(self):
# TODO(minqiyang): dygraph do not support lod now # TODO(minqiyang): dygraph do not support lod now
with self.static_graph(): with self.static_graph():
......
# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import numpy as np
import unittest
from py_precise_roi_pool import PyPrRoIPool
from op_test import OpTest
import paddle
import paddle.fluid as fluid
from paddle.fluid import Program, program_guard
class TestPRROIPoolOp(OpTest):
def set_data(self):
self.init_test_case()
self.make_rois()
self.prRoIPool = PyPrRoIPool()
self.outs = self.prRoIPool.compute(
self.x,
self.rois,
self.output_channels,
self.spatial_scale,
self.pooled_height,
self.pooled_width,
).astype('float32')
self.inputs = {'X': self.x, 'ROIs': (self.rois[:, 1:5], self.rois_lod)}
self.attrs = {
'output_channels': self.output_channels,
'spatial_scale': self.spatial_scale,
'pooled_height': self.pooled_height,
'pooled_width': self.pooled_width,
}
self.outputs = {'Out': self.outs}
def init_test_case(self):
self.batch_size = 3
self.channels = 3 * 2 * 2
self.height = 12
self.width = 16
self.x_dim = [self.batch_size, self.channels, self.height, self.width]
self.spatial_scale = 1.0 / 2.0
self.output_channels = self.channels
self.pooled_height = 4
self.pooled_width = 4
self.x = np.random.random(self.x_dim).astype('float32')
def make_rois(self):
rois = []
self.rois_lod = [[]]
for bno in range(self.batch_size):
self.rois_lod[0].append(bno + 1)
for i in range(bno + 1):
x1 = np.random.uniform(
0, self.width // self.spatial_scale - self.pooled_width
)
y1 = np.random.uniform(
0, self.height // self.spatial_scale - self.pooled_height
)
x2 = np.random.uniform(
x1 + self.pooled_width, self.width // self.spatial_scale
)
y2 = np.random.uniform(
y1 + self.pooled_height, self.height // self.spatial_scale
)
roi = [bno, x1, y1, x2, y2]
rois.append(roi)
self.rois_num = len(rois)
self.rois = np.array(rois).astype('float32')
def setUp(self):
self.op_type = 'prroi_pool'
self.set_data()
def test_check_output(self):
self.check_output(check_eager=True)
def test_backward(self):
places = [fluid.CPUPlace()]
if fluid.core.is_compiled_with_cuda():
places.append(fluid.CUDAPlace(0))
for place in places:
self.check_grad_with_place(place, ['X'], 'Out', check_eager=True)
def run_net(self, place):
with program_guard(Program(), Program()):
x = fluid.layers.data(
name="X",
shape=[self.channels, self.height, self.width],
dtype="float32",
)
rois = fluid.layers.data(
name="ROIs", shape=[4], dtype="float32", lod_level=1
)
output = fluid.layers.prroi_pool(x, rois, 0.25, 2, 2)
loss = paddle.mean(output)
optimizer = fluid.optimizer.SGD(learning_rate=1e-3)
optimizer.minimize(loss)
input_x = fluid.create_lod_tensor(self.x, [], place)
input_rois = fluid.create_lod_tensor(
self.rois[:, 1:5], self.rois_lod, place
)
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
exe.run(
fluid.default_main_program(), {'X': input_x, "ROIs": input_rois}
)
def test_net(self):
places = [fluid.CPUPlace()]
if fluid.core.is_compiled_with_cuda():
places.append(fluid.CUDAPlace(0))
for place in places:
self.run_net(place)
def test_errors(self):
with program_guard(Program(), Program()):
x = fluid.layers.data(
name="x", shape=[245, 30, 30], dtype="float32"
)
rois = fluid.layers.data(
name="rois", shape=[4], dtype="float32", lod_level=1
)
# spatial_scale must be float type
self.assertRaises(
TypeError, fluid.layers.prroi_pool, x, rois, 2, 7, 7
)
# pooled_height must be int type
self.assertRaises(
TypeError, fluid.layers.prroi_pool, x, rois, 0.25, 0.7, 7
)
# pooled_width must be int type
self.assertRaises(
TypeError, fluid.layers.prroi_pool, x, rois, 0.25, 7, 0.7
)
class TestPRROIPoolOpTensorRoIs(OpTest):
def set_data(self):
self.init_test_case()
self.make_rois()
self.prRoIPool = PyPrRoIPool()
self.outs = self.prRoIPool.compute(
self.x,
self.rois,
self.output_channels,
self.spatial_scale,
self.pooled_height,
self.pooled_width,
).astype('float32')
self.rois_index = np.array(self.rois_lod).reshape([-1]).astype(np.int64)
self.inputs = {
'X': self.x,
'ROIs': self.rois[:, 1:5],
'BatchRoINums': self.rois_index,
}
self.attrs = {
'output_channels': self.output_channels,
'spatial_scale': self.spatial_scale,
'pooled_height': self.pooled_height,
'pooled_width': self.pooled_width,
}
self.outputs = {'Out': self.outs}
def init_test_case(self):
self.batch_size = 3
self.channels = 3 * 2 * 2
self.height = 12
self.width = 16
self.x_dim = [self.batch_size, self.channels, self.height, self.width]
self.spatial_scale = 1.0 / 2.0
self.output_channels = self.channels
self.pooled_height = 4
self.pooled_width = 4
self.x = np.random.random(self.x_dim).astype('float32')
def make_rois(self):
rois = []
self.rois_lod = []
for bno in range(self.batch_size):
self.rois_lod.append(bno + 1)
for i in range(bno + 1):
x1 = np.random.uniform(
0, self.width // self.spatial_scale - self.pooled_width
)
y1 = np.random.uniform(
0, self.height // self.spatial_scale - self.pooled_height
)
x2 = np.random.uniform(
x1 + self.pooled_width, self.width // self.spatial_scale
)
y2 = np.random.uniform(
y1 + self.pooled_height, self.height // self.spatial_scale
)
roi = [bno, x1, y1, x2, y2]
rois.append(roi)
self.rois_num = len(rois)
self.rois = np.array(rois).astype('float32')
def setUp(self):
self.op_type = 'prroi_pool'
self.set_data()
def test_check_output(self):
self.check_output(check_eager=True)
def test_backward(self):
places = [fluid.CPUPlace()]
if fluid.core.is_compiled_with_cuda():
places.append(fluid.CUDAPlace(0))
for place in places:
self.check_grad_with_place(place, ['X'], 'Out', check_eager=True)
def run_net(self, place):
with program_guard(Program(), Program()):
x = fluid.layers.data(
name="X",
shape=[self.channels, self.height, self.width],
dtype="float32",
)
rois = fluid.layers.data(name="ROIs", shape=[4], dtype="float32")
rois_index = fluid.layers.data(
name='rois_idx', shape=[], dtype="int64"
)
output = fluid.layers.prroi_pool(
x, rois, 0.25, 2, 2, batch_roi_nums=rois_index
)
loss = paddle.mean(output)
optimizer = fluid.optimizer.SGD(learning_rate=1e-3)
optimizer.minimize(loss)
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
exe.run(
fluid.default_main_program(),
{
'X': self.x,
"ROIs": self.rois[:, 1:5],
"rois_idx": self.rois_index,
},
)
def test_net(self):
places = [fluid.CPUPlace()]
if fluid.core.is_compiled_with_cuda():
places.append(fluid.CUDAPlace(0))
for place in places:
self.run_net(place)
def test_errors(self):
with program_guard(Program(), Program()):
x = fluid.layers.data(
name="x", shape=[245, 30, 30], dtype="float32"
)
rois = fluid.layers.data(
name="rois", shape=[4], dtype="float32", lod_level=1
)
# spatial_scale must be float type
self.assertRaises(
TypeError, fluid.layers.prroi_pool, x, rois, 2, 7, 7
)
# pooled_height must be int type
self.assertRaises(
TypeError, fluid.layers.prroi_pool, x, rois, 0.25, 0.7, 7
)
# pooled_width must be int type
self.assertRaises(
TypeError, fluid.layers.prroi_pool, x, rois, 0.25, 7, 0.7
)
def test_bad_x():
x = fluid.layers.data(
name='data1',
shape=[2, 3, 16, 16],
dtype='int64',
append_batch_size=False,
)
label = fluid.layers.data(
name='label1',
shape=[2, 4],
dtype='float32',
lod_level=1,
append_batch_size=False,
)
output = fluid.layers.prroi_pool(x, label, 0.25, 2, 2)
self.assertRaises(TypeError, test_bad_x)
def test_bad_y():
x = fluid.layers.data(
name='data2',
shape=[2, 3, 16, 16],
dtype='float32',
append_batch_size=False,
)
label = [[1, 2, 3, 4], [2, 3, 4, 5]]
output = fluid.layers.prroi_pool(x, label, 0.25, 2, 2)
self.assertRaises(TypeError, test_bad_y)
if __name__ == '__main__':
import paddle
paddle.enable_static()
unittest.main()
...@@ -18,7 +18,6 @@ import numpy as np ...@@ -18,7 +18,6 @@ import numpy as np
import math import math
import sys import sys
from op_test import OpTest from op_test import OpTest
import paddle.fluid as fluid
from decimal import Decimal, ROUND_HALF_UP from decimal import Decimal, ROUND_HALF_UP
...@@ -176,34 +175,6 @@ class TestROIPoolOp(OpTest): ...@@ -176,34 +175,6 @@ class TestROIPoolOp(OpTest):
self.check_grad(['X'], 'Out', check_eager=True) self.check_grad(['X'], 'Out', check_eager=True)
class BadInputTestRoiPool(unittest.TestCase):
def test_error(self):
with fluid.program_guard(fluid.Program()):
def test_bad_x():
x = fluid.layers.data(
name='data1', shape=[2, 1, 4, 4], dtype='int64'
)
label = fluid.layers.data(
name='label', shape=[2, 4], dtype='float32', lod_level=1
)
output = fluid.layers.roi_pool(x, label, 1, 1, 1.0)
self.assertRaises(TypeError, test_bad_x)
def test_bad_y():
x = fluid.layers.data(
name='data2',
shape=[2, 1, 4, 4],
dtype='float32',
append_batch_size=False,
)
label = [[1, 2, 3, 4], [2, 3, 4, 5]]
output = fluid.layers.roi_pool(x, label, 1, 1, 1.0)
self.assertRaises(TypeError, test_bad_y)
class TestROIPoolInLodOp(TestROIPoolOp): class TestROIPoolInLodOp(TestROIPoolOp):
def set_data(self): def set_data(self):
self.init_test_case() self.init_test_case()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册