677 lines
23 KiB
Python
677 lines
23 KiB
Python
# Copyright (c) 2018 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 os
|
|
import sys
|
|
import unittest
|
|
|
|
sys.path.append("../../legacy_test")
|
|
import numpy as np
|
|
from op_test import (
|
|
OpTest,
|
|
convert_float_to_uint16,
|
|
get_device,
|
|
get_device_place,
|
|
is_custom_device,
|
|
)
|
|
from test_attribute_var import UnittestBase
|
|
|
|
import paddle
|
|
from paddle import base
|
|
from paddle.base import core
|
|
from paddle.framework import in_pir_mode
|
|
|
|
|
|
def sample_output_one_dimension(out, dim):
|
|
# count numbers of different categories
|
|
sample_prob = np.zeros(dim).astype("float32")
|
|
sample_index_prob = np.unique(out, return_counts=True)
|
|
sample_prob[sample_index_prob[0]] = sample_index_prob[1]
|
|
sample_prob /= sample_prob.sum()
|
|
return sample_prob
|
|
|
|
|
|
def sample_output_two_dimension(out, shape):
|
|
num_dist = shape[0]
|
|
out_list = np.split(out, num_dist, axis=0)
|
|
sample_prob = np.zeros(shape).astype("float32")
|
|
for i in range(num_dist):
|
|
sample_index_prob = np.unique(out_list[i], return_counts=True)
|
|
sample_prob[i][sample_index_prob[0]] = sample_index_prob[1]
|
|
sample_prob /= sample_prob.sum(axis=-1, keepdims=True)
|
|
return sample_prob
|
|
|
|
|
|
class TestMultinomialOp(OpTest):
|
|
def setUp(self):
|
|
paddle.enable_static()
|
|
self.op_type = "multinomial"
|
|
self.python_api = paddle.multinomial
|
|
self.init_data()
|
|
self.inputs = {"X": self.input_np}
|
|
|
|
def init_data(self):
|
|
# input probability is a vector, and replacement is True
|
|
self.input_np = np.random.rand(4)
|
|
self.outputs = {"Out": np.zeros(100000).astype("int64")}
|
|
self.attrs = {"num_samples": 100000, "replacement": True}
|
|
|
|
def test_check_output(self):
|
|
self.check_output_customized(self.verify_output, check_pir=True)
|
|
|
|
def sample_output(self, out):
|
|
return sample_output_one_dimension(out, 4)
|
|
|
|
def verify_output(self, outs):
|
|
# normalize the input to get the probability
|
|
prob = self.input_np / self.input_np.sum(axis=-1, keepdims=True)
|
|
sample_prob = self.sample_output(np.array(outs[0]))
|
|
np.testing.assert_allclose(
|
|
sample_prob,
|
|
prob,
|
|
rtol=0,
|
|
atol=0.01,
|
|
err_msg='sample_prob: ' + str(sample_prob) + '\nprob: ' + str(prob),
|
|
)
|
|
|
|
|
|
class TestMultinomialOp2(TestMultinomialOp):
|
|
def init_data(self):
|
|
# input probability is a matrix
|
|
self.input_np = np.random.rand(3, 4)
|
|
self.outputs = {"Out": np.zeros((3, 100000)).astype("int64")}
|
|
self.attrs = {"num_samples": 100000, "replacement": True}
|
|
|
|
def sample_output(self, out):
|
|
return sample_output_two_dimension(out, [3, 4])
|
|
|
|
|
|
class TestMultinomialOp3(TestMultinomialOp):
|
|
def init_data(self):
|
|
# replacement is False. number of samples must be less than number of categories.
|
|
self.input_np = np.random.rand(1000)
|
|
self.outputs = {"Out": np.zeros(100).astype("int64")}
|
|
self.attrs = {"num_samples": 100, "replacement": False}
|
|
|
|
def verify_output(self, outs):
|
|
out = np.array(outs[0])
|
|
unique_out = np.unique(out)
|
|
self.assertEqual(
|
|
len(unique_out),
|
|
100,
|
|
"replacement is False. categories can't be sampled repeatedly",
|
|
)
|
|
|
|
|
|
# FP16 OP
|
|
class TestMultinomialFP16Op(OpTest):
|
|
def setUp(self):
|
|
paddle.enable_static()
|
|
self.op_type = "multinomial"
|
|
self.python_api = paddle.multinomial
|
|
self.dtype = np.float16
|
|
self.init_data()
|
|
self.inputs = {"X": self.input_np}
|
|
|
|
def init_data(self):
|
|
# input probability is a vector, and replacement is True
|
|
self.input_np = np.random.rand(4).astype(self.dtype)
|
|
self.outputs = {"Out": np.zeros(100000).astype("int64")}
|
|
self.attrs = {"num_samples": 100000, "replacement": True}
|
|
|
|
def test_check_output(self):
|
|
self.check_output_customized(self.verify_output, check_pir=True)
|
|
|
|
def sample_output(self, out):
|
|
return sample_output_one_dimension(out, 4)
|
|
|
|
def verify_output(self, outs):
|
|
# normalize the input to get the probability
|
|
prob = self.input_np / self.input_np.sum(axis=-1, keepdims=True)
|
|
sample_prob = self.sample_output(np.array(outs[0]))
|
|
np.testing.assert_allclose(
|
|
sample_prob,
|
|
prob,
|
|
rtol=0,
|
|
atol=0.01,
|
|
err_msg='sample_prob: ' + str(sample_prob) + '\nprob: ' + str(prob),
|
|
)
|
|
|
|
|
|
class TestMultinomialFP16Op2(TestMultinomialFP16Op):
|
|
def init_data(self):
|
|
# input probability is a matrix
|
|
self.input_np = np.random.rand(3, 4).astype(self.dtype)
|
|
self.outputs = {"Out": np.zeros((3, 100000)).astype("int64")}
|
|
self.attrs = {"num_samples": 100000, "replacement": True}
|
|
|
|
def sample_output(self, out):
|
|
return sample_output_two_dimension(out, [3, 4])
|
|
|
|
|
|
class TestMultinomialFP16Op3(TestMultinomialFP16Op):
|
|
def init_data(self):
|
|
# replacement is False. number of samples must be less than number of categories.
|
|
self.input_np = np.random.rand(1000).astype(self.dtype)
|
|
self.outputs = {"Out": np.zeros(100).astype("int64")}
|
|
self.attrs = {"num_samples": 100, "replacement": False}
|
|
|
|
def verify_output(self, outs):
|
|
out = np.array(outs[0])
|
|
unique_out = np.unique(out)
|
|
self.assertEqual(
|
|
len(unique_out),
|
|
100,
|
|
"replacement is False. categories can't be sampled repeatedly",
|
|
)
|
|
|
|
|
|
# BF16 OP
|
|
@unittest.skipIf(
|
|
not (core.is_compiled_with_cuda() or is_custom_device())
|
|
or not core.is_bfloat16_supported(get_device_place()),
|
|
"core is not compiled with CUDA and do not support bfloat16",
|
|
)
|
|
class TestMultinomialBF16OP(OpTest):
|
|
def setUp(self):
|
|
paddle.enable_static()
|
|
self.op_type = "multinomial"
|
|
self.python_api = paddle.multinomial
|
|
self.dtype = np.uint16
|
|
self.init_data()
|
|
self.inputs = {"X": convert_float_to_uint16(self.input_np)}
|
|
|
|
def init_data(self):
|
|
# input probability is a vector, and replacement is True
|
|
self.input_np = np.random.rand(4).astype(np.float32)
|
|
self.outputs = {"Out": np.zeros(100000).astype("int64")}
|
|
self.attrs = {"num_samples": 100000, "replacement": True}
|
|
|
|
def test_check_output(self):
|
|
place = get_device_place()
|
|
self.check_output_with_place_customized(
|
|
self.verify_output, place, check_pir=True
|
|
)
|
|
|
|
def sample_output(self, out):
|
|
return sample_output_one_dimension(out, 4)
|
|
|
|
def verify_output(self, outs):
|
|
# normalize the input to get the probability
|
|
prob = self.input_np / self.input_np.sum(axis=-1, keepdims=True)
|
|
sample_prob = self.sample_output(np.array(outs[0]))
|
|
np.testing.assert_allclose(
|
|
sample_prob,
|
|
prob,
|
|
rtol=0,
|
|
atol=0.01,
|
|
err_msg='sample_prob: ' + str(sample_prob) + '\nprob: ' + str(prob),
|
|
)
|
|
|
|
|
|
@unittest.skipIf(
|
|
not (core.is_compiled_with_cuda() or is_custom_device())
|
|
or not core.is_bfloat16_supported(get_device_place()),
|
|
"core is not compiled with CUDA and do not support bfloat16",
|
|
)
|
|
class TestMultinomialBF16OP2(TestMultinomialBF16OP):
|
|
def init_data(self):
|
|
# input probability is a matrix
|
|
self.input_np = np.random.rand(3, 4).astype(np.float32)
|
|
self.outputs = {"Out": np.zeros((3, 100000)).astype("int64")}
|
|
self.attrs = {"num_samples": 100000, "replacement": True}
|
|
|
|
def sample_output(self, out):
|
|
return sample_output_two_dimension(out, [3, 4])
|
|
|
|
|
|
@unittest.skipIf(
|
|
not (core.is_compiled_with_cuda() or is_custom_device())
|
|
or not core.is_bfloat16_supported(get_device_place()),
|
|
"core is not compiled with CUDA and do not support bfloat16",
|
|
)
|
|
class TestMultinomialBF16OP3(TestMultinomialBF16OP):
|
|
def init_data(self):
|
|
# replacement is False. number of samples must be less than number of categories.
|
|
self.input_np = np.random.rand(1000).astype(np.float32)
|
|
self.outputs = {"Out": np.zeros(100).astype("int64")}
|
|
self.attrs = {"num_samples": 100, "replacement": False}
|
|
|
|
def verify_output(self, outs):
|
|
out = np.array(outs[0])
|
|
unique_out = np.unique(out)
|
|
self.assertEqual(
|
|
len(unique_out),
|
|
100,
|
|
"replacement is False. categories can't be sampled repeatedly",
|
|
)
|
|
|
|
|
|
class TestMultinomialApi(unittest.TestCase):
|
|
def test_dygraph(self):
|
|
# input probability is a vector, and replacement is True
|
|
paddle.disable_static()
|
|
x_numpy = np.random.rand(4)
|
|
x = paddle.to_tensor(x_numpy)
|
|
out = paddle.multinomial(x, num_samples=100000, replacement=True)
|
|
paddle.enable_static()
|
|
|
|
sample_prob = sample_output_one_dimension(out.numpy(), 4)
|
|
prob = x_numpy / x_numpy.sum(axis=-1, keepdims=True)
|
|
np.testing.assert_allclose(
|
|
sample_prob,
|
|
prob,
|
|
rtol=0,
|
|
atol=0.01,
|
|
err_msg='sample_prob: ' + str(sample_prob) + '\nprob: ' + str(prob),
|
|
)
|
|
|
|
def test_dygraph2(self):
|
|
# input probability is a matrix, and replacement is True
|
|
paddle.disable_static()
|
|
x_numpy = np.random.rand(3, 4)
|
|
x = paddle.to_tensor(x_numpy)
|
|
out = paddle.multinomial(x, num_samples=100000, replacement=True)
|
|
|
|
sample_prob = sample_output_two_dimension(out.numpy(), [3, 4])
|
|
prob = x_numpy / x_numpy.sum(axis=-1, keepdims=True)
|
|
np.testing.assert_allclose(
|
|
sample_prob,
|
|
prob,
|
|
rtol=0,
|
|
atol=0.01,
|
|
err_msg='sample_prob: ' + str(sample_prob) + '\nprob: ' + str(prob),
|
|
)
|
|
paddle.enable_static()
|
|
|
|
def test_dygraph3(self):
|
|
# replacement is False. number of samples must be less than number of categories.
|
|
paddle.disable_static()
|
|
x_numpy = np.random.rand(1000)
|
|
x = paddle.to_tensor(x_numpy)
|
|
out = paddle.multinomial(x, num_samples=100, replacement=False)
|
|
|
|
unique_out = np.unique(out.numpy())
|
|
self.assertEqual(
|
|
len(unique_out),
|
|
100,
|
|
"replacement is False. categories can't be sampled repeatedly",
|
|
)
|
|
paddle.enable_static()
|
|
|
|
def test_dygraph4(self):
|
|
paddle.disable_static()
|
|
logits = -1 * paddle.ones([2800])
|
|
# Categorical.sample API will call multinomial op with replacement=True
|
|
cat = paddle.distribution.Categorical(logits.exp())
|
|
cat.sample([1])
|
|
paddle.enable_static()
|
|
|
|
def test_static(self):
|
|
paddle.enable_static()
|
|
startup_program = paddle.static.Program()
|
|
train_program = paddle.static.Program()
|
|
with paddle.static.program_guard(train_program, startup_program):
|
|
x = paddle.static.data('x', shape=[4], dtype='float32')
|
|
out = paddle.multinomial(x, num_samples=100000, replacement=True)
|
|
|
|
place = base.CPUPlace()
|
|
if base.core.is_compiled_with_cuda() or is_custom_device():
|
|
place = get_device_place()
|
|
exe = base.Executor(place)
|
|
|
|
exe.run(startup_program)
|
|
x_np = np.random.rand(4).astype('float32')
|
|
out = exe.run(train_program, feed={'x': x_np}, fetch_list=[out])
|
|
|
|
sample_prob = sample_output_one_dimension(out, 4)
|
|
prob = x_np / x_np.sum(axis=-1, keepdims=True)
|
|
np.testing.assert_allclose(
|
|
sample_prob,
|
|
prob,
|
|
rtol=0,
|
|
atol=0.01,
|
|
err_msg='sample_prob: ' + str(sample_prob) + '\nprob: ' + str(prob),
|
|
)
|
|
|
|
|
|
class TestMultinomialOutParameter(unittest.TestCase):
|
|
def setUp(self):
|
|
paddle.disable_static()
|
|
paddle.seed(100)
|
|
|
|
def tearDown(self):
|
|
paddle.enable_static()
|
|
|
|
def test_out_parameter_basic(self):
|
|
x_numpy = np.random.rand(4)
|
|
x = paddle.to_tensor(x_numpy)
|
|
|
|
out = paddle.empty([1000], dtype='int64')
|
|
paddle.multinomial(x, num_samples=1000, replacement=True, out=out)
|
|
|
|
self.assertEqual(out.shape, [1000])
|
|
self.assertEqual(out.dtype, paddle.int64)
|
|
|
|
self.assertTrue(paddle.all(out >= 0))
|
|
self.assertTrue(paddle.all(out < 4))
|
|
|
|
def test_out_parameter_2d(self):
|
|
x_numpy = np.random.rand(3, 4)
|
|
x = paddle.to_tensor(x_numpy)
|
|
|
|
out = paddle.empty([3, 100], dtype='int64')
|
|
|
|
paddle.multinomial(x, num_samples=100, replacement=True, out=out)
|
|
|
|
self.assertEqual(out.shape, [3, 100])
|
|
self.assertEqual(out.dtype, paddle.int64)
|
|
|
|
self.assertTrue(paddle.all(out >= 0))
|
|
self.assertTrue(paddle.all(out < 4))
|
|
|
|
def test_out_parameter_with_alias(self):
|
|
x_numpy = np.random.rand(4)
|
|
x = paddle.to_tensor(x_numpy)
|
|
|
|
out = paddle.empty([1000], dtype='int64')
|
|
paddle.multinomial(input=x, num_samples=1000, replacement=True, out=out)
|
|
|
|
self.assertEqual(out.shape, [1000])
|
|
self.assertEqual(out.dtype, paddle.int64)
|
|
|
|
def test_out_parameter_different_scenarios(self):
|
|
x_numpy = np.random.rand(100)
|
|
x = paddle.to_tensor(x_numpy)
|
|
out = paddle.empty([50], dtype='int64')
|
|
|
|
paddle.multinomial(x, num_samples=50, replacement=False, out=out)
|
|
|
|
unique_values = paddle.unique(out)
|
|
self.assertEqual(len(unique_values), 50)
|
|
|
|
out_small = paddle.empty([5], dtype='int64')
|
|
paddle.multinomial(x, num_samples=5, replacement=True, out=out_small)
|
|
self.assertEqual(out_small.shape, [5])
|
|
|
|
def test_out_parameter_none_default(self):
|
|
x_numpy = np.random.rand(4)
|
|
x = paddle.to_tensor(x_numpy)
|
|
|
|
result1 = paddle.multinomial(
|
|
x, num_samples=100, replacement=True, out=None
|
|
)
|
|
result2 = paddle.multinomial(x, num_samples=100, replacement=True)
|
|
|
|
self.assertEqual(result1.shape, result2.shape)
|
|
self.assertEqual(result1.dtype, result2.dtype)
|
|
|
|
|
|
class TestMultinomialOutAndAliasDecorator(unittest.TestCase):
|
|
def setUp(self):
|
|
paddle.disable_static()
|
|
|
|
def tearDown(self):
|
|
paddle.enable_static()
|
|
|
|
def do_test(self, test_type):
|
|
x_numpy = np.random.rand(4)
|
|
x = paddle.to_tensor(x_numpy, stop_gradient=False)
|
|
|
|
if test_type == "raw":
|
|
result = paddle.multinomial(x, num_samples=1000, replacement=True)
|
|
loss = paddle.cast(result, 'float32').mean()
|
|
loss.backward()
|
|
return result, x.grad
|
|
|
|
elif test_type == "alias":
|
|
result = paddle.multinomial(
|
|
input=x, num_samples=1000, replacement=True
|
|
)
|
|
loss = paddle.cast(result, 'float32').mean()
|
|
loss.backward()
|
|
return result, x.grad
|
|
|
|
elif test_type == "out":
|
|
out = paddle.empty([1000], dtype='int64')
|
|
out.stop_gradient = False
|
|
paddle.multinomial(x, num_samples=1000, replacement=True, out=out)
|
|
loss = paddle.cast(out, 'float32').mean()
|
|
loss.backward()
|
|
return out, x.grad
|
|
|
|
elif test_type == "out_alias":
|
|
out = paddle.empty([1000], dtype='int64')
|
|
out.stop_gradient = False
|
|
paddle.multinomial(
|
|
input=x, num_samples=1000, replacement=True, out=out
|
|
)
|
|
loss = paddle.cast(out, 'float32').mean()
|
|
loss.backward()
|
|
return out, x.grad
|
|
|
|
else:
|
|
raise ValueError(f"Unknown test type: {test_type}")
|
|
|
|
def test_multinomial_out_and_alias_combination(self):
|
|
test_types = ["raw", "alias", "out", "out_alias"]
|
|
|
|
results = {}
|
|
grads = {}
|
|
|
|
for test_type in test_types:
|
|
paddle.seed(42)
|
|
result, grad = self.do_test(test_type)
|
|
results[test_type] = result
|
|
grads[test_type] = grad
|
|
|
|
base_shape = results["raw"].shape
|
|
base_dtype = results["raw"].dtype
|
|
|
|
for test_type in test_types:
|
|
self.assertEqual(results[test_type].shape, base_shape)
|
|
self.assertEqual(results[test_type].dtype, base_dtype)
|
|
|
|
|
|
class TestMultinomialAlias(unittest.TestCase):
|
|
def test_alias(self):
|
|
paddle.disable_static()
|
|
x = paddle.rand([4])
|
|
paddle.multinomial(x, num_samples=10, replacement=True)
|
|
paddle.tensor.multinomial(x, num_samples=10, replacement=True)
|
|
paddle.tensor.random.multinomial(x, num_samples=10, replacement=True)
|
|
|
|
def test_alias_torch(self):
|
|
if not paddle.is_compiled_with_cuda():
|
|
return
|
|
|
|
if "V100" not in paddle.device.cuda.get_device_name():
|
|
return
|
|
|
|
paddle.disable_static()
|
|
paddle.set_device(get_device())
|
|
paddle.seed(100)
|
|
|
|
x = paddle.randint(0, 100, [1024, 10000]).astype('float32')
|
|
y = paddle.multinomial(
|
|
input=x, num_samples=1, replacement=False
|
|
).numpy()
|
|
self.assertEqual(np.sum(y), 5187793)
|
|
self.assertEqual(np.mean(y), 5066.2041015625)
|
|
expect = [9982, 1655, 4741, 1323, 9319, 3298, 6473, 7477, 2507, 2628]
|
|
np.testing.assert_array_equal(y[100:110, :].flatten(), expect)
|
|
|
|
y = paddle.multinomial(
|
|
input=x, num_samples=5000, replacement=False
|
|
).numpy()
|
|
self.assertEqual(np.sum(y), 25603962316)
|
|
self.assertEqual(np.mean(y), 5000.77388984375)
|
|
expect = [7300, 6055, 8714, 5401, 7360, 161, 5035, 7002, 6788, 2916]
|
|
np.testing.assert_array_equal(y[100, 1000:1010], expect)
|
|
|
|
y = paddle.multinomial(
|
|
input=x, num_samples=5000, replacement=False
|
|
).numpy()
|
|
self.assertEqual(np.sum(y), 25592855710)
|
|
self.assertEqual(np.mean(y), 4998.604630859375)
|
|
expect = [5700, 6567, 4399, 5688, 7472, 545, 6894, 526, 2124, 385]
|
|
np.testing.assert_array_equal(y[300, 3000:3010], expect)
|
|
|
|
y = paddle.multinomial(
|
|
input=x, num_samples=20000, replacement=True
|
|
).numpy()
|
|
self.assertEqual(np.sum(y), 102371362581)
|
|
self.assertEqual(np.mean(y), 4998.60168852539)
|
|
self.assertEqual(np.std(y), 2886.3163085007764)
|
|
expect = [7630, 8235, 8445, 3275, 5580, 4591, 1331, 342, 1662, 7156]
|
|
np.testing.assert_array_equal(y[100, 0:10], expect)
|
|
|
|
paddle.enable_static()
|
|
|
|
|
|
class TestMultinomialError(unittest.TestCase):
|
|
def setUp(self):
|
|
paddle.disable_static()
|
|
|
|
def test_num_sample(self):
|
|
def test_num_sample_less_than_0():
|
|
x = paddle.rand([4])
|
|
paddle.multinomial(x, num_samples=-2)
|
|
|
|
self.assertRaises(ValueError, test_num_sample_less_than_0)
|
|
|
|
def test_replacement_False(self):
|
|
def test_samples_larger_than_categories():
|
|
x = paddle.rand([4])
|
|
paddle.multinomial(x, num_samples=5, replacement=False)
|
|
|
|
self.assertRaises(ValueError, test_samples_larger_than_categories)
|
|
|
|
def test_input_probs_dim(self):
|
|
def test_dim_larger_than_2():
|
|
x = paddle.rand([2, 3, 3])
|
|
paddle.multinomial(x)
|
|
|
|
self.assertRaises(ValueError, test_dim_larger_than_2)
|
|
|
|
def test_dim_less_than_1():
|
|
x_np = np.random.random([])
|
|
x = paddle.to_tensor(x_np)
|
|
paddle.multinomial(x)
|
|
|
|
self.assertRaises(ValueError, test_dim_less_than_1)
|
|
|
|
with self.assertRaises(ValueError):
|
|
y = paddle.multinomial(paddle.to_tensor([1.0, 2.0, -3.0]))
|
|
|
|
|
|
class TestRandomValue(unittest.TestCase):
|
|
def test_fixed_random_number(self):
|
|
# Test GPU Fixed random number, which is generated by 'curandStatePhilox4_32_10_t'
|
|
if not paddle.is_compiled_with_cuda():
|
|
return
|
|
|
|
# Different GPU generate different random value. Only test V100 here.
|
|
if "V100" not in paddle.device.cuda.get_device_name():
|
|
return
|
|
|
|
print("Test Fixed Random number on V100 GPU------>")
|
|
paddle.disable_static()
|
|
paddle.set_device(get_device())
|
|
paddle.seed(100)
|
|
|
|
x = paddle.randint(0, 100, [1024, 10000]).astype('float32')
|
|
y = paddle.multinomial(x, 1, replacement=False).numpy()
|
|
self.assertEqual(np.sum(y), 5187793)
|
|
self.assertEqual(np.mean(y), 5066.2041015625)
|
|
expect = [9982, 1655, 4741, 1323, 9319, 3298, 6473, 7477, 2507, 2628]
|
|
np.testing.assert_array_equal(y[100:110, :].flatten(), expect)
|
|
|
|
y = paddle.multinomial(x, 5000, replacement=False).numpy()
|
|
self.assertEqual(np.sum(y), 25603962316)
|
|
self.assertEqual(np.mean(y), 5000.77388984375)
|
|
expect = [7300, 6055, 8714, 5401, 7360, 161, 5035, 7002, 6788, 2916]
|
|
np.testing.assert_array_equal(y[100, 1000:1010], expect)
|
|
|
|
y = paddle.multinomial(x, 5000, replacement=False).numpy()
|
|
self.assertEqual(np.sum(y), 25592855710)
|
|
self.assertEqual(np.mean(y), 4998.604630859375)
|
|
expect = [5700, 6567, 4399, 5688, 7472, 545, 6894, 526, 2124, 385]
|
|
np.testing.assert_array_equal(y[300, 3000:3010], expect)
|
|
|
|
y = paddle.multinomial(x, 20000, replacement=True).numpy()
|
|
self.assertEqual(np.sum(y), 102371362581)
|
|
self.assertEqual(np.mean(y), 4998.60168852539)
|
|
self.assertEqual(np.std(y), 2886.3163085007764)
|
|
expect = [7630, 8235, 8445, 3275, 5580, 4591, 1331, 342, 1662, 7156]
|
|
np.testing.assert_array_equal(y[100, 0:10], expect)
|
|
|
|
y = paddle.multinomial(x, 20000, replacement=True).numpy()
|
|
self.assertEqual(np.sum(y), 102400672117)
|
|
self.assertEqual(np.mean(y), 5000.032818212891)
|
|
self.assertEqual(np.std(y), 2886.913426124019)
|
|
expect = [4159, 7849, 9305, 5759, 4422, 122, 345, 2897, 5200, 5911]
|
|
np.testing.assert_array_equal(y[100, 0:10], expect)
|
|
|
|
paddle.enable_static()
|
|
|
|
|
|
class TestMultinomialTensorNumSamples(UnittestBase):
|
|
def init_info(self):
|
|
self.shapes = [[3, 4]]
|
|
self.save_path = os.path.join(self.temp_dir.name, self.path_prefix())
|
|
|
|
def path_prefix(self):
|
|
return 'multinomial_tensor_num'
|
|
|
|
def var_prefix(self):
|
|
return "Var["
|
|
|
|
def call_func(self, x):
|
|
num_samples = paddle.assign(3)
|
|
out = paddle.multinomial(x, num_samples)
|
|
return out
|
|
|
|
def test_static(self):
|
|
paddle.enable_static()
|
|
main_prog = paddle.static.Program()
|
|
startup_prog = paddle.static.Program()
|
|
with paddle.static.program_guard(main_prog, startup_prog):
|
|
fc = paddle.nn.Linear(4, 10)
|
|
x = paddle.randn([3, 4])
|
|
x.stop_gradient = False
|
|
feat = fc(x)
|
|
out = self.call_func(paddle.abs(feat))
|
|
sgd = paddle.optimizer.SGD()
|
|
sgd.minimize(paddle.mean(paddle.cast(out, 'float32')))
|
|
if not in_pir_mode():
|
|
self.assertTrue(self.var_prefix() in str(main_prog))
|
|
|
|
exe = paddle.static.Executor()
|
|
exe.run(startup_prog)
|
|
res = exe.run(fetch_list=[feat, out])
|
|
paddle.static.save_inference_model(
|
|
self.save_path, [x], [feat, out], exe
|
|
)
|
|
np.testing.assert_equal(res[1].shape, (3, 3))
|
|
|
|
# Test for Inference Predictor
|
|
infer_outs = self.infer_prog()
|
|
np.testing.assert_equal(infer_outs[1].shape, (3, 3))
|
|
paddle.disable_static()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|