diff --git a/paddle/fluid/API.spec b/paddle/fluid/API.spec index 6937d13dbaa60723f8d55964db8db1eb03f4057b..f4e964d8c20b7b256ca2289d0f8bf9306a8f2705 100644 --- a/paddle/fluid/API.spec +++ b/paddle/fluid/API.spec @@ -140,10 +140,10 @@ paddle.fluid.layers.label_smooth ArgSpec(args=['label', 'prior_dist', 'epsilon', paddle.fluid.layers.roi_pool ArgSpec(args=['input', 'rois', 'pooled_height', 'pooled_width', 'spatial_scale'], varargs=None, keywords=None, defaults=(1, 1, 1.0)) paddle.fluid.layers.roi_align ArgSpec(args=['input', 'rois', 'pooled_height', 'pooled_width', 'spatial_scale', 'sampling_ratio', 'name'], varargs=None, keywords=None, defaults=(1, 1, 1.0, -1, None)) paddle.fluid.layers.dice_loss ArgSpec(args=['input', 'label', 'epsilon'], varargs=None, keywords=None, defaults=(1e-05,)) -paddle.fluid.layers.image_resize ArgSpec(args=['input', 'out_shape', 'scale', 'name', 'resample', 'actual_shape'], varargs=None, keywords=None, defaults=(None, None, None, 'BILINEAR', None)) +paddle.fluid.layers.image_resize ArgSpec(args=['input', 'out_shape', 'scale', 'name', 'resample', 'actual_shape', 'align_corners', 'align_mode'], varargs=None, keywords=None, defaults=(None, None, None, 'BILINEAR', None, True, 1)) paddle.fluid.layers.image_resize_short ArgSpec(args=['input', 'out_short_len', 'resample'], varargs=None, keywords=None, defaults=('BILINEAR',)) -paddle.fluid.layers.resize_bilinear ArgSpec(args=['input', 'out_shape', 'scale', 'name', 'actual_shape'], varargs=None, keywords=None, defaults=(None, None, None, None)) -paddle.fluid.layers.resize_nearest ArgSpec(args=['input', 'out_shape', 'scale', 'name', 'actual_shape'], varargs=None, keywords=None, defaults=(None, None, None, None)) +paddle.fluid.layers.resize_bilinear ArgSpec(args=['input', 'out_shape', 'scale', 'name', 'actual_shape', 'align_corners', 'align_mode'], varargs=None, keywords=None, defaults=(None, None, None, None, True, 1)) +paddle.fluid.layers.resize_nearest ArgSpec(args=['input', 'out_shape', 'scale', 'name', 'actual_shape', 'align_corners'], varargs=None, keywords=None, defaults=(None, None, None, None, True)) paddle.fluid.layers.gather ArgSpec(args=['input', 'index'], varargs=None, keywords=None, defaults=None) paddle.fluid.layers.scatter ArgSpec(args=['input', 'index', 'updates', 'name'], varargs=None, keywords=None, defaults=(None,)) paddle.fluid.layers.sequence_scatter ArgSpec(args=['input', 'index', 'updates', 'name'], varargs=None, keywords=None, defaults=(None,)) @@ -505,3 +505,4 @@ paddle.reader.Fake.__init__ ArgSpec(args=['self'], varargs=None, keywords=None, paddle.reader.creator.np_array ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None) paddle.reader.creator.text_file ArgSpec(args=['path'], varargs=None, keywords=None, defaults=None) paddle.reader.creator.recordio ArgSpec(args=['paths', 'buf_size'], varargs=None, keywords=None, defaults=(100,)) + diff --git a/paddle/fluid/operators/interpolate_op.cc b/paddle/fluid/operators/interpolate_op.cc index 1b34d404c0f0cd6c5cd163f7c53deb0a8931a9a7..13be33a391f96fb2c1ff02109e431366c45290b2 100644 --- a/paddle/fluid/operators/interpolate_op.cc +++ b/paddle/fluid/operators/interpolate_op.cc @@ -90,10 +90,10 @@ class InterpolateOpMaker : public framework::OpProtoAndCheckerMaker { "if Flase, are not aligned") .SetDefault(true); AddAttr("align_mode", - "(int, default \'0\'), align_corners mode , can be \'0\' " - "for pytorch calculation method, can be \'1\' for " - "tensorflow calculation method.") - .SetDefault(0); + "(int, default \'1\'), can be \'0\' for " + "src_idx = scale*(dst_indx+0.5)-0.5 , can be \'1\' for " + "src_idx = scale*dst_index .") + .SetDefault(1); AddComment(R"DOC( This operator samples input X to given output shape by using specified interpolation method, the interpolation methods can be \"nearest\" @@ -115,7 +115,7 @@ class InterpolateOpMaker : public framework::OpProtoAndCheckerMaker { Example: - for scale: + For scale: if align_corners = True and out_{size}>1 : @@ -148,7 +148,7 @@ class InterpolateOpMaker : public framework::OpProtoAndCheckerMaker { Bilinear interpolation: - case 1: + if: align_corners = False , align_mode = 0 input : (N,C,H_in,W_in) @@ -158,10 +158,7 @@ class InterpolateOpMaker : public framework::OpProtoAndCheckerMaker { W_out = (W_{in}+0.5) * scale_{factor} - 0.5 - case 2: - align_corners = False , align_mode = 1 - or - align_corners = True + else: input : (N,C,H_in,W_in) output: (N,C,H_out,W_out) where: diff --git a/paddle/fluid/operators/interpolate_op.cu b/paddle/fluid/operators/interpolate_op.cu index 316811d23eac441e65c093ba6b20c9ae93b8fac0..7595511cf57442811bff4e44e5204f668c439dcb 100644 --- a/paddle/fluid/operators/interpolate_op.cu +++ b/paddle/fluid/operators/interpolate_op.cu @@ -105,6 +105,7 @@ __global__ void KeBilinearInterpFw( int in_img_idy = (align_mode == 0 && !align_corners) ? static_cast(ratio_h * (out_img_idy + 0.5) - 0.5) : static_cast(ratio_h * out_img_idy); + in_img_idy = (in_img_idy > 0) ? in_img_idy : 0; int h_id = (in_img_idy < in_img_h - 1) ? 1 : 0; T h1lambda = (align_mode == 0 && !align_corners) ? ratio_h * (out_img_idy + 0.5) - 0.5 - in_img_idy @@ -115,6 +116,7 @@ __global__ void KeBilinearInterpFw( int in_img_idx = (align_mode == 0 && !align_corners) ? static_cast(ratio_w * (out_img_idx + 0.5) - 0.5) : static_cast(ratio_w * out_img_idx); + in_img_idx = (in_img_idx > 0) ? in_img_idx : 0; int w_id = (in_img_idx < in_img_w - 1) ? 1 : 0; T w1lambda = (align_mode == 0 && !align_corners) ? ratio_w * (out_img_idx + 0.5) - 0.5 - in_img_idx @@ -153,6 +155,7 @@ __global__ void KeBilinearInterpBw( int in_img_idy = (align_mode == 0 && !align_corners) ? ratio_h * (out_img_idy + 0.5) - 0.5 : ratio_h * out_img_idy; + in_img_idy = (in_img_idy > 0) ? in_img_idy : 0; int h_id = (in_img_idy < in_img_h - 1) ? 1 : 0; T h1lambda = (align_mode == 0 && !align_corners) ? ratio_h * (out_img_idy + 0.5) - 0.5 - in_img_idy @@ -164,6 +167,7 @@ __global__ void KeBilinearInterpBw( int in_img_idx = (align_mode == 0 && !align_corners) ? ratio_w * (out_img_idx + 0.5) - 0.5 : ratio_w * out_img_idx; + in_img_idx = (in_img_idx > 0) ? in_img_idx : 0; int w_id = (in_img_idx < in_img_w - 1) ? 1 : 0; T w1lambda = (align_mode == 0 && !align_corners) ? ratio_w * (out_img_idx + 0.5) - 0.5 - in_img_idx diff --git a/paddle/fluid/operators/interpolate_op.h b/paddle/fluid/operators/interpolate_op.h index 95aec33eee6a7b4cdba4b78f3775f1f6ed26d635..ab41ff781a5d5fa9791639984a2ff9babe593911 100644 --- a/paddle/fluid/operators/interpolate_op.h +++ b/paddle/fluid/operators/interpolate_op.h @@ -60,6 +60,7 @@ static void BilinearInterpolation(const Tensor& input, Tensor* output, int y_n = (align_mode == 0 && !align_corners) ? static_cast(ratio_h * (k + 0.5) - 0.5) : static_cast(ratio_h * k); + y_n = (y_n > 0) ? y_n : 0; int y_s = (y_n + 1) < (in_h - 1) ? (y_n + 1) : (in_h - 1); float d_n = (align_mode == 0 && !align_corners) ? ratio_h * (k + 0.5) - 0.5 - y_n @@ -70,6 +71,7 @@ static void BilinearInterpolation(const Tensor& input, Tensor* output, int x_w = (align_mode == 0 && !align_corners) ? static_cast(ratio_w * (l + 0.5) - 0.5) : static_cast(ratio_w * l); + x_w = (x_w > 0) ? x_w : 0; int x_e = (x_w + 1) < (in_w - 1) ? (x_w + 1) : (in_w - 1); float d_w = (align_mode == 0 && !align_corners) ? ratio_w * (l + 0.5) - 0.5 - x_w @@ -128,6 +130,7 @@ static void BilinearInterpolationGrad(const Tensor& output_grad, int y_n = (align_mode == 0 && !align_corners) ? static_cast(ratio_h * (k + 0.5) - 0.5) : static_cast(ratio_h * k); + y_n = (y_n > 0) ? y_n : 0; int y_s = (y_n + 1) < (in_h - 1) ? (y_n + 1) : (in_h - 1); float d_n = (align_mode == 0 && !align_corners) ? ratio_h * (k + 0.5) - 0.5 - y_n @@ -138,6 +141,7 @@ static void BilinearInterpolationGrad(const Tensor& output_grad, int x_w = (align_mode == 0 && !align_corners) ? static_cast(ratio_w * (l + 0.5) - 0.5) : static_cast(ratio_w * l); + x_w = (x_w > 0) ? x_w : 0; int x_e = (x_w + 1) < (in_w - 1) ? (x_w + 1) : (in_w - 1); float d_w = (align_mode == 0 && !align_corners) ? ratio_w * (l + 0.5) - 0.5 - x_w diff --git a/python/paddle/fluid/layers/nn.py b/python/paddle/fluid/layers/nn.py index 93e77dc113c9d020cfd00e1f8685e753e3e1f349..765fa8565be0543d3625df34d4a36d7fe1068b49 100644 --- a/python/paddle/fluid/layers/nn.py +++ b/python/paddle/fluid/layers/nn.py @@ -6557,7 +6557,7 @@ def image_resize(input, Example: - for scale: + For scale: if align_corners = True && out_size > 1 : @@ -6590,7 +6590,7 @@ def image_resize(input, Bilinear interpolation: - case 1: + if: align_corners = False , align_mode = 0 input : (N,C,H_in,W_in) @@ -6600,10 +6600,7 @@ def image_resize(input, W_out = (W_{in}+0.5) * scale_{factor} - 0.5 - case 2: - align_corners = False , align_mode = 1 - or - align_corners = True + else: input : (N,C,H_in,W_in) output: (N,C,H_out,W_out) where: @@ -6652,8 +6649,9 @@ def image_resize(input, input and output tensors are aligned, preserving the values at the corner pixels. Default: True - align_mode(int) : An optional input to specify align_corners mode. can be \'0\' - for pytorch calculation method, can be \'1'\ for tensorflow calculation method. + align_mode(int) : An optional input to specify src_idx calculation. can be \'0\' + for src_idx = scale*(dst_indx+0.5)-0.5 , can be \'1\' for + src_idx = scale*dst_index . Returns: Variable: The output is a 4-D tensor of the shape @@ -6769,7 +6767,7 @@ def resize_bilinear(input, Example: - for scale: + For scale: if align_corners = True && out_size > 1 : @@ -6781,7 +6779,7 @@ def resize_bilinear(input, Bilinear interpolation: - case 1: + if: align_corners = False , align_mode = 0 input : (N,C,H_in,W_in) @@ -6791,11 +6789,8 @@ def resize_bilinear(input, W_out = (W_{in}+0.5) * scale_{factor} - 0.5 - case 2: - align_corners = False , align_mode = 1 - or - align_corners = True - + else: + input : (N,C,H_in,W_in) output: (N,C,H_out,W_out) where: @@ -6858,7 +6853,7 @@ def resize_nearest(input, Example: - for scale: + For scale: if align_corners = True && out_size > 1 : diff --git a/python/paddle/fluid/tests/unittests/test_bilinear_interp_op.py b/python/paddle/fluid/tests/unittests/test_bilinear_interp_op.py index 4523fb54cea667f338ec14baf836e4c6308c870f..2e3de58a3abcb694b1d392d9e49165bb56bd9ae4 100644 --- a/python/paddle/fluid/tests/unittests/test_bilinear_interp_op.py +++ b/python/paddle/fluid/tests/unittests/test_bilinear_interp_op.py @@ -54,6 +54,7 @@ def bilinear_interp_np(input, else: h = int(ratio_h * i) + h = max(0, h) hid = 1 if h < in_h - 1 else 0 if (align_mode == 0 and not align_corners): h1lambda = ratio_h * (i + 0.5) - 0.5 - h @@ -65,6 +66,7 @@ def bilinear_interp_np(input, w = int(ratio_w * (j + 0.5) - 0.5) else: w = int(ratio_w * j) + w = max(0, w) wid = 1 if w < in_w - 1 else 0 if (align_mode == 0 and not align_corners): w1lambda = ratio_w * (j + 0.5) - 0.5 - w @@ -116,8 +118,8 @@ class TestBilinearInterpOp(OpTest): self.out_h = 2 self.out_w = 2 self.out_size = np.array([3, 3]).astype("int32") - self.align_corners = False - self.align_mode = 0 + self.align_corners = True + self.align_mode = 1 class TestBilinearInterpCase1(TestBilinearInterpOp): @@ -126,8 +128,8 @@ class TestBilinearInterpCase1(TestBilinearInterpOp): self.input_shape = [4, 1, 7, 8] self.out_h = 1 self.out_w = 1 - self.align_corners = False - self.align_mode = 0 + self.align_corners = True + self.align_mode = 1 class TestBilinearInterpCase2(TestBilinearInterpOp): @@ -136,8 +138,8 @@ class TestBilinearInterpCase2(TestBilinearInterpOp): self.input_shape = [3, 3, 9, 6] self.out_h = 12 self.out_w = 12 - self.align_corners = False - self.align_mode = 0 + self.align_corners = True + self.align_mode = 1 class TestBilinearInterpCase3(TestBilinearInterpOp): @@ -146,8 +148,8 @@ class TestBilinearInterpCase3(TestBilinearInterpOp): self.input_shape = [1, 1, 128, 64] self.out_h = 64 self.out_w = 128 - self.align_corners = False - self.align_mode = 0 + self.align_corners = True + self.align_mode = 1 class TestBilinearInterpCase4(TestBilinearInterpOp): @@ -157,8 +159,8 @@ class TestBilinearInterpCase4(TestBilinearInterpOp): self.out_h = 1 self.out_w = 1 self.out_size = np.array([2, 2]).astype("int32") - self.align_corners = False - self.align_mode = 0 + self.align_corners = True + self.align_mode = 1 class TestBilinearInterpCase5(TestBilinearInterpOp): @@ -168,8 +170,8 @@ class TestBilinearInterpCase5(TestBilinearInterpOp): self.out_h = 12 self.out_w = 12 self.out_size = np.array([11, 11]).astype("int32") - self.align_corners = False - self.align_mode = 0 + self.align_corners = True + self.align_mode = 1 class TestBilinearInterpCase6(TestBilinearInterpOp): @@ -179,8 +181,8 @@ class TestBilinearInterpCase6(TestBilinearInterpOp): self.out_h = 64 self.out_w = 128 self.out_size = np.array([65, 129]).astype("int32") - self.align_corners = False - self.align_mode = 0 + self.align_corners = True + self.align_mode = 1 class TestBilinearInterpActualShape(TestBilinearInterpOp): @@ -190,8 +192,8 @@ class TestBilinearInterpActualShape(TestBilinearInterpOp): self.out_h = 64 self.out_w = 32 self.out_size = np.array([66, 40]).astype("int32") - self.align_corners = False - self.align_mode = 0 + self.align_corners = True + self.align_mode = 1 class TestBilinearInterpOpUint8(OpTest): @@ -225,8 +227,8 @@ class TestBilinearInterpOpUint8(OpTest): self.input_shape = [1, 3, 9, 6] self.out_h = 10 self.out_w = 9 - self.align_corners = False - self.align_mode = 0 + self.align_corners = True + self.align_mode = 1 class TestBilinearInterpCase1Uint8(TestBilinearInterpOpUint8): @@ -235,8 +237,8 @@ class TestBilinearInterpCase1Uint8(TestBilinearInterpOpUint8): self.input_shape = [2, 3, 128, 64] self.out_h = 120 self.out_w = 50 - self.align_corners = False - self.align_mode = 0 + self.align_corners = True + self.align_mode = 1 class TestBilinearInterpCase2Uint8(TestBilinearInterpOpUint8): @@ -246,20 +248,20 @@ class TestBilinearInterpCase2Uint8(TestBilinearInterpOpUint8): self.out_h = 5 self.out_w = 13 self.out_size = np.array([6, 15]).astype("int32") - self.align_corners = False - self.align_mode = 0 + self.align_corners = True + self.align_mode = 1 class TestBilinearInterpOtherMethod1(TestBilinearInterpOp): def set_align_mode(self): - self.align_mode = 1 self.align_corners = False + self.align_mode = 1 class TestBilinearInterpWithMethod2(TestBilinearInterpOp): def set_align_mode(self): - self.align_corners = True - self.align_mode = 1 + self.align_corners = False + self.align_mode = 0 class TestBilinearInterpWithMethod3(TestBilinearInterpOp): diff --git a/python/paddle/fluid/tests/unittests/test_nearest_interp_op.py b/python/paddle/fluid/tests/unittests/test_nearest_interp_op.py index 22f7bac0be0ca62025ce3d220395d4e80ab0c6b3..c97aa886a9aaa83bab10ab192ca835a6a8ce6b75 100644 --- a/python/paddle/fluid/tests/unittests/test_nearest_interp_op.py +++ b/python/paddle/fluid/tests/unittests/test_nearest_interp_op.py @@ -108,7 +108,7 @@ class TestNearestNeighborInterpCase1(TestNearestInterpOp): self.input_shape = [4, 1, 7, 8] self.out_h = 1 self.out_w = 1 - self.align_corners = False + self.align_corners = True class TestNearestNeighborInterpCase2(TestNearestInterpOp):