Files
paddlepaddle--paddle/test/ai_edited_test/test_ai_functional_activations.py
T
2026-07-13 12:40:42 +08:00

206 lines
6.8 KiB
Python

# Copyright (c) 2026 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.
"""
激活函数单元测试 / Activation Function Unit Tests
测试目标 / Test Target:
paddle.nn.functional 激活函数
覆盖的模块 / Covered Modules:
- F.relu/relu6/leaky_relu/prelu
- F.sigmoid/tanh/swish/silu
- F.gelu/elu/selu/celu
- F.softplus/softsign/mish
- F.log_softmax/log_sigmoid
作用 / Purpose:
补充函数式激活函数API的测试,提升覆盖率。
"""
import unittest
import numpy as np
import paddle
import paddle.nn.functional as F
paddle.disable_static()
class TestReluFamily(unittest.TestCase):
"""测试ReLU系列激活函数 / Test ReLU family activations"""
def test_relu(self):
"""测试ReLU / Test ReLU"""
x = paddle.to_tensor([-2.0, -1.0, 0.0, 1.0, 2.0])
result = F.relu(x)
np.testing.assert_allclose(result.numpy(), [0.0, 0.0, 0.0, 1.0, 2.0])
def test_relu6(self):
"""测试ReLU6 / Test ReLU6"""
x = paddle.to_tensor([-1.0, 0.0, 3.0, 6.0, 8.0])
result = F.relu6(x)
np.testing.assert_allclose(result.numpy(), [0.0, 0.0, 3.0, 6.0, 6.0])
def test_leaky_relu(self):
"""测试LeakyReLU / Test LeakyReLU"""
x = paddle.to_tensor([-2.0, -1.0, 0.0, 1.0, 2.0])
result = F.leaky_relu(x, negative_slope=0.1)
np.testing.assert_allclose(
result.numpy(), [-0.2, -0.1, 0.0, 1.0, 2.0], rtol=1e-5
)
def test_elu(self):
"""测试ELU / Test ELU"""
x = paddle.to_tensor([-1.0, 0.0, 1.0])
result = F.elu(x, alpha=1.0)
self.assertEqual(result.shape, [3])
# For x < 0: alpha*(exp(x)-1), for x >= 0: x
np.testing.assert_allclose(
float(result[0].numpy()), 1.0 * (np.exp(-1.0) - 1), rtol=1e-5
)
def test_selu(self):
"""测试SELU / Test SELU"""
x = paddle.to_tensor([-1.0, 0.0, 1.0])
result = F.selu(x)
self.assertEqual(result.shape, [3])
def test_prelu(self):
"""测试PReLU / Test PReLU"""
weight = paddle.to_tensor([0.25])
x = paddle.to_tensor([-2.0, -1.0, 0.0, 1.0, 2.0])
result = F.prelu(x, weight)
np.testing.assert_allclose(
result.numpy(), [-0.5, -0.25, 0.0, 1.0, 2.0], rtol=1e-5
)
class TestSigmoidFamily(unittest.TestCase):
"""测试Sigmoid系列激活函数 / Test Sigmoid family activations"""
def test_sigmoid(self):
"""测试Sigmoid / Test Sigmoid"""
x = paddle.to_tensor([0.0])
result = F.sigmoid(x)
self.assertAlmostEqual(float(result.item()), 0.5, places=5)
def test_tanh(self):
"""测试Tanh / Test Tanh"""
x = paddle.to_tensor([0.0, 1.0, -1.0])
result = F.tanh(x)
np.testing.assert_allclose(
result.numpy(), np.tanh([0.0, 1.0, -1.0]), rtol=1e-5
)
def test_hardtanh(self):
"""测试HardTanh / Test HardTanh"""
x = paddle.to_tensor([-3.0, -0.5, 0.0, 0.5, 3.0])
result = F.hardtanh(x, min=-1.0, max=1.0)
np.testing.assert_allclose(result.numpy(), [-1.0, -0.5, 0.0, 0.5, 1.0])
def test_hardsigmoid(self):
"""测试HardSigmoid / Test HardSigmoid"""
x = paddle.to_tensor([-3.0, 0.0, 3.0])
result = F.hardsigmoid(x)
self.assertEqual(result.shape, [3])
self.assertAlmostEqual(float(result[0].numpy()), 0.0, places=5)
self.assertAlmostEqual(float(result[2].numpy()), 1.0, places=5)
def test_log_sigmoid(self):
"""测试LogSigmoid / Test LogSigmoid"""
x = paddle.to_tensor([0.0, 1.0, -1.0])
result = F.log_sigmoid(x)
expected = np.log(1 / (1 + np.exp(-np.array([0.0, 1.0, -1.0]))))
np.testing.assert_allclose(result.numpy(), expected, rtol=1e-5)
class TestSwishAndMish(unittest.TestCase):
"""测试Swish/Mish激活函数 / Test Swish/Mish activations"""
def test_swish(self):
"""测试Swish / Test Swish"""
x = paddle.to_tensor([0.0, 1.0, -1.0])
result = F.swish(x)
self.assertEqual(result.shape, [3])
# swish(x) = x * sigmoid(x)
expected = np.array([0.0, 1.0, -1.0]) * (
1 / (1 + np.exp(-np.array([0.0, 1.0, -1.0])))
)
np.testing.assert_allclose(result.numpy(), expected, rtol=1e-5)
def test_silu(self):
"""测试SiLU (Swish) / Test SiLU"""
x = paddle.to_tensor([0.0, 1.0, -1.0])
result = F.silu(x)
self.assertEqual(result.shape, [3])
def test_mish(self):
"""测试Mish / Test Mish"""
x = paddle.to_tensor([0.0, 1.0, -1.0])
result = F.mish(x)
self.assertEqual(result.shape, [3])
def test_gelu(self):
"""测试GELU / Test GELU"""
x = paddle.to_tensor([0.0, 1.0, -1.0])
result = F.gelu(x)
self.assertEqual(result.shape, [3])
def test_gelu_approximate(self):
"""测试近似GELU / Test approximate GELU"""
x = paddle.to_tensor([0.0, 1.0, -1.0])
result = F.gelu(x, approximate=True)
self.assertEqual(result.shape, [3])
class TestSoftmaxFamily(unittest.TestCase):
"""测试Softmax系列 / Test Softmax family"""
def test_softmax(self):
"""测试Softmax / Test Softmax"""
x = paddle.to_tensor([[1.0, 2.0, 3.0]])
result = F.softmax(x, axis=1)
self.assertAlmostEqual(float(paddle.sum(result).numpy()), 1.0, places=5)
def test_log_softmax(self):
"""测试LogSoftmax / Test LogSoftmax"""
x = paddle.to_tensor([[1.0, 2.0, 3.0]])
result = F.log_softmax(x, axis=1)
# exp(log_softmax) should sum to 1
np.testing.assert_allclose(
float(paddle.exp(result).sum().numpy()), 1.0, rtol=1e-5
)
def test_softplus(self):
"""测试Softplus / Test Softplus"""
x = paddle.to_tensor([-1.0, 0.0, 1.0])
result = F.softplus(x)
self.assertEqual(result.shape, [3])
# All outputs should be positive
self.assertTrue(bool((result > 0).all().numpy()))
def test_softsign(self):
"""测试Softsign / Test Softsign"""
x = paddle.to_tensor([-1.0, 0.0, 1.0])
result = F.softsign(x)
# softsign(x) = x / (1 + |x|)
expected = np.array([-1.0, 0.0, 1.0]) / (1 + np.abs([-1.0, 0.0, 1.0]))
np.testing.assert_allclose(result.numpy(), expected, rtol=1e-5)
if __name__ == '__main__':
unittest.main()