未验证 提交 350d20fe 编写于 作者: F FDInSky 提交者: GitHub

[cherry-pick] interpolate api doc (#24685)

* test=develop update interpolate & upsample api
上级 a9050465
...@@ -7051,6 +7051,8 @@ def image_resize(input, ...@@ -7051,6 +7051,8 @@ def image_resize(input,
'NEAREST' : Nearest neighbor interpolation 'NEAREST' : Nearest neighbor interpolation
'BICUBIC' : Bicubic interpolation
Linear interpolation is the method of using a line connecting two known quantities Linear interpolation is the method of using a line connecting two known quantities
to determine the value of an unknown quantity between the two known quantities. to determine the value of an unknown quantity between the two known quantities.
...@@ -7069,6 +7071,11 @@ def image_resize(input, ...@@ -7069,6 +7071,11 @@ def image_resize(input,
H-direction and W-direction in this op) on a rectilinear 3D grid. H-direction and W-direction in this op) on a rectilinear 3D grid.
The linear interpolation is performed on three directions. The linear interpolation is performed on three directions.
Bicubic interpolation is an extension of cubic interpolation for interpolating
data points on a two-dimensional regular grid. The interpolated surface is
smoother than corresponding surfaces obtained by bilinear interpolation or
nearest-neighbor interpolation.
Align_corners and align_mode are optional parameters,the calculation method Align_corners and align_mode are optional parameters,the calculation method
of interpolation can be selected by them. of interpolation can be selected by them.
...@@ -7162,9 +7169,26 @@ def image_resize(input, ...@@ -7162,9 +7169,26 @@ def image_resize(input,
output: (N,C,D_out,H_out,W_out) where: output: (N,C,D_out,H_out,W_out) where:
D_out = D_{in} * scale_{factor} D_out = D_{in} * scale_{factor}
Trilinear interpolation:
if:
align_corners = False , align_mode = 0
input : (N,C,D_in,H_in,W_in)
output: (N,C,D_out,H_out,W_out) where:
D_out = (D_{in}+0.5) * scale_{factor} - 0.5
H_out = (H_{in}+0.5) * scale_{factor} - 0.5
W_out = (W_{in}+0.5) * scale_{factor} - 0.5
else:
input : (N,C,D_in,H_in,W_in)
output: (N,C,D_out,H_out,W_out) where:
D_out = D_{in} * scale_{factor}
H_out = H_{in} * scale_{factor} H_out = H_{in} * scale_{factor}
W_out = W_{in} * scale_{factor} W_out = W_{in} * scale_{factor}
For details of linear interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Linear_interpolation.
For details of nearest neighbor interpolation, please refer to Wikipedia: For details of nearest neighbor interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation. https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation.
...@@ -7174,15 +7198,16 @@ def image_resize(input, ...@@ -7174,15 +7198,16 @@ def image_resize(input,
For details of trilinear interpolation, please refer to Wikipedia: For details of trilinear interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Trilinear_interpolation. https://en.wikipedia.org/wiki/Trilinear_interpolation.
For details of bicubic interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Bicubic_interpolation
Parameters: Parameters:
input (Variable): 4-D or 5-D Tensor, its data type is float32, float64, or uint8, input (Variable): 3-D, 4-D or 5-D Tensor, its data type is float32, float64, or uint8,
its data format is specified by :attr:`data_format`. its data format is specified by :attr:`data_format`.
out_shape(list|tuple|Variable|None): Output shape of image resize out_shape (list|tuple|Variable|None): Output shape of image resize
layer, the shape is (out_h, out_w) when input is a 4-D Tensor and is layer, the shape is (out_w, ) when input is a 3-D Tensor, the shape is (out_h, out_w)
(out_d, out_h, out_w) when input is a 5-D Tensor. Default: None. If when input is a 4-D Tensor and is (out_d, out_h, out_w) when input is a 5-D Tensor.
a list, each element can be an integer or a Tensor Variable of shape: [1]. Default: None. If a list, each element can be an integer or a Tensor Variable of shape: [1].
If a Tensor Variable, its dimensions size should be a 1. If a Tensor Variable, its dimensions size should be a 1.
scale(float|Variable|None): The multiplier for the input height or width. At scale(float|Variable|None): The multiplier for the input height or width. At
least one of :attr:`out_shape` or :attr:`scale` must be set. least one of :attr:`out_shape` or :attr:`scale` must be set.
...@@ -7190,7 +7215,7 @@ def image_resize(input, ...@@ -7190,7 +7215,7 @@ def image_resize(input,
Default: None. Default: None.
name(str|None): A name for this layer(optional). If set None, the layer name(str|None): A name for this layer(optional). If set None, the layer
will be named automatically. will be named automatically.
resample(str): The resample method. It supports 'BILINEAR', 'TRILINEAR' resample(str): The resample method. It supports 'LINEAR', 'BICUBIC', 'BILINEAR', 'TRILINEAR'
and 'NEAREST' currently. Default: 'BILINEAR' and 'NEAREST' currently. Default: 'BILINEAR'
actual_shape(Variable): An optional input to specify output shape actual_shape(Variable): An optional input to specify output shape
dynamically. If provided, image resize dynamically. If provided, image resize
...@@ -7209,26 +7234,27 @@ def image_resize(input, ...@@ -7209,26 +7234,27 @@ def image_resize(input,
input and output tensors are aligned, preserving the values at the input and output tensors are aligned, preserving the values at the
corner pixels. corner pixels.
Default: True Default: True
align_mode(int) : An optional for bilinear interpolation. can be \'0\' align_mode(int) : An optional for linear/bilinear/trilinear interpolation. Refer to the fomula in the
for src_idx = scale*(dst_indx+0.5)-0.5 , can be \'1\' for the example code above, it can be \'0\' for src_idx = scale*(dst_indx+0.5)-0.5 ,
src_idx = scale*dst_index. can be \'1\' for src_idx = scale*dst_index.
data_format (str, optional): Specify the data format of the input, and the data format of the output data_format (str, optional): Specify the data format of the input, and the data format of the output
will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`, `"NCDHW"`, will be consistent with that of the input. An optional string from:`NCW`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`,
`"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of: `"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
`[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored `[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored
in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`. in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`.
Returns: Returns:
A 3-D Tensor of the shape (num_batches, channels, out_w) or (num_batches, out_w, channels),
A 4-D Tensor of the shape (num_batches, channels, out_h, out_w) or (num_batches, out_h, out_w, channels), A 4-D Tensor of the shape (num_batches, channels, out_h, out_w) or (num_batches, out_h, out_w, channels),
or 5-D Tensor of the shape (num_batches, channels, out_d, out_h, out_w) or (num_batches, out_d, out_h, out_w, channels). or 5-D Tensor of the shape (num_batches, channels, out_d, out_h, out_w) or (num_batches, out_d, out_h, out_w, channels).
Raises: Raises:
TypeError: out_shape should be a list or tuple or Variable. TypeError: out_shape should be a list or tuple or Variable.
TypeError: actual_shape should either be Variable or None. TypeError: actual_shape should either be Variable or None.
ValueError: The 'resample' of image_resize can only be 'BILINEAR', ValueError: The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR',
'TRILINEAR' or 'NEAREST' currently. 'TRILINEAR', 'BICUBIC' or 'NEAREST' currently.
ValueError: 'LINEAR' only support 3-D tensor. ValueError: 'LINEAR' only support 3-D tensor.
ValueError: 'BILINEAR' and 'NEAREST' only support 4-D tensor. ValueError: 'BICUBIC', 'BILINEAR' and 'NEAREST' only support 4-D tensor.
ValueError: 'TRILINEAR' only support 5-D tensor. ValueError: 'TRILINEAR' only support 5-D tensor.
ValueError: One of out_shape and scale must not be None. ValueError: One of out_shape and scale must not be None.
ValueError: out_shape length should be 1 for input 3-D tensor. ValueError: out_shape length should be 1 for input 3-D tensor.
...@@ -7237,7 +7263,7 @@ def image_resize(input, ...@@ -7237,7 +7263,7 @@ def image_resize(input,
ValueError: scale should be greater than zero. ValueError: scale should be greater than zero.
TypeError: align_corners should be a bool value TypeError: align_corners should be a bool value
ValueError: align_mode can only be '0' or '1' ValueError: align_mode can only be '0' or '1'
ValueError: data_format can only be 'NCW', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'. ValueError: data_format can only be 'NCW', 'NWC', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'.
Examples: Examples:
.. code-block:: python .. code-block:: python
...@@ -7332,10 +7358,10 @@ def image_resize(input, ...@@ -7332,10 +7358,10 @@ def image_resize(input,
helper = LayerHelper('{}_interp'.format(resample_type), **locals()) helper = LayerHelper('{}_interp'.format(resample_type), **locals())
dtype = helper.input_dtype() dtype = helper.input_dtype()
if len(input.shape) == 3 and data_format not in ['NCHW', 'NHWC']: if len(input.shape) == 3 and data_format not in ['NCW', 'NWC']:
raise ValueError( raise ValueError(
"Got wrong value for param `data_format`: " + data_format + "Got wrong value for param `data_format`: " + data_format +
" received but only `NCHW` or `NHWC` supported for 3-D input.") " received but only `NCW` or `NWC` supported for 3-D input.")
elif len(input.shape) == 4 and data_format not in ['NCHW', 'NHWC']: elif len(input.shape) == 4 and data_format not in ['NCHW', 'NHWC']:
raise ValueError( raise ValueError(
"Got wrong value for param `data_format`: " + data_format + "Got wrong value for param `data_format`: " + data_format +
...@@ -7348,9 +7374,9 @@ def image_resize(input, ...@@ -7348,9 +7374,9 @@ def image_resize(input,
def _is_list_or_turple_(data): def _is_list_or_turple_(data):
return (isinstance(data, list) or isinstance(data, tuple)) return (isinstance(data, list) or isinstance(data, tuple))
if data_format == 'NCHW' or data_format == 'NCDHW': if data_format == 'NCHW' or data_format == 'NCDHW' or data_format == 'NCW':
data_layout = 'NCHW' data_layout = 'NCHW'
if data_format == 'NHWC' or data_format == 'NDHWC': if data_format == 'NHWC' or data_format == 'NDHWC' or data_format == 'NWC':
data_layout = 'NHWC' data_layout = 'NHWC'
inputs = {"X": input} inputs = {"X": input}
...@@ -7472,7 +7498,7 @@ def resize_linear(input, ...@@ -7472,7 +7498,7 @@ def resize_linear(input,
actual_shape=None, actual_shape=None,
align_corners=True, align_corners=True,
align_mode=1, align_mode=1,
data_format='NCHW'): data_format='NCW'):
""" """
This op resizes the input by performing linear interpolation based on given This op resizes the input by performing linear interpolation based on given
output shape which specified by actual_shape, out_shape and scale output shape which specified by actual_shape, out_shape and scale
...@@ -7515,7 +7541,7 @@ def resize_linear(input, ...@@ -7515,7 +7541,7 @@ def resize_linear(input,
W_out = W_{in} * scale_{factor} W_out = W_{in} * scale_{factor}
Parameters: Parameters:
input(Variable): 3-D Tensor(NCHW), its data type is float32, float64, or uint8, input(Variable): 3-D Tensor(NCW), its data type is float32, float64, or uint8,
its data format is specified by :attr:`data_format`. its data format is specified by :attr:`data_format`.
out_shape(list|tuple|Variable|None): Output shape of resize linear out_shape(list|tuple|Variable|None): Output shape of resize linear
layer, the shape is (out_w,). Default: None. If a list, each layer, the shape is (out_w,). Default: None. If a list, each
...@@ -7541,13 +7567,14 @@ def resize_linear(input, ...@@ -7541,13 +7567,14 @@ def resize_linear(input,
align_corners(bool): ${align_corners_comment} align_corners(bool): ${align_corners_comment}
align_mode(bool): ${align_mode_comment} align_mode(bool): ${align_mode_comment}
data_format (str, optional): Specify the data format of the input, and the data format of the output data_format (str, optional): Specify the data format of the input, and the data format of the output
will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`. will be consistent with that of the input. An optional string from: `"NCW"`, `"NWC"`.
The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of: The default is `"NCW"`. When it is `"NCW"`, the data is stored in the order of:
`[batch_size, input_channels, input_height, input_width]`. `[batch_size, input_channels, input_width]`.
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` 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: Returns:
Variable: 3-D tensor(NCHW or NHWC). Variable: 3-D tensor(NCW or NWC).
Examples: Examples:
.. code-block:: python .. code-block:: python
......
...@@ -290,22 +290,18 @@ class TestBicubicInterpOpAPI(unittest.TestCase): ...@@ -290,22 +290,18 @@ class TestBicubicInterpOpAPI(unittest.TestCase):
name="scale_tensor", shape=[1], dtype="float32") name="scale_tensor", shape=[1], dtype="float32")
out1 = interpolate( out1 = interpolate(
x, out_shape=[12, 12], resample='BICUBIC', align_corners=False) x, size=[12, 12], mode='bicubic', align_corners=False)
out2 = interpolate( out2 = interpolate(
x, out_shape=[12, dim], resample='BICUBIC', align_corners=False) x, size=[12, dim], mode='bicubic', align_corners=False)
out3 = interpolate( out3 = interpolate(
x, x, size=shape_tensor, mode='bicubic', align_corners=False)
out_shape=shape_tensor,
resample='BICUBIC',
align_corners=False)
out4 = interpolate( out4 = interpolate(
x, size=[12, 12], mode='bicubic', align_corners=False)
out5 = interpolate(
x, x,
out_shape=[4, 4], scale_factor=scale_tensor,
actual_shape=actual_size, mode='bicubic',
resample='BICUBIC',
align_corners=False) align_corners=False)
out5 = interpolate(
x, scale=scale_tensor, resample='BICUBIC', align_corners=False)
exe = fluid.Executor(place) exe = fluid.Executor(place)
exe.run(fluid.default_startup_program()) exe.run(fluid.default_startup_program())
...@@ -328,7 +324,7 @@ class TestBicubicInterpOpAPI(unittest.TestCase): ...@@ -328,7 +324,7 @@ class TestBicubicInterpOpAPI(unittest.TestCase):
with fluid.dygraph.guard(): with fluid.dygraph.guard():
x = fluid.dygraph.to_variable(x_data) x = fluid.dygraph.to_variable(x_data)
interp = interpolate( interp = interpolate(
x, out_shape=[12, 12], resample='BICUBIC', align_corners=False) x, size=[12, 12], mode='bicubic', align_corners=False)
dy_result = interp.numpy() dy_result = interp.numpy()
expect = bicubic_interp_np( expect = bicubic_interp_np(
x_data, out_h=12, out_w=12, align_corners=False) x_data, out_h=12, out_w=12, align_corners=False)
...@@ -348,28 +344,21 @@ class TestBicubicOpError(unittest.TestCase): ...@@ -348,28 +344,21 @@ class TestBicubicOpError(unittest.TestCase):
x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32") x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32")
out = interpolate( out = interpolate(
x, x, size=[12, 12], mode='UNKONWN', align_corners=False)
out_shape=[12, 12],
resample='UNKONWN',
align_corners=False)
def test_input_shape(): def test_input_shape():
x = fluid.data(name="x", shape=[2], dtype="float32") x = fluid.data(name="x", shape=[2], dtype="float32")
out = interpolate( out = interpolate(
x, x, size=[12, 12], mode='BICUBIC', align_corners=False)
out_shape=[12, 12],
resample='BICUBIC',
align_corners=False)
def test_align_corcers(): def test_align_corcers():
x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32") x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32")
interpolate( interpolate(x, size=[12, 12], mode='BICUBIC', align_corners=3)
x, out_shape=[12, 12], resample='BICUBIC', align_corners=3)
def test_out_shape(): def test_out_shape():
x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32") x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32")
out = interpolate( out = interpolate(
x, out_shape=[12], resample='BICUBIC', align_corners=False) x, size=[12], mode='bicubic', align_corners=False)
def test_attr_data_format(): def test_attr_data_format():
# for 5-D input, data_format only can be NCDHW or NDHWC # for 5-D input, data_format only can be NCDHW or NDHWC
...@@ -377,8 +366,8 @@ class TestBicubicOpError(unittest.TestCase): ...@@ -377,8 +366,8 @@ class TestBicubicOpError(unittest.TestCase):
name="input", shape=[2, 3, 6, 9, 4], dtype="float32") name="input", shape=[2, 3, 6, 9, 4], dtype="float32")
out = interpolate( out = interpolate(
input, input,
out_shape=[4, 8, 4, 5], size=[4, 8, 4, 5],
resample='TRILINEAR', mode='trilinear',
data_format='NHWC') data_format='NHWC')
def test_actual_shape(): def test_actual_shape():
...@@ -386,20 +375,17 @@ class TestBicubicOpError(unittest.TestCase): ...@@ -386,20 +375,17 @@ class TestBicubicOpError(unittest.TestCase):
x = fluid.create_lod_tensor( x = fluid.create_lod_tensor(
np.array([-1, 3, 5, 5]), [[1, 1, 1, 1]], fluid.CPUPlace()) np.array([-1, 3, 5, 5]), [[1, 1, 1, 1]], fluid.CPUPlace())
out = interpolate( out = interpolate(
x, x, size=[12, 12], mode='BICUBIC', align_corners=False)
out_shape=[12, 12],
resample='BICUBIC',
align_corners=False)
def test_scale_value(): def test_scale_value():
# the scale must be greater than zero. # the scale must be greater than zero.
x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32") x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32")
out = interpolate( out = interpolate(
x, x,
out_shape=None, size=None,
resample='BICUBIC', mode='BICUBIC',
align_corners=False, align_corners=False,
scale=-2.0) scale_factor=-2.0)
def test_attr_5D_input(): def test_attr_5D_input():
# for 5-D input, data_format only can be NCDHW or NDHWC # for 5-D input, data_format only can be NCDHW or NDHWC
...@@ -407,8 +393,8 @@ class TestBicubicOpError(unittest.TestCase): ...@@ -407,8 +393,8 @@ class TestBicubicOpError(unittest.TestCase):
name="input", shape=[2, 3, 6, 9, 4], dtype="float32") name="input", shape=[2, 3, 6, 9, 4], dtype="float32")
out = interpolate( out = interpolate(
input, input,
out_shape=[4, 8, 4, 5], size=[4, 8, 4, 5],
resample='TRILINEAR', mode='trilinear',
data_format='NDHWC') data_format='NDHWC')
def test_scale_type(): def test_scale_type():
...@@ -418,29 +404,29 @@ class TestBicubicOpError(unittest.TestCase): ...@@ -418,29 +404,29 @@ class TestBicubicOpError(unittest.TestCase):
np.array([-1, 3, 5, 5]), [[1, 1, 1, 1]], fluid.CPUPlace()) np.array([-1, 3, 5, 5]), [[1, 1, 1, 1]], fluid.CPUPlace())
out = interpolate( out = interpolate(
x, x,
out_shape=None, size=None,
resample='BICUBIC', mode='bicubic',
align_corners=False, align_corners=False,
scale=scale) scale_factor=scale)
def test_align_mode(): def test_align_mode():
x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32") x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32")
out = interpolate( out = interpolate(
x, x,
out_shape=None, size=None,
resample='NEAREST', mode='nearest',
align_corners=False, align_corners=False,
align_mode=2, align_mode=2,
scale=1.0) scale_factor=1.0)
def test_outshape_and_scale(): def test_outshape_and_scale():
x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32") x = fluid.data(name="x", shape=[2, 3, 6, 6], dtype="float32")
out = interpolate( out = interpolate(
x, x,
out_shape=None, size=None,
resample='BICUBIC', mode='bicubic',
align_corners=False, align_corners=False,
scale=None) scale_factor=None)
self.assertRaises(ValueError, test_mode_type) self.assertRaises(ValueError, test_mode_type)
self.assertRaises(ValueError, test_input_shape) self.assertRaises(ValueError, test_input_shape)
......
...@@ -211,106 +211,58 @@ class TestLinearInterpOpSizeTensor(TestLinearInterpOp): ...@@ -211,106 +211,58 @@ class TestLinearInterpOpSizeTensor(TestLinearInterpOp):
self.outputs = {'Out': output_np} self.outputs = {'Out': output_np}
class TestLinearInterpOpAPI(unittest.TestCase): class TestResizeLinearAPI(unittest.TestCase):
def test_case(self): def test_case(self):
x = fluid.data(name="x", shape=[1, 3, 128], dtype="float32") x = fluid.data(name="x", shape=[1, 3, 64], dtype="float32")
dim = fluid.data(name="dim", shape=[1], dtype="int32")
shape_tensor = fluid.data(name="shape_tensor", shape=[1], dtype="int32") shape_tensor = fluid.data(name="shape_tensor", shape=[1], dtype="int32")
actual_size = fluid.data(name="actual_size", shape=[1], dtype="int32")
scale_tensor = fluid.data( scale_tensor = fluid.data(
name="scale_tensor", shape=[1], dtype="float32") name="scale_tensor", shape=[1], dtype="float32")
dim = fluid.data(name="dim", shape=[1], dtype="int32")
actual_size = fluid.data(name='actual_size', shape=[1], dtype='int32')
out1 = fluid.layers.resize_linear( out1 = fluid.layers.resize_linear(
x, out_shape=[256, ], align_mode=1, align_corners=False) x, out_shape=[128, ], align_mode=1, align_corners=False)
out2 = fluid.layers.resize_linear( out2 = fluid.layers.resize_linear(
x, out_shape=shape_tensor, align_mode=1, align_corners=False) x, out_shape=[128], align_mode=1, align_corners=False)
out3 = fluid.layers.resize_linear( out3 = fluid.layers.resize_linear(
x, scale=scale_tensor, align_mode=1, align_corners=False) x, out_shape=shape_tensor, align_mode=1, align_corners=False)
out4 = fluid.layers.resize_linear( out4 = fluid.layers.resize_linear(
x, out_shape=[dim, ], align_mode=1, align_corners=False)
out5 = fluid.layers.resize_linear(
x, x,
out_shape=[256, ], out_shape=[128, ],
actual_shape=actual_size, actual_shape=actual_size,
align_mode=1, align_mode=1,
align_corners=False) align_corners=False)
out5 = fluid.layers.resize_linear(
x, scale=scale_tensor, align_mode=1, align_corners=False)
x_data = np.random.random((1, 3, 128)).astype("float32") out6 = interpolate(
shape_data = np.array([256, ]).astype("int32")
scale_data = np.array([2.0, ]).astype("float32")
dim_data = np.array([256, ]).astype("int32")
actual_size_data = np.array([256, ]).astype("int32")
if core.is_compiled_with_cuda():
place = core.CUDAPlace(0)
else:
place = core.CPUPlace()
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
results = exe.run(fluid.default_main_program(),
feed={
"x": x_data,
"shape_tensor": shape_data,
"scale_tensor": scale_data,
"dim": dim_data,
'actual_size': actual_size_data,
},
fetch_list=[out1, out2, out3, out4, out5],
return_numpy=True)
expect_res = linear_interp_np(
x_data, out_w=256, align_mode=1, align_corners=False)
for res in results:
self.assertTrue(np.allclose(res, expect_res))
class TestLinearInterpOpAPI2_Func(unittest.TestCase):
def test_case(self):
x = fluid.data(name="x", shape=[1, 3, 128], dtype="float32")
shape_tensor = fluid.data(name="shape_tensor", shape=[1], dtype="int32")
scale_tensor = fluid.data(
name="scale_tensor", shape=[1], dtype="float32")
dim = fluid.data(name="dim", shape=[1], dtype="int32")
actual_size = fluid.data(name='actual_size', shape=[1], dtype='int32')
out1 = interpolate(
x,
out_shape=[256, ],
align_mode=1,
align_corners=False,
resample='LINEAR')
out2 = interpolate(
x,
out_shape=shape_tensor,
align_mode=1,
align_corners=False,
resample='LINEAR')
out3 = interpolate(
x, x,
scale=scale_tensor, scale_factor=scale_tensor,
mode='linear',
align_mode=1, align_mode=1,
align_corners=False, align_corners=False,
resample='LINEAR') data_format='NCW')
out4 = interpolate( out7 = interpolate(
x, x,
out_shape=[dim, ], size=[128, ],
mode='linear',
align_mode=1, align_mode=1,
align_corners=False, align_corners=False,
resample='LINEAR') data_format='NCW')
out5 = interpolate( out8 = interpolate(
x, x,
out_shape=[256, ], size=shape_tensor,
actual_shape=actual_size, mode='linear',
align_mode=1, align_mode=1,
align_corners=False, align_corners=False,
resample='LINEAR') data_format='NCW')
x_data = np.random.random((1, 3, 128)).astype("float32") x_data = np.random.random((1, 3, 64)).astype("float32")
shape_data = np.array([256, ]).astype("int32") dim_data = np.array([128]).astype("int32")
scale_data = np.array([2.0, ]).astype("float32") shape_data = np.array([128, ]).astype("int32")
dim_data = np.array([256, ]).astype("int32") actual_size_data = np.array([128, ]).astype("int32")
actual_size_data = np.array([256, ]).astype("int32") scale_data = np.array([2.0]).astype("float32")
if core.is_compiled_with_cuda(): if core.is_compiled_with_cuda():
place = core.CUDAPlace(0) place = core.CUDAPlace(0)
...@@ -318,20 +270,20 @@ class TestLinearInterpOpAPI2_Func(unittest.TestCase): ...@@ -318,20 +270,20 @@ class TestLinearInterpOpAPI2_Func(unittest.TestCase):
place = core.CPUPlace() place = core.CPUPlace()
exe = fluid.Executor(place) exe = fluid.Executor(place)
exe.run(fluid.default_startup_program()) exe.run(fluid.default_startup_program())
results = exe.run(fluid.default_main_program(), results = exe.run(
fluid.default_main_program(),
feed={ feed={
"x": x_data, "x": x_data,
"shape_tensor": shape_data,
"scale_tensor": scale_data,
"dim": dim_data, "dim": dim_data,
'actual_size': actual_size_data, "shape_tensor": shape_data,
"actual_size": actual_size_data,
"scale_tensor": scale_data
}, },
fetch_list=[out1, out2, out3, out4, out5], fetch_list=[out1, out2, out3, out4, out5, out6, out7, out8],
return_numpy=True) return_numpy=True)
expect_res = linear_interp_np( expect_res = linear_interp_np(
x_data, out_w=256, align_mode=1, align_corners=False) x_data, out_w=128, align_mode=1, align_corners=False)
for res in results: for res in results:
self.assertTrue(np.allclose(res, expect_res)) self.assertTrue(np.allclose(res, expect_res))
...@@ -342,10 +294,11 @@ class TestLinearInterpOpAPI2_0(unittest.TestCase): ...@@ -342,10 +294,11 @@ class TestLinearInterpOpAPI2_0(unittest.TestCase):
# dygraph # dygraph
x_data = np.random.random((1, 3, 128)).astype("float32") x_data = np.random.random((1, 3, 128)).astype("float32")
us_1 = paddle.nn.UpSample( us_1 = paddle.nn.UpSample(
out_shape=[64, ], size=[64, ],
resample='LINEAR', mode='linear',
align_mode=1, align_mode=1,
align_corners=False) align_corners=False,
data_format='NCW')
with fluid.dygraph.guard(): with fluid.dygraph.guard():
x = fluid.dygraph.to_variable(x_data) x = fluid.dygraph.to_variable(x_data)
interp = us_1(x) interp = us_1(x)
...@@ -356,7 +309,7 @@ class TestLinearInterpOpAPI2_0(unittest.TestCase): ...@@ -356,7 +309,7 @@ class TestLinearInterpOpAPI2_0(unittest.TestCase):
self.assertTrue(np.allclose(interp.numpy(), expect)) self.assertTrue(np.allclose(interp.numpy(), expect))
class TestLinearInterpOpUint8(OpTest): class TestResizeLinearOpUint8(OpTest):
def setUp(self): def setUp(self):
self.out_size = None self.out_size = None
self.actual_shape = None self.actual_shape = None
...@@ -433,24 +386,22 @@ class TestLinearInterpOpError(unittest.TestCase): ...@@ -433,24 +386,22 @@ class TestLinearInterpOpError(unittest.TestCase):
def input_shape_error(): def input_shape_error():
x1 = fluid.data(name="x1", shape=[1], dtype="float32") x1 = fluid.data(name="x1", shape=[1], dtype="float32")
out1 = paddle.nn.UpSample( out1 = paddle.nn.UpSample(
out_shape=[256, ], data_format='NCW', resample='LINEAR') size=[256, ], data_format='NCW', mode='linear')
out1_res = out1(x1) out1_res = out1(x1)
def data_format_error(): def data_format_error():
x2 = fluid.data(name="x2", shape=[1, 3, 128], dtype="float32") x2 = fluid.data(name="x2", shape=[1, 3, 128], dtype="float32")
out2 = paddle.nn.UpSample( out2 = paddle.nn.UpSample(
out_shape=[256, ], data_format='NHWCD', resample='LINEAR') size=[256, ], data_format='NHWCD', mode='linear')
out2_res = out2(x2) out2_res = out2(x2)
def out_shape_error(): def out_shape_error():
x3 = fluid.data(name="x3", shape=[1, 3, 128], dtype="float32") x3 = fluid.data(name="x3", shape=[1, 3, 128], dtype="float32")
out3 = paddle.nn.UpSample( out3 = paddle.nn.UpSample(
out_shape=[ size=[
256, 256,
256, 256,
], ], data_format='NHWC', mode='linear')
data_format='NHWC',
resample='LINEAR')
out3_res = out3(x3) out3_res = out3(x3)
self.assertRaises(ValueError, input_shape_error) self.assertRaises(ValueError, input_shape_error)
......
...@@ -588,14 +588,11 @@ class TestTrilinearInterpAPI(unittest.TestCase): ...@@ -588,14 +588,11 @@ class TestTrilinearInterpAPI(unittest.TestCase):
x, out_shape=[4, 4, 8], actual_shape=actual_size) x, out_shape=[4, 4, 8], actual_shape=actual_size)
out5 = fluid.layers.resize_trilinear(x, scale=scale_tensor) out5 = fluid.layers.resize_trilinear(x, scale=scale_tensor)
out6 = interpolate( out6 = interpolate(
x, scale=scale_tensor, resample='TRILINEAR', data_format="NCDHW") x, scale_factor=scale_tensor, mode='trilinear', data_format="NCDHW")
out7 = interpolate( out7 = interpolate(
x, out_shape=[4, 4, 8], resample='TRILINEAR', data_format="NCDHW") x, size=[4, 4, 8], mode='trilinear', data_format="NCDHW")
out8 = interpolate( out8 = interpolate(
x, x, size=shape_tensor, mode='trilinear', data_format="NCDHW")
out_shape=shape_tensor,
resample='TRILINEAR',
data_format="NCDHW")
x_data = np.random.random((2, 3, 6, 9, 4)).astype("float32") x_data = np.random.random((2, 3, 6, 9, 4)).astype("float32")
dim_data = np.array([18]).astype("int32") dim_data = np.array([18]).astype("int32")
......
...@@ -45,30 +45,33 @@ __all__ = [ ...@@ -45,30 +45,33 @@ __all__ = [
def interpolate(input, def interpolate(input,
out_shape=None, size=None,
scale=None, scale_factor=None,
name=None, mode='nearest',
resample='BILINEAR', align_corners=False,
actual_shape=None,
align_corners=True,
align_mode=1, align_mode=1,
data_format='NCHW'): data_format='NCHW',
name=None):
""" """
:alias_main: paddle.nn.functional.interpolate :alias_main: paddle.nn.functional.interpolate
:alias: paddle.nn.functional.interpolate,paddle.nn.functional.common.interpolate :alias: paddle.nn.functional.interpolate,paddle.nn.functional.common.interpolate
This op resizes a batch of images. This op resizes a batch of images.
The input must be a 4-D Tensor of the shape (num_batches, channels, in_h, in_w) The input must be a 3-D Tensor of the shape (num_batches, channels, in_w)
or (num_batches, in_h, in_w, channels), or a 5-D Tensor of the shape or 4-D (num_batches, channels, in_h, in_w), or a 5-D Tensor of the shape
(num_batches, channels, in_d, in_h, in_w) or (num_batches, in_d, in_h, in_w, channels), (num_batches, channels, in_d, in_h, in_w) or (num_batches, in_d, in_h, in_w, channels),
and the resizing only applies on the three dimensions(depth, height and width). and the resizing only applies on the three dimensions(depth, height and width).
**Warning:** the parameter :attr:`actual_shape` will be deprecated in the **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
future and only use :attr:`out_shape` instead. future and only use :attr:`out_shape` instead.
Supporting resample methods: Supporting resample methods:
'BILINEAR' : Bilinear interpolation 'linear' : Linear interpolation
'TRILINEAR' : Trilinear interpolation 'bilinear' : Bilinear interpolation
'NEAREST' : Nearest neighbor interpolation 'trilinear' : Trilinear interpolation
'BICUBIC' : Bicubic interpolation 'nearest' : Nearest neighbor interpolation
'bicubic' : Bicubic interpolation
Linear interpolation is the method of using a line connecting two known quantities
to determine the value of an unknown quantity between the two known quantities.
Nearest neighbor interpolation is to perform nearest neighbor interpolation Nearest neighbor interpolation is to perform nearest neighbor interpolation
in both the 3rd dimension(in height direction) and the 4th dimension(in width in both the 3rd dimension(in height direction) and the 4th dimension(in width
...@@ -96,18 +99,24 @@ def interpolate(input, ...@@ -96,18 +99,24 @@ def interpolate(input,
.. code-block:: text .. code-block:: text
For scale: For scale_factor:
if align_corners = True && out_size > 1 : if align_corners = True && out_size > 1 :
scale_factor = (in_size-1.0)/(out_size-1.0) scale_factor = (in_size-1.0)/(out_size-1.0)
else: else:
scale_factor = float(in_size/out_size) scale_factor = float(in_size/out_size)
Linear interpolation:
if:
align_corners = False , align_mode = 0
input : (N,C,W_in)
output: (N,C,W_out) where:
W_out = (W_{in}+0.5) * scale_{factor} - 0.5
else:
input : (N,C,W_in)
output: (N,C,W_out) where:
W_out = W_{in} * scale_{factor}
Nearest neighbor interpolation: Nearest neighbor interpolation:
if: if:
align_corners = False align_corners = False
input : (N,C,H_in,W_in) input : (N,C,H_in,W_in)
...@@ -120,35 +129,28 @@ def interpolate(input, ...@@ -120,35 +129,28 @@ def interpolate(input,
output: (N,C,H_out,W_out) where: output: (N,C,H_out,W_out) where:
H_out = round(H_{in} * scale_{factor}) H_out = round(H_{in} * scale_{factor})
W_out = round(W_{in} * scale_{factor}) W_out = round(W_{in} * scale_{factor})
Bilinear interpolation: Bilinear interpolation:
if: if:
align_corners = False , align_mode = 0 align_corners = False , align_mode = 0
input : (N,C,H_in,W_in) input : (N,C,H_in,W_in)
output: (N,C,H_out,W_out) where: output: (N,C,H_out,W_out) where:
H_out = (H_{in}+0.5) * scale_{factor} - 0.5 H_out = (H_{in}+0.5) * scale_{factor} - 0.5
W_out = (W_{in}+0.5) * scale_{factor} - 0.5 W_out = (W_{in}+0.5) * scale_{factor} - 0.5
else: else:
input : (N,C,H_in,W_in) input : (N,C,H_in,W_in)
output: (N,C,H_out,W_out) where: output: (N,C,H_out,W_out) where:
H_out = H_{in} * scale_{factor} H_out = H_{in} * scale_{factor}
W_out = W_{in} * scale_{factor} W_out = W_{in} * scale_{factor}
Bicubic interpolation: Bicubic interpolation:
if: if:
align_corners = False align_corners = False
input : (N,C,H_in,W_in) input : (N,C,H_in,W_in)
output: (N,C,H_out,W_out) where: output: (N,C,H_out,W_out) where:
H_out = (H_{in}+0.5) * scale_{factor} - 0.5 H_out = (H_{in}+0.5) * scale_{factor} - 0.5
W_out = (W_{in}+0.5) * scale_{factor} - 0.5 W_out = (W_{in}+0.5) * scale_{factor} - 0.5
else: else:
input : (N,C,H_in,W_in) input : (N,C,H_in,W_in)
output: (N,C,H_out,W_out) where: output: (N,C,H_out,W_out) where:
H_out = H_{in} * scale_{factor} H_out = H_{in} * scale_{factor}
...@@ -157,87 +159,82 @@ def interpolate(input, ...@@ -157,87 +159,82 @@ def interpolate(input,
Trilinear interpolation: Trilinear interpolation:
if: if:
align_corners = False , align_mode = 0 align_corners = False , align_mode = 0
input : (N,C,D_in,H_in,W_in) input : (N,C,D_in,H_in,W_in)
output: (N,C,D_out,H_out,W_out) where: output: (N,C,D_out,H_out,W_out) where:
D_out = (D_{in}+0.5) * scale_{factor} - 0.5 D_out = (D_{in}+0.5) * scale_{factor} - 0.5
H_out = (H_{in}+0.5) * scale_{factor} - 0.5 H_out = (H_{in}+0.5) * scale_{factor} - 0.5
W_out = (W_{in}+0.5) * scale_{factor} - 0.5 W_out = (W_{in}+0.5) * scale_{factor} - 0.5
else: else:
input : (N,C,D_in,H_in,W_in) input : (N,C,D_in,H_in,W_in)
output: (N,C,D_out,H_out,W_out) where: output: (N,C,D_out,H_out,W_out) where:
D_out = D_{in} * scale_{factor} D_out = D_{in} * scale_{factor}
H_out = H_{in} * scale_{factor} H_out = H_{in} * scale_{factor}
W_out = W_{in} * scale_{factor} W_out = W_{in} * scale_{factor}
For details of linear interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Linear_interpolation.
For details of nearest neighbor interpolation, please refer to Wikipedia: For details of nearest neighbor interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation. https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation.
For details of bilinear interpolation, please refer to Wikipedia: For details of bilinear interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Bilinear_interpolation. https://en.wikipedia.org/wiki/Bilinear_interpolation.
For details of trilinear interpolation, please refer to Wikipedia: For details of trilinear interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Trilinear_interpolation. https://en.wikipedia.org/wiki/Trilinear_interpolation.
For details of bicubic interpolation, please refer to Wikipedia: For details of bicubic interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Bicubic_interpolation https://en.wikipedia.org/wiki/Bicubic_interpolation
Parameters: Parameters:
input (Variable): 4-D or 5-D Tensor, its data type is float32, float64, or uint8, input (Variable): 3-D, 4-D or 5-D Tensor, its data type is float32, float64, or uint8,
its data format is specified by :attr:`data_format`. its data format is specified by :attr:`data_format`.
out_shape(list|tuple|Variable|None): Output shape of image resize size (list|tuple|Variable|None): Output shape of image resize
layer, the shape is (out_h, out_w) when input is a 4-D Tensor and is layer, the shape is (out_w, ) when input is a 3-D Tensor, the shape is (out_h, out_w)
(out_d, out_h, out_w) when input is a 5-D Tensor. Default: None. If when input is a 4-D Tensor and is (out_d, out_h, out_w) when input is a 5-D Tensor.
a list, each element can be an integer or a Tensor Variable of shape: [1]. Default: None. If a list, each element can be an integer or a Tensor Variable of shape: [1].
If a Tensor Variable, its dimensions size should be a 1. If a Tensor Variable, its dimensions size should be a 1.
scale(float|Variable|None): The multiplier for the input height or width. At scale_factor (float|Variable|None): The multiplier for the input height or width. At
least one of :attr:`out_shape` or :attr:`scale` must be set. least one of :attr:`out_shape` or :attr:`scale_factor` must be set.
And :attr:`out_shape` has a higher priority than :attr:`scale`. And :attr:`out_shape` has a higher priority than :attr:`scale_factor`.
Default: None. Default: None.
name(str|None): A name for this layer(optional). If set None, the layer mode (str): The resample method. It supports 'linear', 'nearest', 'bilinear',
will be named automatically. 'bicubic' and 'trilinear' currently. Default: 'nearest'
resample(str): The resample method. It supports 'BILINEAR', 'TRILINEAR' ,
'BICUBIC' and 'NEAREST' currently. Default: 'BILINEAR'
actual_shape(Variable): An optional input to specify output shape
dynamically. If provided, image resize
according to this given shape rather than
:attr:`out_shape` and :attr:`scale` specifying
shape. That is to say actual_shape has the
highest priority. It is recommended to use
:attr:`out_shape` if you want to specify output
shape dynamically, because :attr:`actual_shape`
will be deprecated. When using actual_shape to
specify output shape, one of :attr:`out_shape`
and :attr:`scale` should also be set, otherwise
errors would be occurred in graph constructing stage.
Default: None
align_corners(bool) : An optional bool, If True, the centers of the 4 corner pixels of the align_corners(bool) : An optional bool, If True, the centers of the 4 corner pixels of the
input and output tensors are aligned, preserving the values at the input and output tensors are aligned, preserving the values at the
corner pixels. corner pixels.
Default: True Default: False
align_mode(int) : An optional for bilinear interpolation. can be \'0\' align_mode(int) : An optional for linear/bilinear/trilinear interpolation. Refer to the formula in the example above,
for src_idx = scale*(dst_indx+0.5)-0.5 , can be \'1\' for it can be \'0\' for src_idx = scale_factor*(dst_indx+0.5)-0.5 , can be \'1\' for
src_idx = scale*dst_index. src_idx = scale_factor*dst_index.
data_format (str, optional): Specify the data format of the input, and the data format of the output data_format (str, optional): Specify the data format of the input, and the data format of the output
will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`, `"NCDHW"`, will be consistent with that of the input. An optional string from:`NCW`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`,
`"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of: `"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
`[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored `[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored
in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`. in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`.
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: Returns:
A 3-D Tensor of the shape (num_batches, channels, out_w) or (num_batches, out_w, channels),
A 4-D Tensor of the shape (num_batches, channels, out_h, out_w) or (num_batches, out_h, out_w, channels), A 4-D Tensor of the shape (num_batches, channels, out_h, out_w) or (num_batches, out_h, out_w, channels),
or 5-D Tensor of the shape (num_batches, channels, out_d, out_h, out_w) or (num_batches, out_d, out_h, out_w, channels). or 5-D Tensor of the shape (num_batches, channels, out_d, out_h, out_w) or (num_batches, out_d, out_h, out_w, channels).
Raises: Raises:
TypeError: out_shape should be a list or tuple or Variable. TypeError: size should be a list or tuple or Variable.
TypeError: actual_shape should either be Variable or None. ValueError: The 'mode' of image_resize can only be 'linear', 'bilinear',
ValueError: The 'resample' of image_resize can only be 'BILINEAR', 'trilinear', 'bicubic', or 'nearest' currently.
'TRILINEAR', 'BICUBIC', or 'NEAREST' currently. ValueError: 'linear' only support 3-D tensor.
ValueError: 'BILINEAR', 'BICUBIC' and 'NEAREST' only support 4-D tensor. ValueError: 'bilinear', 'bicubic' and 'nearest' only support 4-D tensor.
ValueError: 'TRILINEAR' only support 5-D tensor. ValueError: 'trilinear' only support 5-D tensor.
ValueError: One of out_shape and scale must not be None. ValueError: One of size and scale_factor must not be None.
ValueError: out_shape length should be 2 for input 4-D tensor. ValueError: size length should be 1 for input 3-D tensor.
ValueError: out_shape length should be 3 for input 5-D tensor. ValueError: size length should be 2 for input 4-D tensor.
ValueError: scale should be greater than zero. ValueError: size length should be 3 for input 5-D tensor.
ValueError: scale_factor should be greater than zero.
TypeError: align_corners should be a bool value TypeError: align_corners should be a bool value
ValueError: align_mode can only be '0' or '1' ValueError: align_mode can only be '0' or '1'
ValueError: data_format can only be 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'. ValueError: data_format can only be 'NCW', 'NWC', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'.
Examples: Examples:
.. code-block:: python .. code-block:: python
...@@ -246,22 +243,22 @@ def interpolate(input, ...@@ -246,22 +243,22 @@ def interpolate(input,
import numpy as np import numpy as np
input = fluid.data(name="input", shape=[None,3,6,10]) input = fluid.data(name="input", shape=[None,3,6,10])
#1 #1
output = paddle.nn.functional.interpolate(input=input,out_shape=[12,12]) output = paddle.nn.functional.interpolate(input=input, size=[12,12])
#2 #2
#x = np.array([2]).astype("int32") #x = np.array([2]).astype("int32")
#dim1 = fluid.data(name="dim1", shape=[1], dtype="int32") #dim1 = fluid.data(name="dim1", shape=[1], dtype="int32")
#fluid.layers.assign(input=x, output=dim1) #fluid.layers.assign(input=x, output=dim1)
#output = paddle.nn.functional.interpolate(input=input,out_shape=[12,dim1]) #output = paddle.nn.functional.interpolate(input=input, size=[12,dim1])
#3 #3
#x = np.array([3,12]).astype("int32") #x = np.array([3,12]).astype("int32")
#shape_tensor = fluid.data(name="shape_tensor", shape=[2], dtype="int32") #shape_tensor = fluid.data(name="shape_tensor", shape=[2], dtype="int32")
#fluid.layers.assign(input=x, output=shape_tensor) #fluid.layers.assign(input=x, output=shape_tensor)
#output = paddle.nn.functional.interpolate(input=input,out_shape=shape_tensor) #output = paddle.nn.functional.interpolate(input=input, size=shape_tensor)
#4 #4
#x = np.array([0.5]).astype("float32") #x = np.array([0.5]).astype("float32")
#scale_tensor = fluid.data(name="scale", shape=[1], dtype="float32") #scale_tensor = fluid.data(name="scale", shape=[1], dtype="float32")
#fluid.layers.assign(x,scale_tensor) #fluid.layers.assign(x,scale_tensor)
#output = paddle.nn.functional.interpolate(input=input,scale=scale_tensor) #output = paddle.nn.functional.interpolate(input=input, scale_factor=scale_tensor)
place = fluid.CPUPlace() place = fluid.CPUPlace()
exe = fluid.Executor(place) exe = fluid.Executor(place)
exe.run(fluid.default_startup_program()) exe.run(fluid.default_startup_program())
...@@ -285,46 +282,51 @@ def interpolate(input, ...@@ -285,46 +282,51 @@ def interpolate(input,
import paddle.fluid.dygraph as dg import paddle.fluid.dygraph as dg
with dg.guard(place) as g: with dg.guard(place) as g:
input = dg.to_variable(input_data) input = dg.to_variable(input_data)
output = paddle.nn.functional.interpolate(input=input, out_shape=[12,12]) output = paddle.nn.functional.interpolate(input=input, size=[12,12])
print(output.shape) print(output.shape)
# [2L, 3L, 12L, 12L] # [2L, 3L, 12L, 12L]
""" """
resample_methods = { data_format = data_format.upper()
'LINEAR': 'linear', resample = mode.upper()
'BILINEAR': 'bilinear', resample_type = mode.lower()
'TRILINEAR': 'trilinear',
'NEAREST': 'nearest', resample_methods = [
'BICUBIC': 'bicubic', 'LINEAR',
} 'BILINEAR',
'TRILINEAR',
'NEAREST',
'BICUBIC',
]
if resample not in resample_methods: if resample not in resample_methods:
raise ValueError( raise ValueError(
"The 'resample' of image_resize can only be 'LINEAR', 'BILINEAR', 'TRILINEAR', " "The 'resample' of image_resize can only be 'linaer', 'bilinear', 'trilinear', "
" 'BICUBIC' or 'NEAREST' currently.") " 'bicubic' or 'nearest' currently.")
resample_type = resample_methods[resample]
if resample in ['LINEAR'] and len(input.shape) != 3: if resample in ['LINEAR'] and len(input.shape) != 3:
raise ValueError("'LINEAR' only support 3-D tensor.") raise ValueError("'linear' only support 3-D tensor.")
if resample in ['BILINEAR', 'NEAREST', 'BICUBIC'] and len(input.shape) != 4: if resample in ['BILINEAR', 'NEAREST', 'BICUBIC'] and len(input.shape) != 4:
raise ValueError( raise ValueError(
"'BILINEAR', 'BICUBIC' and 'NEAREST' only support 4-D tensor.") "'bilinear', 'bicubic' and 'nearest' only support 4-D tensor.")
if resample == 'TRILINEAR' and len(input.shape) != 5: if resample == 'TRILINEAR' and len(input.shape) != 5:
raise ValueError("'TRILINEAR'only support 5-D tensor.") raise ValueError("'trilinear'only support 5-D tensor.")
if size is None and scale_factor is None:
raise ValueError("One of size and scale_factor must not be None.")
if not isinstance(align_corners, bool): if not isinstance(align_corners, bool):
raise TypeError("Attr align_corners should be a bool value") raise TypeError("Attr align_corners should be a bool value")
if align_mode != 0 and align_mode != 1: if align_mode != 0 and align_mode != 1:
raise ValueError("align_mode can only be 0 or 1") raise ValueError("align_mode can only be 0 or 1")
if out_shape is None and scale is None:
raise ValueError("One of out_shape and scale must not be None.")
helper = LayerHelper('{}_interp'.format(resample_type), **locals()) helper = LayerHelper('{}_interp'.format(resample_type), **locals())
dtype = helper.input_dtype() dtype = helper.input_dtype()
if len(input.shape) == 3 and data_format not in ['NCHW', 'NHWC']: if len(input.shape) == 3 and data_format not in ['NCW', 'NWC']:
raise ValueError( raise ValueError(
"Got wrong value for param `data_format`: " + data_format + "Got wrong value for param `data_format`: " + data_format +
" received but only `NCHW` or `NHWC` supported for 3-D input.") " received but only `NCW` or `NWC` supported for 3-D input.")
elif len(input.shape) == 4 and data_format not in ['NCHW', 'NHWC']: elif len(input.shape) == 4 and data_format not in ['NCHW', 'NHWC']:
raise ValueError( raise ValueError(
"Got wrong value for param `data_format`: " + data_format + "Got wrong value for param `data_format`: " + data_format +
...@@ -337,9 +339,9 @@ def interpolate(input, ...@@ -337,9 +339,9 @@ def interpolate(input,
def _is_list_or_turple_(data): def _is_list_or_turple_(data):
return (isinstance(data, list) or isinstance(data, tuple)) return (isinstance(data, list) or isinstance(data, tuple))
if data_format == 'NCHW' or data_format == 'NCDHW': if data_format == 'NCHW' or data_format == 'NCDHW' or data_format == 'NCW':
data_layout = 'NCHW' data_layout = 'NCHW'
if data_format == 'NHWC' or data_format == 'NDHWC': if data_format == 'NHWC' or data_format == 'NDHWC' or data_format == 'NWC':
data_layout = 'NHWC' data_layout = 'NHWC'
inputs = {"X": input} inputs = {"X": input}
...@@ -353,6 +355,8 @@ def interpolate(input, ...@@ -353,6 +355,8 @@ def interpolate(input,
"data_layout": data_layout "data_layout": data_layout
} }
out_shape = size
scale = scale_factor
if out_shape is not None: if out_shape is not None:
if isinstance(out_shape, Variable): if isinstance(out_shape, Variable):
out_shape.stop_gradient = True out_shape.stop_gradient = True
...@@ -435,16 +439,6 @@ def interpolate(input, ...@@ -435,16 +439,6 @@ def interpolate(input,
raise TypeError( raise TypeError(
"Attr(scale)'s type should be float, int or Variable.") "Attr(scale)'s type should be float, int or Variable.")
if isinstance(actual_shape, Variable):
warnings.warn(
"actual_shape will be deprecated, it is recommended to use "
"out_shape instead of actual_shape to specify output shape dynamically."
)
actual_shape.stop_gradient = True
inputs["OutSize"] = actual_shape
elif actual_shape is not None:
raise TypeError("actual_shape should either be Variable or None.")
out = helper.create_variable_for_type_inference(dtype) out = helper.create_variable_for_type_inference(dtype)
helper.append_op( helper.append_op(
type='{}_interp'.format(resample_type), type='{}_interp'.format(resample_type),
......
...@@ -33,11 +33,11 @@ class UpSample(layers.Layer): ...@@ -33,11 +33,11 @@ class UpSample(layers.Layer):
**Warning:** the parameter :attr:`actual_shape` will be deprecated in the **Warning:** the parameter :attr:`actual_shape` will be deprecated in the
future and only use :attr:`out_shape` instead. future and only use :attr:`out_shape` instead.
Supporting resample methods: Supporting resample methods:
'LINEAR' : linear interpolation 'linear' : Linear interpolation
'BILINEAR' : Bilinear interpolation 'bilinear' : Bilinear interpolation
'TRILINEAR' : Trilinear interpolation 'trilinear' : Trilinear interpolation
'NEAREST' : Nearest neighbor interpolation 'nearest' : Nearest neighbor interpolation
'BICUBIC' : Bicubic interpolation 'bicubic' : Bicubic interpolation
Linear interpolation is the method of using a line connecting two known quantities Linear interpolation is the method of using a line connecting two known quantities
to determine the value of an unknown quantity between the two known quantities. to determine the value of an unknown quantity between the two known quantities.
...@@ -52,6 +52,11 @@ class UpSample(layers.Layer): ...@@ -52,6 +52,11 @@ class UpSample(layers.Layer):
to perform linear interpolation first in one direction, and then to perform linear interpolation first in one direction, and then
again in the other direction. again in the other direction.
Bicubic interpolation is an extension of cubic interpolation for interpolating
data points on a two-dimensional regular grid. The interpolated surface is
smoother than corresponding surfaces obtained by bilinear interpolation or
nearest-neighbor interpolation.
Trilinear interpolation is an extension of linear interpolation for Trilinear interpolation is an extension of linear interpolation for
interpolating functions of three variables (e.g. D-direction, interpolating functions of three variables (e.g. D-direction,
H-direction and W-direction in this op) on a rectilinear 3D grid. H-direction and W-direction in this op) on a rectilinear 3D grid.
...@@ -59,24 +64,26 @@ class UpSample(layers.Layer): ...@@ -59,24 +64,26 @@ class UpSample(layers.Layer):
Align_corners and align_mode are optional parameters,the calculation method Align_corners and align_mode are optional parameters,the calculation method
of interpolation can be selected by them. of interpolation can be selected by them.
Bicubic interpolation is an extension of cubic interpolation for interpolating
data points on a two-dimensional regular grid. The interpolated surface is
smoother than corresponding surfaces obtained by bilinear interpolation or
nearest-neighbor interpolation.
Example: Example:
.. code-block:: text .. code-block:: text
For scale: For scale_factor:
if align_corners = True && out_size > 1 : if align_corners = True && out_size > 1 :
scale_factor = (in_size-1.0)/(out_size-1.0) scale_factor = (in_size-1.0)/(out_size-1.0)
else: else:
scale_factor = float(in_size/out_size) scale_factor = float(in_size/out_size)
Linear interpolation:
if:
align_corners = False , align_mode = 0
input : (N,C,W_in)
output: (N,C,W_out) where:
W_out = (W_{in}+0.5) * scale_{factor} - 0.5
else:
input : (N,C,W_in)
output: (N,C,W_out) where:
W_out = W_{in} * scale_{factor}
Nearest neighbor interpolation: Nearest neighbor interpolation:
if: if:
...@@ -92,25 +99,16 @@ class UpSample(layers.Layer): ...@@ -92,25 +99,16 @@ class UpSample(layers.Layer):
H_out = round(H_{in} * scale_{factor}) H_out = round(H_{in} * scale_{factor})
W_out = round(W_{in} * scale_{factor}) W_out = round(W_{in} * scale_{factor})
Linear interpolation:
if:
align_corners = False , align_mode = 0
input : (N,C,W_in)
output: (N,C,W_out) where:
W_out = (W_{in}+0.5) * scale_{factor} - 0.5
else:
input : (N,C,W_in)
output: (N,C,W_out) where:
W_out = W_{in} * scale_{factor}
Bilinear interpolation: Bilinear interpolation:
if: if:
align_corners = False , align_mode = 0 align_corners = False , align_mode = 0
input : (N,C,H_in,W_in) input : (N,C,H_in,W_in)
output: (N,C,H_out,W_out) where: output: (N,C,H_out,W_out) where:
H_out = (H_{in}+0.5) * scale_{factor} - 0.5 H_out = (H_{in}+0.5) * scale_{factor} - 0.5
W_out = (W_{in}+0.5) * scale_{factor} - 0.5 W_out = (W_{in}+0.5) * scale_{factor} - 0.5
else: else:
input : (N,C,H_in,W_in) input : (N,C,H_in,W_in)
output: (N,C,H_out,W_out) where: output: (N,C,H_out,W_out) where:
H_out = H_{in} * scale_{factor} H_out = H_{in} * scale_{factor}
...@@ -123,6 +121,7 @@ class UpSample(layers.Layer): ...@@ -123,6 +121,7 @@ class UpSample(layers.Layer):
output: (N,C,H_out,W_out) where: output: (N,C,H_out,W_out) where:
H_out = (H_{in}+0.5) * scale_{factor} - 0.5 H_out = (H_{in}+0.5) * scale_{factor} - 0.5
W_out = (W_{in}+0.5) * scale_{factor} - 0.5 W_out = (W_{in}+0.5) * scale_{factor} - 0.5
else: else:
input : (N,C,H_in,W_in) input : (N,C,H_in,W_in)
output: (N,C,H_out,W_out) where: output: (N,C,H_out,W_out) where:
...@@ -144,73 +143,76 @@ class UpSample(layers.Layer): ...@@ -144,73 +143,76 @@ class UpSample(layers.Layer):
H_out = H_{in} * scale_{factor} H_out = H_{in} * scale_{factor}
W_out = W_{in} * scale_{factor} W_out = W_{in} * scale_{factor}
https://en.wikipedia.org/wiki/Linear_interpolation.
For details of linear interpolation, please refer to Wikipedia:
For details of nearest neighbor interpolation, please refer to Wikipedia: For details of nearest neighbor interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation. https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation.
For details of bilinear interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Linear_interpolation.
For details of bilinear interpolation, please refer to Wikipedia: For details of bilinear interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Bilinear_interpolation. https://en.wikipedia.org/wiki/Bilinear_interpolation.
For details of trilinear interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Trilinear_interpolation.
For details of bicubic interpolation, please refer to Wikipedia: For details of bicubic interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Bicubic_interpolation https://en.wikipedia.org/wiki/Bicubic_interpolation
For details of trilinear interpolation, please refer to Wikipedia:
https://en.wikipedia.org/wiki/Trilinear_interpolation.
Parameters: Parameters:
input (Variable): 3-D, 4-D or 5-D Tensor, its data type is float32, float64, or uint8, input (Variable): 3-D, 4-D or 5-D Tensor, its data type is float32, float64, or uint8,
its data format is specified by :attr:`data_format`. its data format is specified by :attr:`data_format`.
out_shape(list|tuple|Variable|None): Output shape of image resize size (list|tuple|Variable|None): Output shape of image resize
layer, the shape is (out_w, ) when input is 3-D Tensor , layer, the shape is (out_w, ) when input is a 3-D Tensor, the shape is (out_h, out_w)
the shape is (out_h, out_w) when input is a 4-D Tensor and is when input is a 4-D Tensor and is (out_d, out_h, out_w) when input is a 5-D Tensor.
(out_d, out_h, out_w) when input is a 5-D Tensor. Default: None. If Default: None. If a list, each element can be an integer or a Tensor Variable of shape: [1].
a list, each element can be an integer or a Tensor Variable of shape: [1].
If a Tensor Variable, its dimensions size should be a 1. If a Tensor Variable, its dimensions size should be a 1.
scale(float|Variable|None): The multiplier for the input height or width. At scale_factor (float|Variable|None): The multiplier for the input height or width. At
least one of :attr:`out_shape` or :attr:`scale` must be set. least one of :attr:`out_shape` or :attr:`scale_factor` must be set.
And :attr:`out_shape` has a higher priority than :attr:`scale`. And :attr:`out_shape` has a higher priority than :attr:`scale_factor`.
Default: None. Default: None.
name(str|None): A name for this layer(optional). If set None, the layer mode (str): The resample method. It supports 'linear', 'nearest', 'bilinear',
will be named automatically. 'bicubic' and 'trilinear' currently. Default: 'nearest'
resample(str): The resample method. It supports 'LINEAR', 'BILINEAR', 'TRILINEAR' ,
'BICUBIC' and 'NEAREST' currently. Default: 'BILINEAR'
align_corners(bool) : An optional bool, If True, the centers of the 4 corner pixels of the align_corners(bool) : An optional bool, If True, the centers of the 4 corner pixels of the
input and output tensors are aligned, preserving the values at the input and output tensors are aligned, preserving the values at the
corner pixels. corner pixels.
Default: True Default: False
align_mode(int) : An optional for bilinear interpolation. can be \'0\' align_mode(int) : An optional for linear/bilinear/trilinear interpolation. Refer to the formula in the example above,
for src_idx = scale*(dst_indx+0.5)-0.5 , can be \'1\' for it can be \'0\' for src_idx = scale_factor*(dst_indx+0.5)-0.5 , can be \'1\' for
src_idx = scale*dst_index. src_idx = scale_factor*dst_index.
data_format (str, optional): Specify the data format of the input, and the data format of the output data_format (str, optional): Specify the data format of the input, and the data format of the output
will be consistent with that of the input. An optional string from:'NCW', `"NCHW"`, `"NHWC"`, `"NCDHW"`, will be consistent with that of the input. An optional string from:`NCW`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`,
`"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of: `"NDHWC"`. The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
`[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored `[batch_size, input_channels, input_height, input_width]`. When it is `"NCHW"`, the data is stored
in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`. in the order of: `[batch_size, input_channels, input_depth, input_height, input_width]`.
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: Returns:
A 3-D Tensor of the shape (num_batches, channels, out_w) or (num_batches, out_w, channels), A 3-D Tensor of the shape (num_batches, channels, out_w) or (num_batches, out_w, channels),
A 4-D Tensor of the shape (num_batches, channels, out_h, out_w) or (num_batches, out_h, out_w, channels), A 4-D Tensor of the shape (num_batches, channels, out_h, out_w) or (num_batches, out_h, out_w, channels),
or 5-D Tensor of the shape (num_batches, channels, out_d, out_h, out_w) or (num_batches, out_d, out_h, out_w, channels). or 5-D Tensor of the shape (num_batches, channels, out_d, out_h, out_w) or (num_batches, out_d, out_h, out_w, channels).
Raises: Raises:
TypeError: out_shape should be a list or tuple or Variable. TypeError: size should be a list or tuple or Variable.
TypeError: actual_shape should either be Variable or None. ValueError: The 'mode' of image_resize can only be 'linear', 'bilinear',
ValueError: The 'resample' of image_resize can only be 'BILINEAR', 'trilinear', 'bicubic', or 'nearest' currently.
'TRILINEAR', 'BICUBIC', or 'NEAREST' currently. ValueError: 'linear' only support 3-D tensor.
ValueError: 'BILINEAR', 'BICUBIC' and 'NEAREST' only support 4-D tensor. ValueError: 'bilinear', 'bicubic' and 'nearest' only support 4-D tensor.
ValueError: 'TRILINEAR' only support 5-D tensor. ValueError: 'trilinear' only support 5-D tensor.
ValueError: One of out_shape and scale must not be None. ValueError: One of size and scale_factor must not be None.
ValueError: out_shape length should be 2 for input 4-D tensor. ValueError: size length should be 1 for input 3-D tensor.
ValueError: out_shape length should be 3 for input 5-D tensor. ValueError: size length should be 2 for input 4-D tensor.
ValueError: scale should be greater than zero. ValueError: size length should be 3 for input 5-D tensor.
ValueError: scale_factor should be greater than zero.
TypeError: align_corners should be a bool value TypeError: align_corners should be a bool value
ValueError: align_mode can only be '0' or '1' ValueError: align_mode can only be '0' or '1'
ValueError: data_format can only be 'NCW', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'. ValueError: data_format can only be 'NCW', 'NWC', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'.
Examples: Examples:
.. code-block:: python .. code-block:: python
import paddle import paddle
import numpy as np import numpy as np
import paddle.fluid.dygraph as dg import paddle.fluid.dygraph as dg
upsample_op = paddle.nn.UpSample(out_shape=[12,12]) upsample_op = paddle.nn.UpSample(size=[12,12])
input_data = np.random.rand(2,3,6,10).astype("float32") input_data = np.random.rand(2,3,6,10).astype("float32")
place = paddle.fluid.CPUPlace() place = paddle.fluid.CPUPlace()
with dg.guard(place) as g: with dg.guard(place) as g:
...@@ -221,16 +223,16 @@ class UpSample(layers.Layer): ...@@ -221,16 +223,16 @@ class UpSample(layers.Layer):
""" """
def __init__(self, def __init__(self,
out_shape=None, size=None,
scale=None, scale_factor=None,
resample='BILINEAR', mode='nearest',
align_corners=True, align_corners=False,
align_mode=1, align_mode=1,
data_format='NCHW'): data_format='NCHW'):
super(UpSample, self).__init__() super(UpSample, self).__init__()
self.out_shape = out_shape self.size = size
self.scale = scale self.scale_factor = scale_factor
self.resample = resample self.mode = mode.lower()
self.align_corners = align_corners self.align_corners = align_corners
self.align_mode = align_mode self.align_mode = align_mode
self.data_format = data_format self.data_format = data_format
...@@ -238,9 +240,9 @@ class UpSample(layers.Layer): ...@@ -238,9 +240,9 @@ class UpSample(layers.Layer):
def forward(self, input): def forward(self, input):
out = F.interpolate( out = F.interpolate(
input, input,
out_shape=self.out_shape, size=self.size,
scale=self.scale, scale_factor=self.scale_factor,
resample=self.resample, mode=self.mode,
align_corners=self.align_corners, align_corners=self.align_corners,
align_mode=self.align_mode, align_mode=self.align_mode,
data_format=self.data_format) data_format=self.data_format)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册