diff --git a/paddle/fluid/operators/interpolate_op.cc b/paddle/fluid/operators/interpolate_op.cc index e5c8525f9efca..643fa28023018 100644 --- a/paddle/fluid/operators/interpolate_op.cc +++ b/paddle/fluid/operators/interpolate_op.cc @@ -70,6 +70,9 @@ static void Interpolate1DInferShapeCheck(framework::InferShapeContext* ctx) { out_w = -1; } else { float scale_w = ctx->Attrs().Get("scale_w"); + PADDLE_ENFORCE_EQ(scale_w > 0, true, platform::errors::InvalidArgument( + "scale of Op(interpolate) " + "should be greater than 0.")); if (scale_w > 0) { // round down out_w = (data_layout == DataLayout::kNCHW @@ -157,6 +160,10 @@ static void Interpolate2DInferShapeCheck(framework::InferShapeContext* ctx) { } else { float scale_h = ctx->Attrs().Get("scale_h"); float scale_w = ctx->Attrs().Get("scale_w"); + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); if (scale_h > 0 && scale_w > 0) { // round down out_h = (data_layout == DataLayout::kNCHW @@ -255,7 +262,10 @@ static void Interpolate3DInferShapeCheck(framework::InferShapeContext* ctx) { float scale_d = ctx->Attrs().Get("scale_d"); float scale_h = ctx->Attrs().Get("scale_h"); float scale_w = ctx->Attrs().Get("scale_w"); - + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0 && scale_d > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); if (scale_d > 0 && scale_h > 0 && scale_w > 0) { // round down out_d = (data_layout == DataLayout::kNCHW diff --git a/paddle/fluid/operators/interpolate_op.cu b/paddle/fluid/operators/interpolate_op.cu index 78ccaa9e2f943..bb8a5186c8b64 100644 --- a/paddle/fluid/operators/interpolate_op.cu +++ b/paddle/fluid/operators/interpolate_op.cu @@ -846,8 +846,14 @@ static void Interpolate1DCUDAFwd(const framework::ExecutionContext& ctx, if (scale_tensor != nullptr) { auto scale_data = get_new_data_from_tensor(scale_tensor); scale = scale_data[0]; + PADDLE_ENFORCE_EQ(scale_w > 0, true, platform::errors::InvalidArgument( + "scale of Op(interpolate) " + "should be greater than 0.")); } else { scale = ctx.Attr("scale_w"); + PADDLE_ENFORCE_EQ(scale_w > 0, true, platform::errors::InvalidArgument( + "scale of Op(interpolate) " + "should be greater than 0.")); } if (scale > 0) { out_w = static_cast(in_w * scale); @@ -933,9 +939,17 @@ static void Interpolate2DCUDAFwd(const framework::ExecutionContext& ctx, scale_h = scale_data[0]; scale_w = scale_data[0]; } + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } else { scale_w = ctx.Attr("scale_w"); scale_h = ctx.Attr("scale_h"); + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } if (scale_w > 0 && scale_h > 0) { out_h = static_cast(in_h * scale_h); @@ -1050,10 +1064,18 @@ static void Interpolate3DCUDAFwd(const framework::ExecutionContext& ctx, scale_h = scale_data[0]; scale_w = scale_data[0]; } + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0 && scale_d > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } else { scale_d = ctx.Attr("scale_d"); scale_h = ctx.Attr("scale_h"); scale_w = ctx.Attr("scale_w"); + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0 && scale_d > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } if (scale_d > 0 && scale_h > 0 && scale_w > 0) { out_d = static_cast(in_d * scale_d); @@ -1147,8 +1169,14 @@ static void Interpolate1DCUDABwd(const framework::ExecutionContext& ctx, if (scale_tensor != nullptr) { auto scale_data = get_new_data_from_tensor(scale_tensor); scale = scale_data[0]; + PADDLE_ENFORCE_EQ(scale_w > 0, true, platform::errors::InvalidArgument( + "scale of Op(interpolate) " + "should be greater than 0.")); } else { scale = ctx.Attr("scale_w"); + PADDLE_ENFORCE_EQ(scale_w > 0, true, platform::errors::InvalidArgument( + "scale of Op(interpolate) " + "should be greater than 0.")); } if (scale > 0) { out_w = static_cast(in_w * scale); @@ -1233,9 +1261,17 @@ static void Interpolate2DCUDABwd(const framework::ExecutionContext& ctx, scale_h = scale_data[0]; scale_w = scale_data[0]; } + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } else { scale_w = ctx.Attr("scale_w"); scale_h = ctx.Attr("scale_h"); + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } if (scale_w > 0 && scale_h > 0) { out_h = static_cast(in_h * scale_h); @@ -1348,10 +1384,18 @@ static void Interpolate3DCUDABwd(const framework::ExecutionContext& ctx, scale_h = scale_data[0]; scale_w = scale_data[0]; } + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0 && scale_d > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } else { scale_d = ctx.Attr("scale_d"); scale_h = ctx.Attr("scale_h"); scale_w = ctx.Attr("scale_w"); + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0 && scale_d > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } if (scale_d > 0 && scale_h > 0 && scale_w > 0) { out_d = static_cast(in_d * scale_d); diff --git a/paddle/fluid/operators/interpolate_op.h b/paddle/fluid/operators/interpolate_op.h index b6c6d135abe12..512a24804fd33 100644 --- a/paddle/fluid/operators/interpolate_op.h +++ b/paddle/fluid/operators/interpolate_op.h @@ -792,12 +792,18 @@ static void Interpolate1DCPUFwd(const framework::ExecutionContext& ctx, auto scale_tensor = ctx.Input("Scale"); if (scale_tensor != nullptr) { auto scale_data = get_new_data_from_tensor(scale_tensor); - scale = scale_data[0]; + scale_w = scale_data[0]; + PADDLE_ENFORCE_EQ(scale_w > 0, true, platform::errors::InvalidArgument( + "scale of Op(interpolate) " + "should be greater than 0.")); } else { - scale = ctx.Attr("scale_w"); + scale_w = ctx.Attr("scale_w"); + PADDLE_ENFORCE_EQ(scale_w > 0, true, platform::errors::InvalidArgument( + "scale of Op(interpolate) " + "should be greater than 0.")); } - if (scale > 0) { - out_w = static_cast(in_w * scale); + if (scale_w > 0) { + out_w = static_cast(in_w * scale_w); } auto out_size = ctx.Input("OutSize"); if (out_size != nullptr) { @@ -866,9 +872,17 @@ static void Interpolate2DCPUFwd(const framework::ExecutionContext& ctx, scale_h = scale_data[0]; scale_w = scale_data[0]; } + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } else { scale_w = ctx.Attr("scale_w"); scale_h = ctx.Attr("scale_h"); + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } if (scale_h > 0 && scale_w > 0) { out_h = static_cast(in_h * scale_h); @@ -963,10 +977,18 @@ static void Interpolate3DCPUFwd(const framework::ExecutionContext& ctx, scale_h = scale_data[0]; scale_w = scale_data[0]; } + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0 && scale_d, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } else { scale_d = ctx.Attr("scale_d"); scale_h = ctx.Attr("scale_h"); scale_w = ctx.Attr("scale_w"); + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0 && scale_d, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } if (scale_w > 0 && scale_h > 0 && scale_d > 0) { out_d = static_cast(in_d * scale_d); @@ -1046,12 +1068,18 @@ static void Interpolate1DCPUBwd(const framework::ExecutionContext& ctx, auto scale_tensor = ctx.Input("Scale"); if (scale_tensor != nullptr) { auto scale_data = get_new_data_from_tensor(scale_tensor); - scale = scale_data[0]; + scale_w = scale_data[0]; + PADDLE_ENFORCE_EQ(scale_w > 0, true, platform::errors::InvalidArgument( + "scale of Op(interpolate) " + "should be greater than 0.")); } else { - scale = ctx.Attr("scale_w"); + scale_w = ctx.Attr("scale_w"); + PADDLE_ENFORCE_EQ(scale_w > 0, true, platform::errors::InvalidArgument( + "scale of Op(interpolate) " + "should be greater than 0.")); } - if (scale > 0) { - out_w = static_cast(in_w * scale); + if (scale_w > 0) { + out_w = static_cast(in_w * scale_w); } auto out_size = ctx.Input("OutSize"); if (out_size != nullptr) { @@ -1120,9 +1148,17 @@ static void Interpolate2DCPUBwd(const framework::ExecutionContext& ctx, scale_w = scale_data[0]; scale_h = scale_data[0]; } + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } else { scale_h = ctx.Attr("scale_h"); scale_w = ctx.Attr("scale_w"); + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } if (scale_h > 0 && scale_w > 0) { out_h = static_cast(in_h * scale_h); @@ -1216,10 +1252,18 @@ static void Interpolate3DCPUBwd(const framework::ExecutionContext& ctx, scale_h = scale_data[0]; scale_w = scale_data[0]; } + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0 && scale_d > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } else { scale_d = ctx.Attr("scale_d"); scale_h = ctx.Attr("scale_h"); scale_w = ctx.Attr("scale_w"); + PADDLE_ENFORCE_EQ( + scale_w > 0 && scale_h > 0 && scale_d > 0, true, + platform::errors::InvalidArgument("scale of Op(interpolate) " + "should be greater than 0.")); } if (scale_d > 0 && scale_h > 0 && scale_w > 0) { out_d = static_cast(in_d * scale_d); diff --git a/python/paddle/nn/functional/common.py b/python/paddle/nn/functional/common.py index 14f0d0f777735..f5bc54d29267c 100644 --- a/python/paddle/nn/functional/common.py +++ b/python/paddle/nn/functional/common.py @@ -40,7 +40,8 @@ 'unfold', # 'bilinear_tensor_product', 'assign', - 'interpolate' + 'interpolate', + 'upsample' ] @@ -117,18 +118,11 @@ def interpolate(input, W_out = W_{in} * scale_{factor} Nearest neighbor interpolation: - if: - align_corners = False + input : (N,C,H_in,W_in) output: (N,C,H_out,W_out) where: H_out = floor (H_{in} * scale_{factor}) W_out = floor (W_{in} * scale_{factor}) - else: - align_corners = True - input : (N,C,H_in,W_in) - output: (N,C,H_out,W_out) where: - H_out = round(H_{in} * scale_{factor}) - W_out = round(W_{in} * scale_{factor}) Bilinear interpolation: if: @@ -352,9 +346,6 @@ def _is_list_or_turple_(data): "out_d": -1, "out_h": -1, "out_w": -1, - "scale_w": -1, - "scale_h": -1, - "scale_d": -1, "interp_method": resample_type, "align_corners": align_corners, "align_mode": align_mode, @@ -470,3 +461,197 @@ def _is_list_or_turple_(data): outputs={"Out": out}, attrs=attrs) return out + + +def upsample(input, + size=None, + scale_factor=None, + mode='nearest', + align_corners=False, + align_mode=0, + data_format='NCHW', + name=None): + """ + This op resizes a batch of images. + The input must be a 3-D Tensor of the shape (num_batches, channels, in_w) + 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), + and the resizing only applies on the three dimensions(depth, height and width). + **Warning:** the parameter :attr:`actual_shape` will be deprecated in the + future and only use :attr:`out_shape` instead. + Supporting resample methods: + 'linear' : Linear interpolation + 'bilinear' : Bilinear interpolation + 'trilinear' : Trilinear 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 + in both the 3rd dimension(in height direction) and the 4th dimension(in width + direction) on input tensor. + Bilinear interpolation is an extension of linear interpolation for + interpolating functions of two variables (e.g. H-direction and + W-direction in this op) on a rectilinear 2D grid. The key idea is + to perform linear interpolation first in one direction, and then + 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 + interpolating functions of three variables (e.g. D-direction, + H-direction and W-direction in this op) on a rectilinear 3D grid. + The linear interpolation is performed on three directions. + Align_corners and align_mode are optional parameters,the calculation method + of interpolation can be selected by them. + Example: + .. code-block:: text + For scale_factor: + if align_corners = True && out_size > 1 : + scale_factor = (in_size-1.0)/(out_size-1.0) + else: + 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: + if: + align_corners = False + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + H_out = floor (H_{in} * scale_{factor}) + W_out = floor (W_{in} * scale_{factor}) + else: + align_corners = True + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + H_out = round(H_{in} * scale_{factor}) + W_out = round(W_{in} * scale_{factor}) + + Bilinear interpolation: + if: + align_corners = False , align_mode = 0 + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + H_out = (H_{in}+0.5) * scale_{factor} - 0.5 + W_out = (W_{in}+0.5) * scale_{factor} - 0.5 + else: + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + H_out = H_{in} * scale_{factor} + W_out = W_{in} * scale_{factor} + Bicubic interpolation: + if: + align_corners = False + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + H_out = (H_{in}+0.5) * scale_{factor} - 0.5 + W_out = (W_{in}+0.5) * scale_{factor} - 0.5 + else: + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + H_out = H_{in} * scale_{factor} + W_out = W_{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} + 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: + https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation. + + For details of bilinear interpolation, please refer to Wikipedia: + https://en.wikipedia.org/wiki/Bilinear_interpolation. + + For details of bicubic interpolation, please refer to Wikipedia: + https://en.wikipedia.org/wiki/Bicubic_interpolation + + For details of trilinear interpolation, please refer to Wikipedia: + https://en.wikipedia.org/wiki/Trilinear_interpolation. + + Parameters: + 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`. + size (list|tuple|Variable|None): Output shape of image resize + layer, the shape is (out_w, ) when input is a 3-D Tensor, the shape is (out_h, out_w) + when input is a 4-D Tensor and is (out_d, out_h, out_w) when input is a 5-D Tensor. + 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. + scale_factor (float|Variable|None): The multiplier for the input height or width. At + least one of :attr:`out_shape` or :attr:`scale_factor` must be set. + And :attr:`out_shape` has a higher priority than :attr:`scale_factor`. + Default: None. + mode (str): The resample method. It supports 'linear', 'nearest', 'bilinear', + 'bicubic' and 'trilinear' currently. Default: 'nearest' + 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 + corner pixels. + Default: False + align_mode(int) : An optional for linear/bilinear/trilinear interpolation. Refer to the formula in the example above, + it can be \'0\' for src_idx = scale_factor*(dst_indx+0.5)-0.5 , can be \'1\' for + src_idx = scale_factor*dst_index. + 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`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`, + `"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 + 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: + 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), + 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: + TypeError: size should be a list or tuple or Variable. + ValueError: The 'mode' of image_resize can only be 'linear', 'bilinear', + 'trilinear', 'bicubic', or 'nearest' currently. + ValueError: 'linear' only support 3-D tensor. + ValueError: 'bilinear', 'bicubic' and 'nearest' only support 4-D tensor. + ValueError: 'trilinear' only support 5-D tensor. + ValueError: One of size and scale_factor must not be None. + ValueError: size length should be 1 for input 3-D tensor. + ValueError: size length should be 2 for input 4-D tensor. + 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 + ValueError: align_mode can only be '0' or '1' + ValueError: data_format can only be 'NCW', 'NWC', 'NCHW', 'NHWC', 'NCDHW' or 'NDHWC'. + Examples: + .. code-block:: python + import paddle + import numpy as np + import paddle.fluid.dygraph as dg + upsample_op = paddle.nn.UpSample(size=[12,12]) + input_data = np.random.rand(2,3,6,10).astype("float32") + place = paddle.fluid.CPUPlace() + with dg.guard(place) as g: + input = dg.to_variable(input_data) + output = upsample_op(input=input) + print(output.shape) + # [2L, 3L, 12L, 12L] + """ + return interpolate(input, size, scale_factor, mode, align_corners, + align_mode, data_format) diff --git a/python/paddle/nn/layer/common.py b/python/paddle/nn/layer/common.py index 1a02d53b9c695..197420e45d7ff 100644 --- a/python/paddle/nn/layer/common.py +++ b/python/paddle/nn/layer/common.py @@ -22,7 +22,7 @@ __all__ = [ 'BilinearTensorProduct', 'Pool2D', 'Embedding', 'Linear', 'UpSample', - 'Pad2D' + 'Pad2D', 'UpsamplingNearest2d', 'UpsamplingBilinear2d' ] @@ -219,7 +219,7 @@ class UpSample(layers.Layer): input_data = np.random.rand(2,3,6,10).astype("float32") place = paddle.fluid.CPUPlace() with dg.guard(place) as g: - input = dg.to_variable(input_data) + input = paddle.to_tensor(input_data) output = upsample_op(input=input) print(output.shape) # [2L, 3L, 12L, 12L] @@ -253,6 +253,160 @@ def forward(self, input): return out +class UpsamplingNearest2d(layers.Layer): + """ + This op upsamples a batch of images, using nearest neighbours' pixel values. + The input must be a 4-D Tensor of the shape (num_batches, channels, in_h, in_w), + and the upsampling only applies on the two dimensions(height and width). + **Warning:** the parameter :attr:`actual_shape` will be deprecated in the + future and only use :attr:`out_shape` instead. + Nearest neighbor interpolation is to perform nearest neighbor interpolation + in both the 3rd dimension(in height direction) and the 4th dimension(in width + direction) on input tensor. + + For details of nearest neighbor interpolation, please refer to Wikipedia: + https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation. + + input (Variable): 4-D Tensor, its data type is float32, float64, or uint8, + its data format is specified by :attr:`data_format`. + 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. + 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. + scale_factor (float|int|list|Variable|None): The multiplier for the input height or width. At + least one of :attr:`out_shape` or :attr:`scale_factor` must be set. + And :attr:`out_shape` has a higher priority than :attr:`scale_factor`. + Default: None. Has to match input size if it is a list. + 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`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`, + `"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 + 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: + A 4-D Tensor of the shape (num_batches, channels, out_h, out_w) or (num_batches, out_h, out_w, channels), + Raises: + TypeError: size should be a list or tuple or Variable. + ValueError: 'nearest' only support 4-D tensor. + ValueError: One of size and scale_factor must not be None. + ValueError: size length should be 2 for input 4-D tensor. + ValueError: scale_factor should be greater than zero. + ValueError: data_format can only be 'NCHW', 'NHWC'. + Examples: + .. code-block:: python + import paddle + import numpy as np + import paddle.fluid.dygraph as dg + upsample_op = paddle.nn.UpsamplingNearest2d(size=[12,12]) + input_data = np.random.rand(2,3,6,10).astype("float32") + place = paddle.fluid.CPUPlace() + with dg.guard(place) as g: + input = paddle.to_tensor(input_data) + output = upsample_op(input=input) + print(output.shape) + # [2L, 3L, 12L, 12L] + """ + + def __init__(self, size=None, scale_factor=None, data_format='NCHW'): + super(UpSample, self).__init__() + self.size = size + self.scale_factor = scale_factor + self.mode = mode.lower() + self.data_format = data_format + + def forward(self, input): + out = F.interpolate( + input, + size=self.size, + scale_factor=self.scale_factor, + mode='nearest', + align_corners=False, + align_mode=0, + data_format=self.data_format) + + return out + + +class UpsamplingBilinear2d(layers.Layer): + """ + This op upsamples a batch of images, using bilinear' pixel values. + The input must be a 4-D Tensor of the shape (num_batches, channels, in_h, in_w), + and the upsampling only applies on the two dimensions(height and width). + **Warning:** the parameter :attr:`actual_shape` will be deprecated in the + future and only use :attr:`out_shape` instead. + Bilinear interpolation is an extension of linear interpolation for + interpolating functions of two variables (e.g. H-direction and + W-direction in this op) on a rectilinear 2D grid. The key idea is + to perform linear interpolation first in one direction, and then + again in the other direction. + + For details of bilinear interpolation, please refer to Wikipedia: + https://en.wikipedia.org/wiki/Bilinear_interpolation. + + input (Variable): 4-D Tensor, its data type is float32, float64, or uint8, + its data format is specified by :attr:`data_format`. + 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. + 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. + scale_factor (float|int|list|Variable|None): The multiplier for the input height or width. At + least one of :attr:`out_shape` or :attr:`scale_factor` must be set. + And :attr:`out_shape` has a higher priority than :attr:`scale_factor`. + Default: None. Has to match input size if it is a list. + 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`, `NWC`, `"NCHW"`, `"NHWC"`, `"NCDHW"`, + `"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 + 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: + A 4-D Tensor of the shape (num_batches, channels, out_h, out_w) or (num_batches, out_h, out_w, channels), + Raises: + TypeError: size should be a list or tuple or Variable. + ValueError: 'bilinear' only support 4-D tensor. + ValueError: One of size and scale_factor must not be None. + ValueError: size length should be 2 for input 4-D tensor. + ValueError: scale_factor should be greater than zero. + ValueError: data_format can only be 'NCHW', 'NHWC'. + Examples: + .. code-block:: python + import paddle + import numpy as np + import paddle.fluid.dygraph as dg + upsample_op = paddle.nn.UpsamplingBilinear2d(size=[12,12]) + input_data = np.random.rand(2,3,6,10).astype("float32") + place = paddle.fluid.CPUPlace() + with dg.guard(place) as g: + input = paddle.to_tensor(input_data) + output = upsample_op(input=input) + print(output.shape) + # [2L, 3L, 12L, 12L] + """ + + def __init__(self, size=None, scale_factor=None, data_format='NCHW'): + super(UpSample, self).__init__() + self.size = size + self.scale_factor = scale_factor + self.mode = mode.lower() + self.data_format = data_format + + def forward(self, input): + out = F.interpolate( + input, + size=self.size, + scale_factor=self.scale_factor, + mode='bilinear', + align_corners=True, + align_mode=0, + data_format=self.data_format) + + return out + + class Pad2D(layers.Layer): """ :alias_main: paddle.nn.Pad2D