提交 d9a052a0 编写于 作者: M mindspore-ci-bot 提交者: Gitee

!4313 Add interfaces to check input value range and check the value of seed in random ops

Merge pull request !4313 from peixu_ren/custom_pp_ops
......@@ -57,6 +57,26 @@ def check_equal(param1, param2, msg="{},{}"):
return param1
@constexpr
def check_int_positive(arg_name, arg_value, op_name):
"""Int type judgment."""
if isinstance(arg_value, int):
if arg_value > 0:
return arg_value
raise ValueError("For \'{}\' the `{}` must be positive, but got {}".format(op_name, arg_name, arg_value))
raise TypeError("For \'{}\' the `{}` must be int, cannot be {}".format(op_name, arg_name, type(arg_value)))
@constexpr
def check_non_negative(arg_name, arg_value, op_name):
"""Int type judgment."""
if isinstance(arg_value, int):
if arg_value >= 0:
return arg_value
raise ValueError("For \'{}\' the `{}` must be non_negative, but got {}".format(op_name, arg_name, arg_value))
raise TypeError("For \'{}\' the `{}` must be int, cannot be {}".format(op_name, arg_name, type(arg_value)))
@constexpr
def check_ellipsis_shape_size(data_shape, value_shape, data_size, value_size):
"""Checks the shape and size of the sensor and value."""
......
......@@ -21,7 +21,6 @@ from ..primitive import constexpr
from .multitype_ops import _constexpr_utils as const_utils
from ...common import dtype as mstype
from ..._checkparam import Validator as validator
from ..._checkparam import check_int_positive
from ..._checkparam import Rel
# set graph-level RNG seed
......@@ -41,7 +40,7 @@ def set_seed(seed):
Examples:
>>> C.set_seed(10)
"""
check_int_positive(seed)
const_utils.check_int_positive("seed", seed, "set_seed")
global _GRAPH_SEED
_GRAPH_SEED = seed
......@@ -61,7 +60,6 @@ def get_seed():
"""
return _GRAPH_SEED
def normal(shape, mean, stddev, seed=0):
"""
Generates random numbers according to the Normal (or Gaussian) random number distribution.
......@@ -88,59 +86,14 @@ def normal(shape, mean, stddev, seed=0):
stddev_dtype = F.dtype(stddev)
const_utils.check_tensors_dtype_same(mean_dtype, mstype.float32, "normal")
const_utils.check_tensors_dtype_same(stddev_dtype, mstype.float32, "normal")
const_utils.check_non_negative("seed", seed, "normal")
seed1 = get_seed()
seed2 = seed
stdnormal = P.StandardNormal(seed1, seed2)
rnd = stdnormal(shape)
value = rnd * stddev + mean
random_normal = stdnormal(shape)
value = random_normal * stddev + mean
return value
def multinomial(inputs, num_sample=None, replacement=True, seed=0):
r"""
Returns a tensor sampled from the multinomial probability distribution located in the corresponding
row of tensor input.
Note:
The rows of input do not need to sum to one (in which case we use the values as weights),
but must be non-negative, finite and have a non-zero sum.
Args:
seed (int): Seed data is used as entropy source for Random number engines generating pseudo-random numbers.
Default: 0.
Inputs:
- **input** (Tensor) - the input tensor containing probabilities, must be 1 or 2 dims.
- **num_samples** (int) - number of samples to draw, default None.
- **replacement** (bool, optional) - whether to draw with replacement or not, default True.
Outputs:
Tensor. have the same rows with input, each row has num_samples sampled indices.
Examples:
>>> input = Tensor([0, 9, 4, 0], mstype.float32)
>>> output = C.multinomial(input, 2, True)
"""
shape = P.Shape()
reshape = P.Reshape()
validator.check_value_type('replacement', replacement, (bool,), None)
validator.check_value_type('num_sample', num_sample, (int,), None)
validator.check_integer("num_sample", num_sample, 0, Rel.GT, None)
if inputs.dim() != 1 and inputs.dim() != 2:
raise ValueError("inputs dim must be 1d or 2d")
if not replacement:
if shape(inputs)[-1] < num_sample:
raise ValueError("num_sample must be less than shape(input)[-1] without replacement")
n_dist = 1
if len(shape(inputs)) > 1:
n_dist = shape(inputs)[-2]
random_uniform = P.UniformReal(seed=seed)((n_dist * num_sample,))
if n_dist != 1:
random_uniform = reshape(random_uniform, (n_dist, num_sample))
vals = P.RealDiv()(P.Log()(random_uniform), inputs + 1e-6)
_, indices = P.TopK()(vals, num_sample)
return indices
return P.Multinomial(seed=seed)(inputs, num_sample)
def uniform(shape, a, b, seed=0, dtype=mstype.float32):
"""
Generates random numbers according to the Uniform random number distribution.
......@@ -158,27 +111,35 @@ def uniform(shape, a, b, seed=0, dtype=mstype.float32):
Returns:
Tensor. The shape should be the broadcasted shape of Input "shape" and shapes of a and b.
The dtype is float32.
The dtype is designated as the input `dtype`.
Examples:
>>> shape = (4, 16)
>>> a = Tensor(1.0, mstype.float32)
>>> b = Tensor(1.0, mstype.float32)
>>> For discrete uniform distribution, only one number is allowed for both a and b:
>>> shape = (4, 2)
>>> a = Tensor(1, mstype.int32)
>>> b = Tensor(2, mstype.int32)
>>> output = C.uniform(shape, a, b, seed=5)
>>>
>>> For continuous uniform distribution, a and b can be multi-dimentional:
>>> shape = (4, 2)
>>> a = Tensor([1.0, 2.0], mstype.float32)
>>> b = Tensor([4.0, 5.0], mstype.float32)
>>> output = C.uniform(shape, a, b, seed=5)
"""
a_dtype = F.dtype(a)
b_dtype = F.dtype(b)
const_utils.check_tensors_dtype_same(a_dtype, dtype, "uniform")
const_utils.check_tensors_dtype_same(b_dtype, dtype, "uniform")
const_utils.check_non_negative("seed", seed, "uniform")
seed1 = get_seed()
seed2 = seed
if const_utils.is_same_type(dtype, mstype.int32):
rnd = P.UniformInt(seed1, seed2)
value = rnd(shape, a, b)
random_uniform = P.UniformInt(seed1, seed2)
value = random_uniform(shape, a, b)
else:
uniform_real = P.UniformReal(seed1, seed2)
rnd = uniform_real(shape)
value = rnd * (b - a) + a
random_uniform = uniform_real(shape)
value = random_uniform * (b - a) + a
return value
def gamma(shape, alpha, beta, seed=0):
......@@ -206,6 +167,7 @@ def gamma(shape, alpha, beta, seed=0):
beta_dtype = F.dtype(beta)
const_utils.check_tensors_dtype_same(alpha_dtype, mstype.float32, "gamma")
const_utils.check_tensors_dtype_same(beta_dtype, mstype.float32, "gamma")
const_utils.check_non_negative("seed", seed, "gamma")
seed1 = get_seed()
seed2 = seed
random_gamma = P.Gamma(seed1, seed2)
......@@ -233,8 +195,56 @@ def poisson(shape, mean, seed=0):
"""
mean_dtype = F.dtype(mean)
const_utils.check_tensors_dtype_same(mean_dtype, mstype.float32, "poisson")
const_utils.check_non_negative("seed", seed, "poisson")
seed1 = get_seed()
seed2 = seed
random_poisson = P.Poisson(seed1, seed2)
value = random_poisson(shape, mean)
return value
def multinomial(inputs, num_sample=None, replacement=True, seed=0):
r"""
Returns a tensor sampled from the multinomial probability distribution located in the corresponding
row of tensor input.
Note:
The rows of input do not need to sum to one (in which case we use the values as weights),
but must be non-negative, finite and have a non-zero sum.
Args:
seed (int): Seed data is used as entropy source for Random number engines generating pseudo-random numbers.
Default: 0.
Inputs:
- **input** (Tensor) - the input tensor containing probabilities, must be 1 or 2 dims.
- **num_samples** (int) - number of samples to draw, default None.
- **replacement** (bool, optional) - whether to draw with replacement or not, default True.
Outputs:
Tensor. have the same rows with input, each row has num_samples sampled indices.
Examples:
>>> input = Tensor([0, 9, 4, 0], mstype.float32)
>>> output = C.multinomial(input, 2, True)
"""
shape = P.Shape()
reshape = P.Reshape()
validator.check_value_type('replacement', replacement, (bool,), None)
validator.check_value_type('num_sample', num_sample, (int,), None)
validator.check_integer("num_sample", num_sample, 0, Rel.GT, None)
if inputs.dim() != 1 and inputs.dim() != 2:
raise ValueError("inputs dim must be 1d or 2d")
if not replacement:
if shape(inputs)[-1] < num_sample:
raise ValueError("num_sample must be less than shape(input)[-1] without replacement")
n_dist = 1
if len(shape(inputs)) > 1:
n_dist = shape(inputs)[-2]
a = Tensor(0.0, mstype.float32)
b = Tensor(1.0, mstype.float32)
random_uniform = P.UniformReal(seed=seed)((n_dist * num_sample,), a, b)
if n_dist != 1:
random_uniform = reshape(random_uniform, (n_dist, num_sample))
vals = P.RealDiv()(P.Log()(random_uniform), inputs + 1e-6)
_, indices = P.TopK()(vals, num_sample)
return indices
return P.Multinomial(seed=seed)(inputs, num_sample)
......@@ -46,8 +46,8 @@ class StandardNormal(PrimitiveWithInfer):
def __init__(self, seed=0, seed2=0):
"""Init StandardNormal"""
self.init_prim_io_names(inputs=['shape'], outputs=['output'])
validator.check_value_type('seed', seed, [int], self.name)
validator.check_value_type('seed2', seed2, [int], self.name)
validator.check_integer("seed", seed, 0, Rel.GE, self.name)
validator.check_integer("seed2", seed2, 0, Rel.GE, self.name)
def __infer__(self, shape):
shape_v = shape["value"]
......@@ -151,8 +151,8 @@ class Gamma(PrimitiveWithInfer):
def __init__(self, seed=0, seed2=0):
"""Init Gamma"""
self.init_prim_io_names(inputs=['shape', 'alpha', 'beta'], outputs=['output'])
validator.check_value_type('seed', seed, [int], self.name)
validator.check_value_type('seed2', seed2, [int], self.name)
validator.check_integer("seed", seed, 0, Rel.GE, self.name)
validator.check_integer("seed2", seed2, 0, Rel.GE, self.name)
def __infer__(self, shape, alpha, beta):
shape_v = shape["value"]
......@@ -203,8 +203,8 @@ class Poisson(PrimitiveWithInfer):
def __init__(self, seed=0, seed2=0):
"""Init Poisson"""
self.init_prim_io_names(inputs=['shape', 'mean'], outputs=['output'])
validator.check_value_type('seed', seed, [int], self.name)
validator.check_value_type('seed2', seed2, [int], self.name)
validator.check_integer("seed", seed, 0, Rel.GE, self.name)
validator.check_integer("seed2", seed2, 0, Rel.GE, self.name)
def __infer__(self, shape, mean):
shape_v = shape["value"]
......@@ -259,8 +259,8 @@ class UniformInt(PrimitiveWithInfer):
def __init__(self, seed=0, seed2=0):
"""Init UniformInt"""
self.init_prim_io_names(inputs=['shape', 'a', 'b'], outputs=['output'])
validator.check_value_type('seed', seed, [int], self.name)
validator.check_value_type('seed2', seed2, [int], self.name)
validator.check_integer("seed", seed, 0, Rel.GE, self.name)
validator.check_integer("seed2", seed2, 0, Rel.GE, self.name)
def __infer__(self, shape, a, b):
shape_v = shape["value"]
......@@ -306,8 +306,8 @@ class UniformReal(PrimitiveWithInfer):
def __init__(self, seed=0, seed2=0):
"""Init UniformReal"""
self.init_prim_io_names(inputs=['shape'], outputs=['output'])
validator.check_value_type('seed', seed, [int], self.name)
validator.check_value_type('seed2', seed2, [int], self.name)
validator.check_integer("seed", seed, 0, Rel.GE, self.name)
validator.check_integer("seed2", seed2, 0, Rel.GE, self.name)
def __infer__(self, shape):
shape_v = shape["value"]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册