You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

random_ops.py 13 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. # Copyright 2020 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ============================================================================
  15. """Operations for random number generators."""
  16. from mindspore.ops.primitive import constexpr
  17. from .. import operations as P
  18. from .. import functional as F
  19. from .multitype_ops import _constexpr_utils as const_utils
  20. from ...common import dtype as mstype
  21. from ...common.seed import _get_graph_seed
  22. @constexpr
  23. def _get_seed(op_seed, kernel_name):
  24. "Get the graph-level seed."
  25. return _get_graph_seed(op_seed, kernel_name)
  26. def normal(shape, mean, stddev, seed=None):
  27. """
  28. Generates random numbers according to the Normal (or Gaussian) random number distribution.
  29. Args:
  30. shape (tuple): The shape of random tensor to be generated.
  31. mean (Tensor): The mean μ distribution parameter, which specifies the location of the peak,
  32. with data type in [int8, int16, int32, int64, float16, float32].
  33. stddev (Tensor): The deviation σ distribution parameter. It should be greater than 0,
  34. with data type in [int8, int16, int32, int64, float16, float32].
  35. seed (int): Seed is used as entropy source for the Random number engines to generate pseudo-random numbers.
  36. must be non-negative. Default: None, which will be treated as 0.
  37. Returns:
  38. Tensor. The shape should be equal to the broadcasted shape between the input `shape` and shapes
  39. of `mean` and `stddev`.
  40. The dtype is float32.
  41. Supported Platforms:
  42. ``Ascend`` ``GPU`` ``CPU``
  43. Examples:
  44. >>> shape = (3, 1, 2)
  45. >>> mean = Tensor(np.array([[3, 4], [5, 6]]), mstype.float32)
  46. >>> stddev = Tensor(1.0, mstype.float32)
  47. >>> output = C.normal(shape, mean, stddev, seed=5)
  48. >>> result = output.shape
  49. >>> print(result)
  50. (3, 2, 2)
  51. """
  52. mean_dtype = F.dtype(mean)
  53. stddev_dtype = F.dtype(stddev)
  54. const_utils.check_type_valid(mean_dtype, mstype.int_type + (mstype.float16, mstype.float32), 'normal')
  55. const_utils.check_type_valid(stddev_dtype, mstype.int_type + (mstype.float16, mstype.float32), 'normal')
  56. seed1, seed2 = _get_seed(seed, "normal")
  57. stdnormal = P.StandardNormal(seed1, seed2)
  58. random_normal = stdnormal(shape)
  59. value = random_normal * stddev + mean
  60. return value
  61. def laplace(shape, mean, lambda_param, seed=None):
  62. r"""
  63. Generates random numbers according to the Laplace random number distribution.
  64. It is defined as:
  65. .. math::
  66. \text{f}(x;μ,λ) = \frac{1}{2λ}\exp(-\frac{|x-μ|}{λ}),
  67. Args:
  68. shape (tuple): The shape of random tensor to be generated.
  69. mean (Tensor): The mean μ distribution parameter, which specifies the location of the peak.
  70. With float32 data type.
  71. lambda_param (Tensor): The parameter used for controlling the variance of this random distribution. The
  72. variance of Laplace distribution is equal to twice the square of lambda_param. With float32 data type.
  73. seed (int): Seed is used as entropy source for Random number engines generating pseudo-random numbers.
  74. Default: None, which will be treated as 0.
  75. Returns:
  76. Tensor. The shape should be the broadcasted shape of Input "shape" and shapes of mean and lambda_param.
  77. The dtype is float32.
  78. Supported Platforms:
  79. ``Ascend``
  80. Examples:
  81. >>> from mindspore import Tensor
  82. >>> from mindspore.ops import composite as C
  83. >>> import mindspore.common.dtype as mstype
  84. >>> shape = (2, 3)
  85. >>> mean = Tensor(1.0, mstype.float32)
  86. >>> lambda_param = Tensor(1.0, mstype.float32)
  87. >>> output = C.laplace(shape, mean, lambda_param, seed=5)
  88. >>> print(output.shape)
  89. (2, 3)
  90. """
  91. mean_dtype = F.dtype(mean)
  92. lambda_param_dtype = F.dtype(lambda_param)
  93. const_utils.check_tensors_dtype_same(mean_dtype, mstype.float32, "laplace")
  94. const_utils.check_tensors_dtype_same(lambda_param_dtype, mstype.float32, "laplace")
  95. seed1, seed2 = _get_seed(seed, "laplace")
  96. stdlaplace = P.StandardLaplace(seed1, seed2)
  97. rnd = stdlaplace(shape)
  98. value = rnd * lambda_param + mean
  99. return value
  100. def uniform(shape, minval, maxval, seed=None, dtype=mstype.float32):
  101. """
  102. Generates random numbers according to the Uniform random number distribution.
  103. Note:
  104. The number in tensor minval should be strictly less than maxval at any position after broadcasting.
  105. Args:
  106. shape (tuple): The shape of random tensor to be generated.
  107. minval (Tensor): The distribution parameter `a`.
  108. It defines the minimum possible generated value, with int32 or float32 data type.
  109. If dtype is int32, only one number is allowed.
  110. maxval (Tensor): The distribution parameter `b`.
  111. It defines the maximum possible generated value, with int32 or float32 data type.
  112. If dtype is int32, only one number is allowed.
  113. seed (int): Seed is used as entropy source for the random number engines to generate pseudo-random numbers,
  114. must be non-negative. Default: None, which will be treated as 0.
  115. dtype (mindspore.dtype): type of the Uniform distribution. If it is int32, it generates numbers from discrete
  116. uniform distribution; if it is float32, it generates numbers from continuous uniform distribution. It only
  117. supports these two data types. Default: mstype.float32.
  118. Returns:
  119. Tensor. The shape should be equal to the broadcasted shape between the input `shape` and shapes
  120. of `minval` and `maxval`.
  121. The dtype is designated as the input `dtype`.
  122. Supported Platforms:
  123. ``Ascend`` ``GPU``
  124. Examples:
  125. >>> # For discrete uniform distribution, only one number is allowed for both minval and maxval:
  126. >>> shape = (4, 2)
  127. >>> minval = Tensor(1, mstype.int32)
  128. >>> maxval = Tensor(2, mstype.int32)
  129. >>> output = C.uniform(shape, minval, maxval, seed=5, dtype=mstype.int32)
  130. >>>
  131. >>> # For continuous uniform distribution, minval and maxval can be multi-dimentional:
  132. >>> shape = (3, 1, 2)
  133. >>> minval = Tensor(np.array([[3, 4], [5, 6]]), mstype.float32)
  134. >>> maxval = Tensor([8.0, 10.0], mstype.float32)
  135. >>> output = C.uniform(shape, minval, maxval, seed=5)
  136. >>> result = output.shape
  137. >>> print(result)
  138. (3, 2, 2)
  139. """
  140. minval_dtype = F.dtype(minval)
  141. maxval_dtype = F.dtype(maxval)
  142. const_utils.check_type_valid(dtype, [mstype.int32, mstype.float32], 'uniform')
  143. const_utils.check_tensors_dtype_same(minval_dtype, dtype, "uniform")
  144. const_utils.check_tensors_dtype_same(maxval_dtype, dtype, "uniform")
  145. seed1, seed2 = _get_seed(seed, "uniform")
  146. if const_utils.is_same_type(dtype, mstype.int32):
  147. random_uniform = P.UniformInt(seed1, seed2)
  148. value = random_uniform(shape, minval, maxval)
  149. else:
  150. uniform_real = P.UniformReal(seed1, seed2)
  151. random_uniform = uniform_real(shape)
  152. value = random_uniform * (maxval - minval) + minval
  153. return value
  154. def gamma(shape, alpha, beta, seed=None):
  155. """
  156. Generates random numbers according to the Gamma random number distribution.
  157. Args:
  158. shape (tuple): The shape of random tensor to be generated.
  159. alpha (Tensor): The alpha α distribution parameter. It should be greater than 0 with float32 data type.
  160. beta (Tensor): The beta β distribution parameter. It should be greater than 0 with float32 data type.
  161. seed (int): Seed is used as entropy source for the random number engines to generate
  162. pseudo-random numbers, must be non-negative. Default: None, which will be treated as 0.
  163. Returns:
  164. Tensor. The shape should be equal to the broadcasted shape between the input "shape" and shapes
  165. of `alpha` and `beta`.
  166. The dtype is float32.
  167. Raises:
  168. TypeError: If `shape` is not a tuple.
  169. TypeError: If neither `alpha` nor `beta` is a Tensor.
  170. TypeError: If `seed` is not an int.
  171. TypeError: If dtype of `alpha` and `beta` is not float32.
  172. Supported Platforms:
  173. ``Ascend``
  174. Examples:
  175. >>> shape = (3, 1, 2)
  176. >>> alpha = Tensor(np.array([[3, 4], [5, 6]]), mstype.float32)
  177. >>> beta = Tensor(np.array([1.0]), mstype.float32)
  178. >>> output = C.gamma(shape, alpha, beta, seed=5)
  179. >>> result = output.shape
  180. >>> print(result)
  181. (3, 2, 2)
  182. """
  183. seed1, seed2 = _get_seed(seed, "gamma")
  184. random_gamma = P.Gamma(seed1, seed2)
  185. value = random_gamma(shape, alpha, beta)
  186. return value
  187. def poisson(shape, mean, seed=None):
  188. r"""
  189. Generates random numbers according to the Poisson random number distribution.
  190. .. math::
  191. \text{P}(i|μ) = \frac{\exp(-μ)μ^{i}}{i!}
  192. Args:
  193. shape (tuple): The shape of random tensor to be generated.
  194. mean (Tensor): The mean μ distribution parameter. It should be greater than 0 with float32 data type.
  195. seed (int): Seed is used as entropy source for the random number engines to generate pseudo-random numbers
  196. and must be non-negative. Default: None, which will be treated as 0.
  197. Returns:
  198. Tensor. The shape should be equal to the broadcasted shape between the input "shape" and shapes of `mean`.
  199. The dtype is float32.
  200. Raises:
  201. TypeError: If `shape` is not a tuple.
  202. TypeError: If `mean` is not a Tensor whose dtype is not float32.
  203. TypeError: If `seed` is not an int.
  204. Supported Platforms:
  205. ``Ascend``
  206. Examples:
  207. >>> shape = (4, 1)
  208. >>> mean = Tensor(np.array([5.0, 10.0]), mstype.float32)
  209. >>> output = C.poisson(shape, mean, seed=5)
  210. >>> result = output.shape
  211. >>> print(result)
  212. (4, 2)
  213. """
  214. seed1, seed2 = _get_seed(seed, "poisson")
  215. random_poisson = P.Poisson(seed1, seed2)
  216. value = random_poisson(shape, mean)
  217. return value
  218. def multinomial(inputs, num_sample, replacement=True, seed=None):
  219. r"""
  220. Returns a tensor sampled from the multinomial probability distribution located in the corresponding
  221. row of the input tensor.
  222. Note:
  223. The rows of input do not need to sum to one (in which case we use the values as weights),
  224. but must be non-negative, finite and have a non-zero sum.
  225. Args:
  226. inputs (Tensor): The input tensor containing probabilities, must be 1 or 2 dimensions, with
  227. float32 data type.
  228. num_sample (int): Number of samples to draw.
  229. replacement (bool, optional): Whether to draw with replacement or not, default True.
  230. seed (int, optional): Seed is used as entropy source for the random number engines to generate
  231. pseudo-random numbers, must be non-negative. Default: 0.
  232. Outputs:
  233. Tensor, has the same rows with input. The number of sampled indices of each row is `num_samples`.
  234. The dtype is float32.
  235. Raises:
  236. TypeError: If `inputs` is not a Tensor whose dtype is not float32.
  237. TypeError: If `num_sample` is not an int.
  238. TypeError: If `seed` is neither an int nor a optional.
  239. Supported Platforms:
  240. ``GPU``
  241. Examples:
  242. >>> input = Tensor([0, 9, 4, 0], mstype.float32)
  243. >>> output = C.multinomial(input, 2, True)
  244. >>> print(output)
  245. [1 1]
  246. """
  247. shape = P.Shape()
  248. reshape = P.Reshape()
  249. const_utils.check_valid_dim(len(shape(inputs)), "multinomial")
  250. seed1, seed2 = _get_seed(seed, "multinomial")
  251. if not replacement:
  252. if shape(inputs)[-1] < num_sample:
  253. const_utils.raise_value_error("num_sample must be less than shape(input)[-1] without replacement")
  254. n_dist = 1
  255. if len(shape(inputs)) > 1:
  256. n_dist = shape(inputs)[-2]
  257. random_uniform = P.UniformReal(seed1, seed2)((n_dist * shape(inputs)[-1],))
  258. if n_dist != 1:
  259. random_uniform = reshape(random_uniform, (n_dist, shape(inputs)[-1]))
  260. vals = P.RealDiv()(P.Log()(random_uniform), inputs + 1e-6)
  261. _, indices = P.TopK()(vals, num_sample)
  262. return indices
  263. return P.Multinomial(seed1, seed2)(inputs, num_sample)