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

267 lines
10 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.
"""
分布式概率分布单元测试 / Probability Distribution Unit Tests
测试目标 / Test Target:
paddle.distribution 模块 (覆盖率约84.2%)
覆盖的模块 / Covered Modules:
- paddle.distribution.Normal: 正态分布
- paddle.distribution.Uniform: 均匀分布
- paddle.distribution.Categorical: 类别分布
- paddle.distribution.Bernoulli: 伯努利分布
- paddle.distribution.Beta: Beta分布
- paddle.distribution.Dirichlet: Dirichlet分布
- paddle.distribution.Geometric: 几何分布
- paddle.distribution.LogNormal: 对数正态分布
作用 / Purpose:
覆盖各类概率分布的sample、log_prob、entropy、cdf等操作路径,
补充概率分布模块中未被测试覆盖的代码路径。
"""
import unittest
import numpy as np
import paddle
import paddle.distribution as dist
paddle.disable_static()
class TestNormalDistribution(unittest.TestCase):
"""测试正态分布 / Test Normal distribution"""
def test_normal_sample(self):
"""测试正态分布采样 / Test Normal distribution sampling"""
normal = dist.Normal(loc=0.0, scale=1.0)
samples = normal.sample([100])
self.assertEqual(samples.shape, [100])
def test_normal_log_prob(self):
"""测试正态分布对数概率 / Test Normal log probability"""
normal = dist.Normal(loc=0.0, scale=1.0)
x = paddle.to_tensor([0.0, 1.0, -1.0])
log_prob = normal.log_prob(x)
self.assertEqual(log_prob.shape, [3])
def test_normal_entropy(self):
"""测试正态分布熵 / Test Normal entropy"""
normal = dist.Normal(loc=0.0, scale=1.0)
entropy = normal.entropy()
self.assertIsNotNone(entropy)
self.assertTrue(entropy.item() > 0)
def test_normal_mean_variance(self):
"""测试正态分布均值和方差 / Test Normal mean and variance"""
normal = dist.Normal(loc=2.0, scale=3.0)
self.assertAlmostEqual(float(normal.mean.numpy()), 2.0, places=5)
self.assertAlmostEqual(float(normal.variance.numpy()), 9.0, places=5)
def test_normal_kl_divergence(self):
"""测试正态分布KL散度 / Test Normal KL divergence"""
p = dist.Normal(loc=0.0, scale=1.0)
q = dist.Normal(loc=1.0, scale=2.0)
kl = paddle.distribution.kl_divergence(p, q)
self.assertTrue(kl.item() >= 0)
def test_normal_batch(self):
"""测试批量正态分布 / Test batched Normal distribution"""
loc = paddle.to_tensor([0.0, 1.0, 2.0])
scale = paddle.to_tensor([1.0, 1.0, 1.0])
normal = dist.Normal(loc=loc, scale=scale)
samples = normal.sample([10])
self.assertEqual(samples.shape, [10, 3])
class TestUniformDistribution(unittest.TestCase):
"""测试均匀分布 / Test Uniform distribution"""
def test_uniform_sample(self):
"""测试均匀分布采样 / Test Uniform sampling"""
uniform = dist.Uniform(low=0.0, high=1.0)
samples = uniform.sample([100])
self.assertEqual(samples.shape, [100])
self.assertTrue(paddle.all(samples >= 0.0).item())
self.assertTrue(paddle.all(samples <= 1.0).item())
def test_uniform_log_prob(self):
"""测试均匀分布对数概率 / Test Uniform log probability"""
uniform = dist.Uniform(low=0.0, high=1.0)
x = paddle.to_tensor([0.5])
log_prob = uniform.log_prob(x)
self.assertAlmostEqual(log_prob.numpy()[0], 0.0, places=5)
def test_uniform_entropy(self):
"""测试均匀分布熵 / Test Uniform entropy"""
uniform = dist.Uniform(low=0.0, high=2.0)
entropy = uniform.entropy()
# entropy of Uniform(0,2) = log(2)
self.assertAlmostEqual(float(entropy.numpy()), np.log(2.0), places=4)
def test_uniform_sample_range(self):
"""测试均匀分布采样范围 / Test Uniform sample range"""
uniform = dist.Uniform(low=0.0, high=4.0)
samples = uniform.sample([1000])
# Mean should be close to 2.0
sample_mean = float(samples.mean().numpy())
self.assertAlmostEqual(sample_mean, 2.0, delta=0.2)
class TestCategoricalDistribution(unittest.TestCase):
"""测试类别分布 / Test Categorical distribution"""
def test_categorical_sample(self):
"""测试类别分布采样 / Test Categorical sampling"""
logits = paddle.to_tensor([1.0, 2.0, 3.0])
categorical = dist.Categorical(logits=logits)
samples = categorical.sample([10])
self.assertEqual(samples.shape, [10])
def test_categorical_log_prob(self):
"""测试类别分布对数概率 / Test Categorical log probability"""
logits = paddle.to_tensor([1.0, 2.0, 3.0])
categorical = dist.Categorical(logits=logits)
x = paddle.to_tensor([0, 1, 2])
log_prob = categorical.log_prob(x)
self.assertEqual(log_prob.shape, [3])
def test_categorical_entropy(self):
"""测试类别分布熵 / Test Categorical entropy"""
# Uniform logits => maximum entropy
logits = paddle.zeros([4])
categorical = dist.Categorical(logits=logits)
entropy = categorical.entropy()
self.assertAlmostEqual(float(entropy.numpy()), np.log(4.0), places=4)
class TestBernoulliDistribution(unittest.TestCase):
"""测试伯努利分布 / Test Bernoulli distribution"""
def test_bernoulli_sample(self):
"""测试伯努利分布采样 / Test Bernoulli sampling"""
bernoulli = dist.Bernoulli(probs=0.5)
samples = bernoulli.sample([100])
self.assertEqual(samples.shape, [100])
unique_vals = paddle.unique(samples).numpy()
# Only 0 and 1
self.assertTrue(all(v in [0, 1] for v in unique_vals))
def test_bernoulli_log_prob(self):
"""测试伯努利分布对数概率 / Test Bernoulli log probability"""
bernoulli = dist.Bernoulli(probs=0.7)
x = paddle.to_tensor([0.0, 1.0])
log_prob = bernoulli.log_prob(x)
self.assertEqual(log_prob.shape, [2])
def test_bernoulli_entropy(self):
"""测试伯努利分布熵 / Test Bernoulli entropy"""
bernoulli = dist.Bernoulli(probs=0.5)
entropy = bernoulli.entropy()
# Binary entropy at p=0.5 is log(2)
self.assertAlmostEqual(float(entropy.numpy()), np.log(2.0), places=4)
def test_bernoulli_mean_variance(self):
"""测试伯努利分布均值和方差 / Test Bernoulli mean and variance"""
p = 0.3
bernoulli = dist.Bernoulli(probs=p)
mean = bernoulli.mean
var = bernoulli.variance
self.assertAlmostEqual(float(mean.numpy()), p, places=5)
self.assertAlmostEqual(float(var.numpy()), p * (1 - p), places=5)
class TestBetaDistribution(unittest.TestCase):
"""测试Beta分布 / Test Beta distribution"""
def test_beta_sample(self):
"""测试Beta分布采样 / Test Beta sampling"""
beta = dist.Beta(alpha=2.0, beta=5.0)
samples = beta.sample([100])
self.assertEqual(samples.shape, [100])
self.assertTrue(paddle.all(samples > 0).item())
self.assertTrue(paddle.all(samples < 1).item())
def test_beta_log_prob(self):
"""测试Beta分布对数概率 / Test Beta log probability"""
beta = dist.Beta(alpha=2.0, beta=5.0)
x = paddle.to_tensor([0.3, 0.5, 0.7])
log_prob = beta.log_prob(x)
self.assertEqual(log_prob.shape, [3])
def test_beta_entropy(self):
"""测试Beta分布熵 / Test Beta entropy"""
beta = dist.Beta(alpha=2.0, beta=5.0)
entropy = beta.entropy()
self.assertIsNotNone(entropy)
def test_beta_mean_variance(self):
"""测试Beta分布均值和方差 / Test Beta mean and variance"""
alpha, b = 2.0, 5.0
beta = dist.Beta(alpha=alpha, beta=b)
expected_mean = alpha / (alpha + b)
self.assertAlmostEqual(
float(beta.mean.numpy()), expected_mean, places=4
)
class TestLogNormalDistribution(unittest.TestCase):
"""测试对数正态分布 / Test LogNormal distribution"""
def test_lognormal_sample(self):
"""测试对数正态分布采样 / Test LogNormal sampling"""
lognormal = dist.LogNormal(loc=0.0, scale=1.0)
samples = lognormal.sample([100])
self.assertEqual(samples.shape, [100])
self.assertTrue(paddle.all(samples > 0).item())
def test_lognormal_log_prob(self):
"""测试对数正态分布对数概率 / Test LogNormal log probability"""
lognormal = dist.LogNormal(loc=0.0, scale=1.0)
x = paddle.to_tensor([1.0, 2.0, 0.5])
log_prob = lognormal.log_prob(x)
self.assertEqual(log_prob.shape, [3])
def test_lognormal_entropy(self):
"""测试对数正态分布熵 / Test LogNormal entropy"""
lognormal = dist.LogNormal(loc=0.0, scale=1.0)
entropy = lognormal.entropy()
self.assertIsNotNone(entropy)
class TestTransformedDistribution(unittest.TestCase):
"""测试变换分布 / Test transformed distributions"""
def test_independent_distribution(self):
"""测试独立分布包装 / Test Independent distribution wrapper"""
base = dist.Normal(loc=paddle.zeros([3]), scale=paddle.ones([3]))
independent = dist.Independent(base, 1)
samples = independent.sample([10])
self.assertEqual(samples.shape, [10, 3])
def test_independent_log_prob(self):
"""测试独立分布的log_prob / Test Independent log_prob"""
base = dist.Normal(loc=paddle.zeros([3]), scale=paddle.ones([3]))
independent = dist.Independent(base, 1)
x = paddle.zeros([10, 3])
log_prob = independent.log_prob(x)
self.assertEqual(log_prob.shape, [10])
if __name__ == '__main__':
unittest.main()