未验证 提交 2afa7b93 编写于 作者: R Ryan 提交者: GitHub

[Dy2St] transforms.RandomRotation Support static mode (#49128)

上级 0edbd7a5
......@@ -30,7 +30,7 @@ class TestTransformUnitTestBase(unittest.TestCase):
self.set_trans_api()
def get_shape(self):
return (64, 64, 3)
return (3, 64, 64)
def set_trans_api(self):
self.api = transforms.Resize(size=16)
......@@ -142,5 +142,21 @@ class TestRandomCrop_same(TestTransformUnitTestBase):
self.api = transforms.RandomCrop(self.crop_size)
class TestRandomRotation(TestTransformUnitTestBase):
def set_trans_api(self):
degree = np.random.uniform(-180, 180)
eps = 10e-5
degree_tuple = (degree - eps, degree + eps)
self.api = transforms.RandomRotation(degree_tuple)
class TestRandomRotation_expand_True(TestTransformUnitTestBase):
def set_trans_api(self):
degree = np.random.uniform(-180, 180)
eps = 10e-5
degree_tuple = (degree - eps, degree + eps)
self.api = transforms.RandomRotation(degree_tuple, expand=True, fill=3)
if __name__ == "__main__":
unittest.main()
......@@ -15,6 +15,8 @@
import math
import numbers
import numpy as np
import paddle
import paddle.nn.functional as F
......@@ -221,12 +223,23 @@ def _affine_grid(theta, w, h, ow, oh):
x_grid = paddle.linspace(-ow * 0.5 + d, ow * 0.5 + d - 1, ow)
base_grid[..., 0] = x_grid
y_grid = paddle.linspace(-oh * 0.5 + d, oh * 0.5 + d - 1, oh).unsqueeze_(-1)
base_grid[..., 1] = y_grid
scaled_theta = theta.transpose((0, 2, 1)) / paddle.to_tensor(
[0.5 * w, 0.5 * h]
if paddle.in_dynamic_mode():
y_grid = paddle.linspace(
-oh * 0.5 + d, oh * 0.5 + d - 1, oh
).unsqueeze_(-1)
base_grid[..., 1] = y_grid
tmp = paddle.to_tensor([0.5 * w, 0.5 * h])
else:
# To eliminate the warning:
# In static mode, unsqueeze_() is the same as unsqueeze() and does not perform inplace operation.
y_grid = paddle.linspace(-oh * 0.5 + d, oh * 0.5 + d - 1, oh).unsqueeze(
-1
)
base_grid[..., 1] = y_grid
tmp = paddle.assign(np.array([0.5 * w, 0.5 * h], dtype="float32"))
scaled_theta = theta.transpose((0, 2, 1)) / tmp
output_grid = base_grid.reshape((1, oh * ow, 3)).bmm(scaled_theta)
return output_grid.reshape((1, oh, ow, 2))
......@@ -252,10 +265,20 @@ def _grid_transform(img, grid, mode, fill):
if fill is not None:
mask = img[:, -1:, :, :] # n 1 h w
img = img[:, :-1, :, :] # n c h w
mask = mask.expand_as(img)
mask = mask.tile([1, img.shape[1], 1, 1])
len_fill = len(fill) if isinstance(fill, (tuple, list)) else 1
if paddle.in_dynamic_mode():
fill_img = (
paddle.to_tensor(fill).reshape((1, len_fill, 1, 1)).expand_as(img)
paddle.to_tensor(fill)
.reshape((1, len_fill, 1, 1))
.astype(img.dtype)
.expand_as(img)
)
else:
fill = np.array(fill).reshape(len_fill).astype("float32")
fill_img = paddle.ones_like(img) * paddle.assign(fill).reshape(
[1, len_fill, 1, 1]
)
if mode == 'nearest':
......@@ -363,6 +386,7 @@ def rotate(
else:
rotn_center = [(p - s * 0.5) for p, s in zip(center, [w, h])]
if paddle.in_dynamic_mode():
angle = math.radians(angle)
matrix = [
math.cos(angle),
......@@ -372,6 +396,19 @@ def rotate(
math.cos(angle),
0.0,
]
matrix = paddle.to_tensor(matrix, place=img.place)
else:
angle = angle / 180 * math.pi
matrix = paddle.concat(
[
paddle.cos(angle),
paddle.sin(angle),
paddle.zeros([1]),
-paddle.sin(angle),
paddle.cos(angle),
paddle.zeros([1]),
]
)
matrix[2] += matrix[0] * (-rotn_center[0] - post_trans[0]) + matrix[1] * (
-rotn_center[1] - post_trans[1]
......@@ -383,11 +420,11 @@ def rotate(
matrix[2] += rotn_center[0]
matrix[5] += rotn_center[1]
matrix = paddle.to_tensor(matrix, place=img.place)
matrix = matrix.reshape((1, 2, 3))
if expand:
# calculate output size
if paddle.in_dynamic_mode():
corners = paddle.to_tensor(
[
[-0.5 * w, -0.5 * h, 1.0],
......@@ -397,6 +434,15 @@ def rotate(
],
place=matrix.place,
).astype(matrix.dtype)
else:
corners = paddle.assign(
[
[-0.5 * w, -0.5 * h, 1.0],
[-0.5 * w, 0.5 * h, 1.0],
[0.5 * w, 0.5 * h, 1.0],
[0.5 * w, -0.5 * h, 1.0],
],
).astype(matrix.dtype)
_pos = (
corners.reshape((1, -1, 3))
......@@ -410,7 +456,10 @@ def rotate(
nw = npos[0][0]
nh = npos[0][1]
if paddle.in_dynamic_mode():
ow, oh = int(nw.numpy()[0]), int(nh.numpy()[0])
else:
ow, oh = nw.astype("int32"), nh.astype("int32")
else:
ow, oh = w, h
......
......@@ -1520,7 +1520,12 @@ class RandomRotation(BaseTransform):
self.fill = fill
def _get_param(self, degrees):
if paddle.in_dynamic_mode():
angle = random.uniform(degrees[0], degrees[1])
else:
angle = paddle.uniform(
[1], dtype="float32", min=degrees[0], max=degrees[1]
)
return angle
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册