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

384 lines
14 KiB
Python

# Copyright (c) 2024 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.
# Note:
# 0D Tensor indicates that the tensor's dimension is 0
# 0D Tensor's shape is always [], numel is 1
# which can be created by paddle.rand([])
import unittest
import numpy as np
from decorator_helper import prog_scope
import paddle
import paddle.nn.functional as F
class TestDistribution(unittest.TestCase):
def setUp(self):
self.x = paddle.full([], 2.0)
def test_Bernoulli(self):
d = paddle.distribution.Bernoulli(probs=0.3)
self.assertEqual(d.mean.shape, [])
self.assertEqual(d.variance.shape, [])
self.assertEqual(d.entropy().shape, [])
self.assertEqual(d.sample([]).shape, [])
self.assertEqual(d.rsample([]).shape, [])
self.assertEqual(d.cdf(self.x).shape, [])
self.assertEqual(d.prob(self.x).shape, [])
self.assertEqual(d.log_prob(self.x).shape, [])
d_other = paddle.distribution.Bernoulli(probs=0.7)
self.assertEqual(d.kl_divergence(d_other).shape, [])
def test_Geometric(self):
d = paddle.distribution.Geometric(0.5)
self.assertEqual(d.mean.shape, [])
self.assertEqual(d.variance.shape, [])
self.assertEqual(d.entropy().shape, [])
self.assertEqual(d.stddev.shape, [])
self.assertEqual(d.pmf(self.x).shape, [])
self.assertEqual(d.log_pmf(self.x).shape, [])
self.assertEqual(d.sample([]).shape, [])
self.assertEqual(d.rsample([]).shape, [])
self.assertEqual(d.cdf(self.x).shape, [])
d_other = paddle.distribution.Geometric(probs=0.7)
self.assertEqual(d.kl_divergence(d_other).shape, [])
def test_Cauchy(self):
d = paddle.distribution.Cauchy(loc=0.1, scale=1.2)
self.assertEqual(d.sample([]).shape, [])
self.assertEqual(d.rsample([]).shape, [])
self.assertEqual(d.prob(self.x).shape, [])
self.assertEqual(d.log_prob(self.x).shape, [])
self.assertEqual(d.cdf(self.x).shape, [])
self.assertEqual(d.entropy().shape, [])
d_other = paddle.distribution.Cauchy(
loc=paddle.to_tensor(1.2), scale=paddle.to_tensor(2.3)
)
self.assertEqual(d.kl_divergence(d_other).shape, [])
def test_Categorical(self):
logits = paddle.rand([6])
d = paddle.distribution.Categorical(logits)
self.assertEqual(d.sample([]).shape, [])
self.assertEqual(d.probs(paddle.full([], 2, dtype='int64')).shape, [])
self.assertEqual(
d.log_prob(paddle.full([], 2, dtype='int64')).shape, []
)
self.assertEqual(d.entropy().shape, [])
def test_Normal(self):
normal = paddle.distribution.Normal(0.0, 3.0)
self.assertEqual(normal.sample([]).shape, [])
self.assertEqual(normal.rsample([]).shape, [])
self.assertEqual(normal.mean.shape, [])
self.assertEqual(normal.variance.shape, [])
self.assertEqual(normal.probs(self.x).shape, [])
self.assertEqual(normal.log_prob(self.x).shape, [])
self.assertEqual(normal.entropy().shape, [])
normal = paddle.distribution.Normal(
paddle.full([], 0.0), paddle.full([], 3.0)
)
self.assertEqual(normal.sample([]).shape, [])
self.assertEqual(normal.rsample([]).shape, [])
self.assertEqual(normal.mean.shape, [])
self.assertEqual(normal.variance.shape, [])
self.assertEqual(normal.probs(self.x).shape, [])
self.assertEqual(normal.log_prob(self.x).shape, [])
self.assertEqual(normal.entropy().shape, [])
def test_Uniform(self):
uniform = paddle.distribution.Uniform(0.0, 1.0)
self.assertEqual(uniform.sample([]).shape, [])
self.assertEqual(uniform.probs(self.x).shape, [])
self.assertEqual(uniform.log_prob(self.x).shape, [])
self.assertEqual(uniform.entropy().shape, [])
uniform = paddle.distribution.Uniform(
paddle.full([], 0.0), paddle.full([], 1.0)
)
self.assertEqual(uniform.sample([]).shape, [])
self.assertEqual(uniform.probs(self.x).shape, [])
self.assertEqual(uniform.log_prob(self.x).shape, [])
self.assertEqual(uniform.entropy().shape, [])
def test_Beta(self):
beta = paddle.distribution.Beta(alpha=0.5, beta=0.5)
self.assertEqual(beta.sample([]).shape, [])
self.assertEqual(beta.mean.shape, [])
self.assertEqual(beta.variance.shape, [])
self.assertEqual(beta.prob(self.x).shape, [])
self.assertEqual(beta.log_prob(self.x).shape, [])
self.assertEqual(beta.entropy().shape, [])
def test_kl_divergence(self):
p = paddle.distribution.Beta(alpha=0.5, beta=0.5)
q = paddle.distribution.Beta(alpha=0.2, beta=1.0)
kl = paddle.distribution.kl_divergence(p, q)
self.assertEqual(kl.shape, [])
def test_TransformedDistribution(self):
d = paddle.distribution.TransformedDistribution(
paddle.distribution.Normal(0.0, 1.0),
[
paddle.distribution.AffineTransform(
paddle.full([], 1.0), paddle.full([], 2.0)
)
],
)
self.assertEqual(d.sample([]).shape, [])
self.assertEqual(d.rsample([]).shape, [])
self.assertEqual(d.prob(self.x).shape, [])
self.assertEqual(d.log_prob(self.x).shape, [])
def test_Laplace(self):
d = paddle.distribution.Laplace(0.0, 1.0)
self.assertEqual(d.sample([]).shape, [])
self.assertEqual(d.rsample([]).shape, [])
self.assertEqual(d.mean.shape, [])
self.assertEqual(d.stddev.shape, [])
self.assertEqual(d.variance.shape, [])
self.assertEqual(d.prob(self.x).shape, [])
self.assertEqual(d.log_prob(self.x).shape, [])
self.assertEqual(d.cdf(self.x).shape, [])
self.assertEqual(d.icdf(self.x).shape, [])
self.assertEqual(d.entropy().shape, [])
def test_LogNormal(self):
d = paddle.distribution.LogNormal(0.0, 1.0)
self.assertEqual(d.sample([]).shape, [])
self.assertEqual(d.mean.shape, [])
self.assertEqual(d.variance.shape, [])
self.assertEqual(d.entropy().shape, [])
self.assertEqual(d.probs(self.x).shape, [])
def test_Gumbel(self):
d = paddle.distribution.Gumbel(0.0, 1.0)
self.assertEqual(d.sample([]).shape, [])
self.assertEqual(d.rsample([]).shape, [])
self.assertEqual(d.mean.shape, [])
self.assertEqual(d.variance.shape, [])
self.assertEqual(d.stddev.shape, [])
self.assertEqual(d.prob(self.x).shape, [])
self.assertEqual(d.log_prob(self.x).shape, [])
self.assertEqual(d.cdf(self.x).shape, [])
self.assertEqual(d.entropy().shape, [])
def test_Multinomial(self):
d = paddle.distribution.Multinomial(
10, paddle.to_tensor([0.2, 0.3, 0.5])
)
self.assertEqual(d.prob(self.x).shape, [])
self.assertEqual(d.log_prob(self.x).shape, [])
self.assertEqual(d.entropy().shape, [])
class TestLossAPI(unittest.TestCase):
def test_sigmoid_focal_loss(self):
logit = paddle.to_tensor(
[[0.97, 0.91, 0.03], [0.55, 0.43, 0.71]],
dtype='float32',
stop_gradient=False,
)
logit.retain_grads()
label = paddle.to_tensor(
[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]], dtype='float32'
)
fg_num_0 = paddle.full([], 2.0)
fg_num_1 = paddle.full([1], 2.0)
out0 = F.sigmoid_focal_loss(
logit, label, normalizer=fg_num_0, reduction='sum'
)
out1 = F.sigmoid_focal_loss(
logit, label, normalizer=fg_num_1, reduction='sum'
)
out0.retain_grads()
np.testing.assert_array_equal(
out0.numpy(),
out1.numpy(),
)
out0.backward()
self.assertEqual(out0.shape, [])
self.assertEqual(out1.shape, [])
self.assertEqual(out0.grad.shape, [])
self.assertEqual(logit.grad.shape, [2, 3])
def test_cross_entropy(self):
input = paddle.rand([3, 5])
input.stop_gradient = False
label = paddle.randint(0, 5, shape=[3])
loss = paddle.nn.functional.cross_entropy(input, label, reduction='sum')
loss.backward()
self.assertEqual(loss.shape, [])
self.assertEqual(input.grad.shape, [3, 5])
def test_l1_loss(self):
input = paddle.rand([3, 5])
input.stop_gradient = False
label = paddle.rand([3, 5])
loss = paddle.nn.functional.l1_loss(input, label, reduction='mean')
loss.backward()
self.assertEqual(loss.shape, [])
self.assertEqual(input.grad.shape, [3, 5])
def test_nll_loss(self):
input = paddle.rand([5, 3])
input.stop_gradient = False
log_softmax = paddle.nn.LogSoftmax(axis=1)
log_out = log_softmax(input)
label = paddle.randint(0, 3, [5], "int64")
loss = paddle.nn.functional.nll_loss(log_out, label)
loss.backward()
self.assertEqual(loss.shape, [])
self.assertEqual(input.grad.shape, [5, 3])
input = paddle.rand([5, 3, 2, 4])
input.stop_gradient = False
log_softmax = paddle.nn.LogSoftmax(axis=1)
log_out = log_softmax(input)
label = paddle.randint(0, 3, [5, 2, 4], "int64")
loss = paddle.nn.functional.nll_loss(log_out, label)
loss.backward()
self.assertEqual(loss.shape, [])
self.assertEqual(input.grad.shape, [5, 3, 2, 4])
class TestLossAPIStatic(unittest.TestCase):
def setUp(self):
paddle.enable_static()
self.exe = paddle.static.Executor()
@prog_scope()
def test_sigmoid_focal_loss(self):
logit = paddle.rand([2, 3])
logit.stop_gradient = False
label = paddle.randint(0, 1, [2, 3]).astype('float32')
label.stop_gradient = False
fg_num_0 = paddle.full([], 2.0)
fg_num_1 = paddle.full([1], 2.0)
out0 = F.sigmoid_focal_loss(
logit, label, normalizer=fg_num_0, reduction='mean'
)
out1 = F.sigmoid_focal_loss(
logit, label, normalizer=fg_num_1, reduction='mean'
)
[(_, out0_grad), (_, logit_grad)] = paddle.static.append_backward(
out0.sum(), parameter_list=[out0, logit]
)
prog = paddle.static.default_main_program()
res = self.exe.run(prog, fetch_list=[out0, out1, out0_grad, logit_grad])
np.testing.assert_allclose(res[0], res[1])
self.assertEqual(res[0].shape, ())
self.assertEqual(res[1].shape, ())
self.assertEqual(res[2].shape, ())
self.assertEqual(res[3].shape, (2, 3))
@prog_scope()
def test_cross_entropy(self):
input = paddle.rand([3, 5])
input.stop_gradient = False
label = paddle.randint(0, 5, shape=[3])
label.stop_gradient = False
loss = paddle.nn.functional.cross_entropy(
input, label, reduction='mean'
)
[(_, input_grad)] = paddle.static.append_backward(
loss, parameter_list=[input]
)
prog = paddle.static.default_main_program()
res = self.exe.run(prog, fetch_list=[loss, input_grad])
self.assertEqual(res[0].shape, ())
self.assertEqual(res[1].shape, (3, 5))
@prog_scope()
def test_l1_loss(self):
input = paddle.rand([3, 5])
input.stop_gradient = False
label = paddle.rand([3, 5])
loss = paddle.nn.functional.l1_loss(input, label, reduction='sum')
[(_, input_grad)] = paddle.static.append_backward(
loss, parameter_list=[input]
)
prog = paddle.static.default_main_program()
res = self.exe.run(prog, fetch_list=[loss, input_grad])
self.assertEqual(res[0].shape, ())
self.assertEqual(res[1].shape, (3, 5))
@prog_scope()
def test_nll_loss(self):
input = paddle.rand([5, 3])
input.stop_gradient = False
log_softmax = paddle.nn.LogSoftmax(axis=1)
log_out = log_softmax(input)
label = paddle.randint(0, 3, shape=[5])
label.stop_gradient = False
loss = paddle.nn.functional.nll_loss(log_out, label)
[(_, input_grad)] = paddle.static.append_backward(
loss, parameter_list=[input]
)
prog = paddle.static.default_main_program()
res = self.exe.run(prog, fetch_list=[loss, input_grad])
self.assertEqual(res[0].shape, ())
self.assertEqual(res[1].shape, (5, 3))
input = paddle.rand([5, 3, 2, 4])
input.stop_gradient = False
log_softmax = paddle.nn.LogSoftmax(axis=1)
log_out = log_softmax(input)
label = paddle.randint(0, 3, shape=[5, 2, 4])
label.stop_gradient = False
loss = paddle.nn.functional.nll_loss(log_out, label)
[(_, input_grad)] = paddle.static.append_backward(
loss, parameter_list=[input]
)
prog = paddle.static.default_main_program()
res = self.exe.run(prog, fetch_list=[loss, input_grad])
self.assertEqual(res[0].shape, ())
self.assertEqual(res[1].shape, (5, 3, 2, 4))
if __name__ == "__main__":
unittest.main()