Files
2026-07-13 12:40:42 +08:00

438 lines
12 KiB
Python

# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import numpy as np
from dygraph_to_static_utils import (
Dy2StTestBase,
test_default_mode_only,
)
import paddle
from paddle import to_tensor
from paddle.jit.api import to_static
SEED = 2020
np.random.seed(SEED)
def dyfunc_to_tensor(x):
res1 = paddle.to_tensor(x, dtype=None, place=None, stop_gradient=True)
res2 = paddle.tensor.to_tensor(data=res1)
res3 = to_tensor(data=res2)
return res3
def dyfunc_int_to_tensor(x):
res = paddle.to_tensor(3)
return res
def dyfunc_float_to_tensor(x):
return paddle.to_tensor(2.0)
def dyfunc_bool_to_tensor(x):
return paddle.to_tensor(True)
class TestDygraphBasicApi_ToVariable(Dy2StTestBase):
def setUp(self):
self.input = np.ones(5).astype("int32")
self.test_funcs = [
dyfunc_to_tensor,
dyfunc_bool_to_tensor,
dyfunc_int_to_tensor,
dyfunc_float_to_tensor,
]
def get_dygraph_output(self):
res = self.dygraph_func(self.input).numpy()
return res
def get_static_output(self):
static_res = to_static(self.dygraph_func)(self.input).numpy()
return static_res
@test_default_mode_only
def test_transformed_static_result(self):
for func in self.test_funcs:
self.dygraph_func = func
dygraph_res = self.get_dygraph_output()
static_res = self.get_static_output()
np.testing.assert_allclose(dygraph_res, static_res, rtol=1e-05)
# test Apis that inherit from layers.Layer
def dyfunc_BilinearTensorProduct(bilinearTensorProduct, x1, x2):
res = bilinearTensorProduct(
paddle.to_tensor(x1),
paddle.to_tensor(x2),
)
return res
def dyfunc_conv2d(conv2d, input):
res = conv2d(input)
return res
def dyfunc_conv3d(conv3d, input):
res = conv3d(input)
return res
def dyfunc_conv2d_transpose(conv2dTranspose, input):
ret = conv2dTranspose(input)
return ret
def dyfunc_conv3d_transpose(conv3dTranspose, input):
ret = conv3dTranspose(input)
return ret
def dyfunc_linear(fc, m, input):
res = fc(input)
return m(res)
def dyfunc_pool2d(input):
paddle.nn.AvgPool2D(kernel_size=2, stride=1)
pool2d = paddle.nn.AvgPool2D(kernel_size=2, stride=1)
res = pool2d(input)
return res
def dyfunc_prelu(prelu0, input):
res = prelu0(input)
return res
class TestDygraphBasicApi(Dy2StTestBase):
# Compare results of dynamic graph and transformed static graph function which only
# includes basic Api.
def setUp(self):
self.input = np.random.random((1, 4, 3, 3)).astype('float32')
self.dygraph_func = dyfunc_pool2d
def get_dygraph_output(self):
paddle.seed(SEED)
data = paddle.to_tensor(self.input)
res = self.dygraph_func(data).numpy()
return res
def get_static_output(self):
data = paddle.assign(self.input)
static_res = to_static(self.dygraph_func)(data).numpy()
return static_res
@test_default_mode_only
def test_transformed_static_result(self):
dygraph_res = self.get_dygraph_output()
static_res = self.get_static_output()
np.testing.assert_allclose(dygraph_res, static_res, rtol=1e-05)
class TestDygraphBasicApi_BilinearTensorProduct(TestDygraphBasicApi):
def setUp(self):
self.input1 = np.random.random((5, 5)).astype('float32')
self.input2 = np.random.random((5, 4)).astype('float32')
bilinearTensorProduct = paddle.nn.Bilinear(
5,
4,
1000,
weight_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.99)
),
bias_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.5)
),
)
self.dygraph_func = lambda x, y: dyfunc_BilinearTensorProduct(
bilinearTensorProduct, x, y
)
def get_dygraph_output(self):
paddle.seed(SEED)
res = self.dygraph_func(self.input1, self.input2).numpy()
return res
def get_static_output(self):
static_res = to_static(self.dygraph_func)(
self.input1, self.input2
).numpy()
return static_res
class TestDygraphBasicApi_Conv2D(TestDygraphBasicApi):
def setUp(self):
conv2d = paddle.nn.Conv2D(
in_channels=3,
out_channels=2,
kernel_size=3,
weight_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.99)
),
bias_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.5)
),
)
self.input = np.random.random((1, 3, 3, 5)).astype('float32')
self.dygraph_func = lambda x: dyfunc_conv2d(conv2d, x)
class TestDygraphBasicApi_Conv3D(TestDygraphBasicApi):
def setUp(self):
self.input = np.random.random((1, 3, 3, 3, 5)).astype('float32')
conv3d = paddle.nn.Conv3D(
in_channels=3,
out_channels=2,
kernel_size=3,
weight_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.99)
),
bias_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.5)
),
)
self.dygraph_func = lambda x: dyfunc_conv3d(conv3d, x)
class TestDygraphBasicApi_Conv2DTranspose(TestDygraphBasicApi):
def setUp(self):
self.input = np.random.random((5, 3, 32, 32)).astype('float32')
conv2d_transpose = paddle.nn.Conv2DTranspose(
3,
12,
12,
weight_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.99)
),
bias_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.5)
),
)
self.dygraph_func = lambda x: dyfunc_conv2d_transpose(
conv2d_transpose, x
)
class TestDygraphBasicApi_Conv3DTranspose(TestDygraphBasicApi):
def setUp(self):
self.input = np.random.random((5, 3, 12, 32, 32)).astype('float32')
conv3d_transpose = paddle.nn.Conv3DTranspose(
in_channels=3,
out_channels=12,
kernel_size=12,
weight_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.99)
),
bias_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.5)
),
)
self.dygraph_func = lambda x: dyfunc_conv3d_transpose(
conv3d_transpose, x
)
class TestDygraphBasicApi_Linear(TestDygraphBasicApi):
def setUp(self):
self.input = np.random.random((4, 3, 10)).astype('float32')
fc = paddle.nn.Linear(
in_features=10,
out_features=5,
weight_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.99)
),
bias_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(value=0.5)
),
)
m = paddle.nn.ReLU()
self.dygraph_func = lambda x: dyfunc_linear(fc, m, x)
class TestDygraphBasicApi_Prelu(TestDygraphBasicApi):
def setUp(self):
self.input = np.ones([5, 20, 10, 10]).astype('float32')
prelu0 = paddle.nn.PReLU(
weight_attr=paddle.ParamAttr(
initializer=paddle.nn.initializer.Constant(1.0)
),
)
self.dygraph_func = lambda x: dyfunc_prelu(prelu0, x)
# 2. test Apis that inherit from LearningRateDecay
def dyfunc_cosine_decay(CosineDecay):
lr = CosineDecay()
return paddle.to_tensor(lr)
def dyfunc_exponential_decay():
base_lr = 0.1
exponential_decay = paddle.optimizer.lr.ExponentialDecay(
learning_rate=base_lr, gamma=0.5
)
lr = exponential_decay()
return lr
def dyfunc_inverse_time_decay():
base_lr = 0.1
inverse_time_decay = paddle.optimizer.lr.InverseTimeDecay(
learning_rate=base_lr, gamma=0.5
)
lr = inverse_time_decay()
return lr
def dyfunc_natural_exp_decay():
base_lr = 0.1
natural_exp_decay = paddle.optimizer.lr.NaturalExpDecay(
learning_rate=base_lr, gamma=0.5
)
lr = natural_exp_decay()
return lr
def dyfunc_noam_decay():
noam_decay = paddle.optimizer.lr.NoamDecay(100, 100)
lr = noam_decay()
return paddle.to_tensor(lr)
def dyfunc_piecewise_decay():
boundaries = [10000, 20000]
values = [1.0, 0.5, 0.1]
pd = paddle.optimizer.lr.PiecewiseDecay(boundaries, values)
lr = pd()
return paddle.to_tensor(lr)
def dyfunc_polynomial_decay():
start_lr = 0.01
total_step = 5000
end_lr = 0
pd = paddle.optimizer.lr.PolynomialDecay(
start_lr, total_step, end_lr, power=1.0
)
lr = pd()
return paddle.to_tensor(lr)
class TestDygraphBasicApi_CosineDecay(Dy2StTestBase):
def setUp(self):
base_lr = 0.1
CosineDecay = paddle.optimizer.lr.CosineAnnealingDecay(
learning_rate=base_lr, T_max=120
)
self.dygraph_func = lambda: dyfunc_cosine_decay(CosineDecay)
def get_dygraph_output(self):
res = self.dygraph_func().numpy()
return res
def get_static_output(self):
static_res = to_static(self.dygraph_func)()
return static_res
@test_default_mode_only
def test_transformed_static_result(self):
dygraph_res = self.get_dygraph_output()
static_res = self.get_static_output()
np.testing.assert_allclose(dygraph_res, static_res, rtol=1e-05)
class TestDygraphBasicApi_ExponentialDecay(TestDygraphBasicApi_CosineDecay):
def setUp(self):
self.dygraph_func = dyfunc_exponential_decay
def get_dygraph_output(self):
paddle.seed(SEED)
res = self.dygraph_func()
return res
def get_static_output(self):
static_out = to_static(self.dygraph_func)()
return static_out
class TestDygraphBasicApi_InverseTimeDecay(TestDygraphBasicApi_CosineDecay):
def setUp(self):
self.dygraph_func = dyfunc_inverse_time_decay
def get_dygraph_output(self):
paddle.seed(SEED)
res = self.dygraph_func()
return res
def get_static_output(self):
static_out = to_static(self.dygraph_func)()
return static_out
class TestDygraphBasicApi_NaturalExpDecay(TestDygraphBasicApi_CosineDecay):
def setUp(self):
self.dygraph_func = dyfunc_natural_exp_decay
def get_dygraph_output(self):
paddle.seed(SEED)
res = self.dygraph_func()
return res
def get_static_output(self):
static_out = to_static(self.dygraph_func)()
return static_out
class TestDygraphBasicApi_NoamDecay(TestDygraphBasicApi_CosineDecay):
def setUp(self):
self.dygraph_func = dyfunc_noam_decay
class TestDygraphBasicApi_PiecewiseDecay(TestDygraphBasicApi_CosineDecay):
def setUp(self):
self.dygraph_func = dyfunc_piecewise_decay
class TestDygraphBasicApi_PolynomialDecay(TestDygraphBasicApi_CosineDecay):
def setUp(self):
self.dygraph_func = dyfunc_polynomial_decay
def get_dygraph_output(self):
paddle.seed(SEED)
res = self.dygraph_func()
return res
if __name__ == '__main__':
unittest.main()