Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorflow/python/ops/random_ops.py: 39%

176 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-03 07:57 +0000

1# Copyright 2015 The TensorFlow Authors. All Rights Reserved. 

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 generating random numbers.""" 

16 

17import numpy as np 

18 

19from tensorflow.python.eager import context 

20from tensorflow.python.framework import dtypes 

21from tensorflow.python.framework import ops 

22from tensorflow.python.framework import random_seed 

23from tensorflow.python.framework import tensor_util 

24from tensorflow.python.ops import array_ops 

25from tensorflow.python.ops import control_flow_assert 

26from tensorflow.python.ops import control_flow_ops 

27from tensorflow.python.ops import gen_random_ops 

28from tensorflow.python.ops import math_ops 

29from tensorflow.python.ops import shape_util 

30from tensorflow.python.ops import stateless_random_ops 

31 

32# go/tf-wildcard-import 

33# pylint: disable=wildcard-import 

34from tensorflow.python.ops.gen_random_ops import * 

35# pylint: enable=wildcard-import 

36 

37from tensorflow.python.util import deprecation 

38from tensorflow.python.util import dispatch 

39from tensorflow.python.util.tf_export import tf_export 

40 

41 

42@tf_export("random.normal", v1=["random.normal", "random_normal"]) 

43@dispatch.add_dispatch_support 

44@deprecation.deprecated_endpoints("random_normal") 

45def random_normal(shape, 

46 mean=0.0, 

47 stddev=1.0, 

48 dtype=dtypes.float32, 

49 seed=None, 

50 name=None): 

51 """Outputs random values from a normal distribution. 

52 

53 Example that generates a new set of random values every time: 

54 

55 >>> tf.random.set_seed(5); 

56 >>> tf.random.normal([4], 0, 1, tf.float32) 

57 <tf.Tensor: shape=(4,), dtype=float32, numpy=..., dtype=float32)> 

58 

59 Example that outputs a reproducible result: 

60 

61 >>> tf.random.set_seed(5); 

62 >>> tf.random.normal([2,2], 0, 1, tf.float32, seed=1) 

63 <tf.Tensor: shape=(2, 2), dtype=float32, numpy= 

64 array([[-1.3768897 , -0.01258316], 

65 [-0.169515 , 1.0824056 ]], dtype=float32)> 

66 

67 In this case, we are setting both the global and operation-level seed to 

68 ensure this result is reproducible. See `tf.random.set_seed` for more 

69 information. 

70 

71 Args: 

72 shape: A 1-D integer Tensor or Python array. The shape of the output tensor. 

73 mean: A Tensor or Python value of type `dtype`, broadcastable with `stddev`. 

74 The mean of the normal distribution. 

75 stddev: A Tensor or Python value of type `dtype`, broadcastable with `mean`. 

76 The standard deviation of the normal distribution. 

77 dtype: The float type of the output: `float16`, `bfloat16`, `float32`, 

78 `float64`. Defaults to `float32`. 

79 seed: A Python integer. Used to create a random seed for the distribution. 

80 See 

81 `tf.random.set_seed` 

82 for behavior. 

83 name: A name for the operation (optional). 

84 

85 Returns: 

86 A tensor of the specified shape filled with random normal values. 

87 """ 

88 with ops.name_scope(name, "random_normal", [shape, mean, stddev]) as name: 

89 shape_tensor = shape_util.shape_tensor(shape) 

90 mean_tensor = ops.convert_to_tensor(mean, dtype=dtype, name="mean") 

91 stddev_tensor = ops.convert_to_tensor(stddev, dtype=dtype, name="stddev") 

92 seed1, seed2 = random_seed.get_seed(seed) 

93 rnd = gen_random_ops.random_standard_normal( 

94 shape_tensor, dtype, seed=seed1, seed2=seed2) 

95 mul = rnd * stddev_tensor 

96 value = math_ops.add(mul, mean_tensor, name=name) 

97 shape_util.maybe_set_static_shape(value, shape) 

98 return value 

99 

100 

101ops.NotDifferentiable("RandomStandardNormal") 

102 

103 

104def parameterized_truncated_normal(shape, 

105 means=0.0, 

106 stddevs=1.0, 

107 minvals=-2.0, 

108 maxvals=2.0, 

109 dtype=dtypes.float32, 

110 seed=None, 

111 name=None): 

112 """Outputs random values from a truncated normal distribution. 

113 

114 The generated values follow a normal distribution with specified mean and 

115 standard deviation, except that values whose magnitude is more than 2 standard 

116 deviations from the mean are dropped and re-picked. 

117 

118 Args: 

119 shape: A 1-D integer Tensor or Python array. The shape of the output tensor. 

120 means: A 0-D Tensor or Python value of type `dtype`. The mean of the 

121 truncated normal distribution. 

122 stddevs: A 0-D Tensor or Python value of type `dtype`. The standard 

123 deviation of the truncated normal distribution. 

124 minvals: A 0-D Tensor or Python value of type `dtype`. The minimum value of 

125 the truncated normal distribution. 

126 maxvals: A 0-D Tensor or Python value of type `dtype`. The maximum value of 

127 the truncated normal distribution. 

128 dtype: The type of the output. 

129 seed: A Python integer. Used to create a random seed for the distribution. 

130 See 

131 `tf.random.set_seed` 

132 for behavior. 

133 name: A name for the operation (optional). 

134 

135 Returns: 

136 A tensor of the specified shape filled with random truncated normal values. 

137 """ 

138 with ops.name_scope(name, "parameterized_truncated_normal", 

139 [shape, means, stddevs, minvals, maxvals]) as name: 

140 shape_tensor = shape_util.shape_tensor(shape) 

141 means_tensor = ops.convert_to_tensor(means, dtype=dtype, name="means") 

142 stddevs_tensor = ops.convert_to_tensor(stddevs, dtype=dtype, name="stddevs") 

143 minvals_tensor = ops.convert_to_tensor(minvals, dtype=dtype, name="minvals") 

144 maxvals_tensor = ops.convert_to_tensor(maxvals, dtype=dtype, name="maxvals") 

145 seed1, seed2 = random_seed.get_seed(seed) 

146 rnd = gen_random_ops.parameterized_truncated_normal( 

147 shape_tensor, 

148 means_tensor, 

149 stddevs_tensor, 

150 minvals_tensor, 

151 maxvals_tensor, 

152 seed=seed1, 

153 seed2=seed2) 

154 shape_util.maybe_set_static_shape(rnd, shape) 

155 return rnd 

156 

157 

158@tf_export("random.truncated_normal", 

159 v1=["random.truncated_normal", "truncated_normal"]) 

160@dispatch.add_dispatch_support 

161@deprecation.deprecated_endpoints("truncated_normal") 

162def truncated_normal(shape, 

163 mean=0.0, 

164 stddev=1.0, 

165 dtype=dtypes.float32, 

166 seed=None, 

167 name=None): 

168 """Outputs random values from a truncated normal distribution. 

169 

170 The values are drawn from a normal distribution with specified mean and 

171 standard deviation, discarding and re-drawing any samples that are more than 

172 two standard deviations from the mean. 

173 

174 Examples: 

175 

176 >>> tf.random.truncated_normal(shape=[2]) 

177 <tf.Tensor: shape=(2,), dtype=float32, numpy=array([..., ...], dtype=float32)> 

178 

179 >>> tf.random.truncated_normal(shape=[2], mean=3, stddev=1, dtype=tf.float32) 

180 <tf.Tensor: shape=(2,), dtype=float32, numpy=array([..., ...], dtype=float32)> 

181 

182 Args: 

183 shape: A 1-D integer Tensor or Python array. The shape of the output tensor. 

184 mean: A 0-D Tensor or Python value of type `dtype`. The mean of the 

185 truncated normal distribution. 

186 stddev: A 0-D Tensor or Python value of type `dtype`. The standard deviation 

187 of the normal distribution, before truncation. 

188 dtype: The type of the output. Restricted to floating-point types: 

189 `tf.half`, `tf.float`, `tf.double`, etc. 

190 seed: A Python integer. Used to create a random seed for the distribution. 

191 See `tf.random.set_seed` for more information. 

192 name: A name for the operation (optional). 

193 

194 Returns: 

195 A tensor of the specified shape filled with random truncated normal values. 

196 """ 

197 with ops.name_scope(name, "truncated_normal", [shape, mean, stddev]) as name: 

198 shape_tensor = shape_util.shape_tensor(shape) 

199 mean_tensor = ops.convert_to_tensor(mean, dtype=dtype, name="mean") 

200 stddev_tensor = ops.convert_to_tensor(stddev, dtype=dtype, name="stddev") 

201 seed1, seed2 = random_seed.get_seed(seed) 

202 rnd = gen_random_ops.truncated_normal( 

203 shape_tensor, dtype, seed=seed1, seed2=seed2) 

204 mul = rnd * stddev_tensor 

205 value = math_ops.add(mul, mean_tensor, name=name) 

206 shape_util.maybe_set_static_shape(value, shape) 

207 return value 

208 

209 

210ops.NotDifferentiable("ParameterizedTruncatedNormal") 

211ops.NotDifferentiable("TruncatedNormal") 

212 

213 

214@tf_export("random.uniform", v1=["random.uniform", "random_uniform"]) 

215@dispatch.add_dispatch_support 

216@deprecation.deprecated_endpoints("random_uniform") 

217def random_uniform(shape, 

218 minval=0, 

219 maxval=None, 

220 dtype=dtypes.float32, 

221 seed=None, 

222 name=None): 

223 """Outputs random values from a uniform distribution. 

224 

225 The generated values follow a uniform distribution in the range 

226 `[minval, maxval)`. The lower bound `minval` is included in the range, while 

227 the upper bound `maxval` is excluded. 

228 

229 For floats, the default range is `[0, 1)`. For ints, at least `maxval` must 

230 be specified explicitly. 

231 

232 In the integer case, the random integers are slightly biased unless 

233 `maxval - minval` is an exact power of two. The bias is small for values of 

234 `maxval - minval` significantly smaller than the range of the output (either 

235 `2**32` or `2**64`). 

236 

237 Examples: 

238 

239 >>> tf.random.uniform(shape=[2]) 

240 <tf.Tensor: shape=(2,), dtype=float32, numpy=array([..., ...], dtype=float32)> 

241 >>> tf.random.uniform(shape=[], minval=-1., maxval=0.) 

242 <tf.Tensor: shape=(), dtype=float32, numpy=-...> 

243 >>> tf.random.uniform(shape=[], minval=5, maxval=10, dtype=tf.int64) 

244 <tf.Tensor: shape=(), dtype=int64, numpy=...> 

245 

246 The `seed` argument produces a deterministic sequence of tensors across 

247 multiple calls. To repeat that sequence, use `tf.random.set_seed`: 

248 

249 >>> tf.random.set_seed(5) 

250 >>> tf.random.uniform(shape=[], maxval=3, dtype=tf.int32, seed=10) 

251 <tf.Tensor: shape=(), dtype=int32, numpy=2> 

252 >>> tf.random.uniform(shape=[], maxval=3, dtype=tf.int32, seed=10) 

253 <tf.Tensor: shape=(), dtype=int32, numpy=0> 

254 >>> tf.random.set_seed(5) 

255 >>> tf.random.uniform(shape=[], maxval=3, dtype=tf.int32, seed=10) 

256 <tf.Tensor: shape=(), dtype=int32, numpy=2> 

257 >>> tf.random.uniform(shape=[], maxval=3, dtype=tf.int32, seed=10) 

258 <tf.Tensor: shape=(), dtype=int32, numpy=0> 

259 

260 Without `tf.random.set_seed` but with a `seed` argument is specified, small 

261 changes to function graphs or previously executed operations will change the 

262 returned value. See `tf.random.set_seed` for details. 

263 

264 Args: 

265 shape: A 1-D integer Tensor or Python array. The shape of the output tensor. 

266 minval: A Tensor or Python value of type `dtype`, broadcastable with 

267 `shape` (for integer types, broadcasting is not supported, so it needs to 

268 be a scalar). The lower bound on the range of random values to generate 

269 (inclusive). Defaults to 0. 

270 maxval: A Tensor or Python value of type `dtype`, broadcastable with 

271 `shape` (for integer types, broadcasting is not supported, so it needs to 

272 be a scalar). The upper bound on the range of random values to generate 

273 (exclusive). Defaults to 1 if `dtype` is floating point. 

274 dtype: The type of the output: `float16`, `bfloat16`, `float32`, `float64`, 

275 `int32`, or `int64`. Defaults to `float32`. 

276 seed: A Python integer. Used in combination with `tf.random.set_seed` to 

277 create a reproducible sequence of tensors across multiple calls. 

278 name: A name for the operation (optional). 

279 

280 Returns: 

281 A tensor of the specified shape filled with random uniform values. 

282 

283 Raises: 

284 ValueError: If `dtype` is integral and `maxval` is not specified. 

285 """ 

286 dtype = dtypes.as_dtype(dtype) 

287 accepted_dtypes = (dtypes.float16, dtypes.bfloat16, dtypes.float32, 

288 dtypes.float64, dtypes.int32, dtypes.int64) 

289 if dtype not in accepted_dtypes: 

290 raise ValueError( 

291 f"Argument `dtype` got invalid value {dtype}. Accepted dtypes are " 

292 f"{accepted_dtypes}.") 

293 if maxval is None: 

294 if dtype.is_integer: 

295 raise ValueError("Must specify maxval for integer dtype %r" % dtype) 

296 maxval = 1 

297 with ops.name_scope(name, "random_uniform", [shape, minval, maxval]) as name: 

298 shape = shape_util.shape_tensor(shape) 

299 # In case of [0,1) floating results, minval and maxval is unused. We do an 

300 # `is` comparison here since this is cheaper than isinstance or __eq__. 

301 minval_is_zero = isinstance(minval, int) and minval == 0 

302 maxval_is_one = isinstance(maxval, int) and maxval == 1 

303 if not minval_is_zero or not maxval_is_one or dtype.is_integer: 

304 minval = ops.convert_to_tensor(minval, dtype=dtype, name="min") 

305 maxval = ops.convert_to_tensor(maxval, dtype=dtype, name="max") 

306 seed1, seed2 = random_seed.get_seed(seed) 

307 if dtype.is_integer: 

308 result = gen_random_ops.random_uniform_int( 

309 shape, minval, maxval, seed=seed1, seed2=seed2, name=name) 

310 else: 

311 result = gen_random_ops.random_uniform( 

312 shape, dtype, seed=seed1, seed2=seed2) 

313 if minval_is_zero: 

314 if not maxval_is_one: 

315 result = math_ops.multiply(result, maxval) 

316 else: 

317 result = math_ops.add(result * (maxval - minval), minval, name=name) 

318 # TODO(b/132092188): C++ shape inference inside functional ops does not 

319 # cross FuncGraph boundaries since that information is only available in 

320 # python. So we manually get the static shape using 

321 # `constant_value_as_shape` which *does* cross function boundaries. 

322 shape_util.maybe_set_static_shape(result, shape) 

323 return result 

324 

325 

326ops.NotDifferentiable("RandomUniform") 

327 

328 

329@tf_export("random.shuffle", v1=["random.shuffle", "random_shuffle"]) 

330@dispatch.add_dispatch_support 

331@deprecation.deprecated_endpoints("random_shuffle") 

332def random_shuffle(value, seed=None, name=None): 

333 """Randomly shuffles a tensor along its first dimension. 

334 

335 The tensor is shuffled along dimension 0, such that each `value[j]` is mapped 

336 to one and only one `output[i]`. For example, a mapping that might occur for a 

337 3x2 tensor is: 

338 

339 ```python 

340 [[1, 2], [[5, 6], 

341 [3, 4], ==> [1, 2], 

342 [5, 6]] [3, 4]] 

343 ``` 

344 

345 Args: 

346 value: A Tensor to be shuffled. 

347 seed: A Python integer. Used to create a random seed for the distribution. 

348 See 

349 `tf.random.set_seed` 

350 for behavior. 

351 name: A name for the operation (optional). 

352 

353 Returns: 

354 A tensor of same shape and type as `value`, shuffled along its first 

355 dimension. 

356 """ 

357 seed1, seed2 = random_seed.get_seed(seed) 

358 return gen_random_ops.random_shuffle( 

359 value, seed=seed1, seed2=seed2, name=name) 

360 

361 

362ops.NotDifferentiable("RandomShuffle") 

363 

364 

365@tf_export("image.random_crop", v1=["image.random_crop", "random_crop"]) 

366@dispatch.add_dispatch_support 

367@deprecation.deprecated_endpoints("random_crop") 

368def random_crop(value, size, seed=None, name=None): 

369 """Randomly crops a tensor to a given size. 

370 

371 Slices a shape `size` portion out of `value` at a uniformly chosen offset. 

372 Requires `value.shape >= size`. 

373 

374 If a dimension should not be cropped, pass the full size of that dimension. 

375 For example, RGB images can be cropped with 

376 `size = [crop_height, crop_width, 3]`. 

377 

378 Example usage: 

379 

380 >>> image = [[1, 2, 3], [4, 5, 6]] 

381 >>> result = tf.image.random_crop(value=image, size=(1, 3)) 

382 >>> result.shape.as_list() 

383 [1, 3] 

384 

385 For producing deterministic results given a `seed` value, use 

386 `tf.image.stateless_random_crop`. Unlike using the `seed` param with 

387 `tf.image.random_*` ops, `tf.image.stateless_random_*` ops guarantee the same 

388 results given the same seed independent of how many times the function is 

389 called, and independent of global seed settings (e.g. tf.random.set_seed). 

390 

391 Args: 

392 value: Input tensor to crop. 

393 size: 1-D tensor with size the rank of `value`. 

394 seed: Python integer. Used to create a random seed. See 

395 `tf.random.set_seed` 

396 for behavior. 

397 name: A name for this operation (optional). 

398 

399 Returns: 

400 A cropped tensor of the same rank as `value` and shape `size`. 

401 """ 

402 with ops.name_scope(name, "random_crop", [value, size]) as name: 

403 value = ops.convert_to_tensor(value, name="value") 

404 size = ops.convert_to_tensor(size, dtype=dtypes.int32, name="size") 

405 shape = array_ops.shape(value) 

406 check = control_flow_assert.Assert( 

407 math_ops.reduce_all(shape >= size), 

408 ["Need value.shape >= size, got ", shape, size], 

409 summarize=1000) 

410 shape = control_flow_ops.with_dependencies([check], shape) 

411 limit = shape - size + 1 

412 offset = random_uniform( 

413 array_ops.shape(shape), 

414 dtype=size.dtype, 

415 maxval=size.dtype.max, 

416 seed=seed) % limit 

417 return array_ops.slice(value, offset, size, name=name) 

418 

419 

420@tf_export("image.stateless_random_crop", v1=[]) 

421@dispatch.add_dispatch_support 

422def stateless_random_crop(value, size, seed, name=None): 

423 """Randomly crops a tensor to a given size in a deterministic manner. 

424 

425 Slices a shape `size` portion out of `value` at a uniformly chosen offset. 

426 Requires `value.shape >= size`. 

427 

428 If a dimension should not be cropped, pass the full size of that dimension. 

429 For example, RGB images can be cropped with 

430 `size = [crop_height, crop_width, 3]`. 

431 

432 Guarantees the same results given the same `seed` independent of how many 

433 times the function is called, and independent of global seed settings (e.g. 

434 `tf.random.set_seed`). 

435 

436 Usage Example: 

437 

438 >>> image = [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]] 

439 >>> seed = (1, 2) 

440 >>> tf.image.stateless_random_crop(value=image, size=(1, 2, 3), seed=seed) 

441 <tf.Tensor: shape=(1, 2, 3), dtype=int32, numpy= 

442 array([[[1, 2, 3], 

443 [4, 5, 6]]], dtype=int32)> 

444 

445 Args: 

446 value: Input tensor to crop. 

447 size: 1-D tensor with size the rank of `value`. 

448 seed: A shape [2] Tensor, the seed to the random number generator. Must have 

449 dtype `int32` or `int64`. (When using XLA, only `int32` is allowed.) 

450 name: A name for this operation (optional). 

451 

452 Returns: 

453 A cropped tensor of the same rank as `value` and shape `size`. 

454 """ 

455 with ops.name_scope(name, "random_crop", [value, size]) as name: 

456 value = ops.convert_to_tensor(value, name="value") 

457 size = ops.convert_to_tensor(size, dtype=dtypes.int32, name="size") 

458 shape = array_ops.shape(value) 

459 check = control_flow_assert.Assert( 

460 math_ops.reduce_all(shape >= size), 

461 ["Need value.shape >= size, got ", shape, size], 

462 summarize=1000) 

463 shape = control_flow_ops.with_dependencies([check], shape) 

464 limit = shape - size + 1 

465 offset = stateless_random_ops.stateless_random_uniform( 

466 array_ops.shape(shape), 

467 dtype=size.dtype, 

468 maxval=size.dtype.max, 

469 seed=seed) % limit 

470 return array_ops.slice(value, offset, size, name=name) 

471 

472 

473@tf_export(v1=["random.multinomial", "multinomial"]) 

474@dispatch.add_dispatch_support 

475@deprecation.deprecated( 

476 date=None, instructions="Use `tf.random.categorical` instead.") 

477def multinomial(logits, num_samples, seed=None, name=None, output_dtype=None): 

478 """Draws samples from a multinomial distribution. 

479 

480 Example: 

481 

482 ```python 

483 # samples has shape [1, 5], where each value is either 0 or 1 with equal 

484 # probability. 

485 samples = tf.random.categorical(tf.math.log([[0.5, 0.5]]), 5) 

486 ``` 

487 

488 Args: 

489 logits: 2-D Tensor with shape `[batch_size, num_classes]`. Each slice 

490 `[i, :]` represents the unnormalized log-probabilities for all classes. 

491 num_samples: 0-D. Number of independent samples to draw for each row slice. 

492 seed: A Python integer. Used to create a random seed for the distribution. 

493 See `tf.random.set_seed` for behavior. 

494 name: Optional name for the operation. 

495 output_dtype: The integer type of the output: `int32` or `int64`. Defaults 

496 to `int64`. 

497 

498 Returns: 

499 The drawn samples of shape `[batch_size, num_samples]`. 

500 """ 

501 with ops.name_scope(name, "multinomial", [logits]): 

502 return multinomial_categorical_impl(logits, num_samples, output_dtype, seed) 

503 

504 

505@tf_export("random.categorical") 

506@dispatch.add_dispatch_support 

507def categorical(logits, num_samples, dtype=None, seed=None, name=None): 

508 """Draws samples from a categorical distribution. 

509 

510 Example: 

511 

512 ```python 

513 # samples has shape [1, 5], where each value is either 0 or 1 with equal 

514 # probability. 

515 samples = tf.random.categorical(tf.math.log([[0.5, 0.5]]), 5) 

516 ``` 

517 

518 Args: 

519 logits: 2-D Tensor with shape `[batch_size, num_classes]`. Each slice 

520 `[i, :]` represents the unnormalized log-probabilities for all classes. 

521 num_samples: 0-D. Number of independent samples to draw for each row slice. 

522 dtype: The integer type of the output: `int32` or `int64`. Defaults to 

523 `int64`. 

524 seed: A Python integer. Used to create a random seed for the distribution. 

525 See `tf.random.set_seed` for behavior. 

526 name: Optional name for the operation. 

527 

528 Returns: 

529 The drawn samples of shape `[batch_size, num_samples]`. 

530 """ 

531 with ops.name_scope(name, "categorical", [logits]): 

532 return multinomial_categorical_impl(logits, num_samples, dtype, seed) 

533 

534 

535def multinomial_categorical_impl(logits, num_samples, dtype, seed): 

536 """Implementation for random.categorical (v1) and random.categorical (v2).""" 

537 logits = ops.convert_to_tensor(logits, name="logits") 

538 dtype = dtypes.as_dtype(dtype) if dtype else dtypes.int64 

539 accepted_dtypes = (dtypes.int32, dtypes.int64) 

540 if dtype not in accepted_dtypes: 

541 raise ValueError( 

542 f"Argument `dtype` got invalid value {dtype}. Accepted dtypes are " 

543 f"{accepted_dtypes}.") 

544 seed1, seed2 = random_seed.get_seed(seed) 

545 return gen_random_ops.multinomial( 

546 logits, num_samples, seed=seed1, seed2=seed2, output_dtype=dtype) 

547 

548 

549ops.NotDifferentiable("Multinomial") 

550 

551 

552def _maybe_set_static_shape_helper(tensor, shape, postfix_tensor): 

553 if (not context.executing_eagerly() and 

554 ops.get_default_graph().building_function and 

555 not tensor.shape.is_fully_defined()): 

556 shape = shape_util.shape_tensor(shape) 

557 const_shape = tensor_util.constant_value_as_shape(shape) 

558 postfix_tensor = ops.convert_to_tensor(postfix_tensor) 

559 tensor.set_shape(const_shape.concatenate(postfix_tensor.shape)) 

560 

561 

562@tf_export("random.gamma", v1=["random.gamma", "random_gamma"]) 

563@dispatch.add_dispatch_support 

564@deprecation.deprecated_endpoints("random_gamma") 

565def random_gamma(shape, 

566 alpha, 

567 beta=None, 

568 dtype=dtypes.float32, 

569 seed=None, 

570 name=None): 

571 """Draws `shape` samples from each of the given Gamma distribution(s). 

572 

573 `alpha` is the shape parameter describing the distribution(s), and `beta` is 

574 the inverse scale parameter(s). 

575 

576 Note: Because internal calculations are done using `float64` and casting has 

577 `floor` semantics, we must manually map zero outcomes to the smallest 

578 possible positive floating-point value, i.e., `np.finfo(dtype).tiny`. This 

579 means that `np.finfo(dtype).tiny` occurs more frequently than it otherwise 

580 should. This bias can only happen for small values of `alpha`, i.e., 

581 `alpha << 1` or large values of `beta`, i.e., `beta >> 1`. 

582 

583 The samples are differentiable w.r.t. alpha and beta. 

584 The derivatives are computed using the approach described in 

585 (Figurnov et al., 2018). 

586 

587 Example: 

588 

589 ```python 

590 samples = tf.random.gamma([10], [0.5, 1.5]) 

591 # samples has shape [10, 2], where each slice [:, 0] and [:, 1] represents 

592 # the samples drawn from each distribution 

593 

594 samples = tf.random.gamma([7, 5], [0.5, 1.5]) 

595 # samples has shape [7, 5, 2], where each slice [:, :, 0] and [:, :, 1] 

596 # represents the 7x5 samples drawn from each of the two distributions 

597 

598 alpha = tf.constant([[1.],[3.],[5.]]) 

599 beta = tf.constant([[3., 4.]]) 

600 samples = tf.random.gamma([30], alpha=alpha, beta=beta) 

601 # samples has shape [30, 3, 2], with 30 samples each of 3x2 distributions. 

602 

603 loss = tf.reduce_mean(tf.square(samples)) 

604 dloss_dalpha, dloss_dbeta = tf.gradients(loss, [alpha, beta]) 

605 # unbiased stochastic derivatives of the loss function 

606 alpha.shape == dloss_dalpha.shape # True 

607 beta.shape == dloss_dbeta.shape # True 

608 ``` 

609 

610 Args: 

611 shape: A 1-D integer Tensor or Python array. The shape of the output samples 

612 to be drawn per alpha/beta-parameterized distribution. 

613 alpha: A Tensor or Python value or N-D array of type `dtype`. `alpha` 

614 provides the shape parameter(s) describing the gamma distribution(s) to 

615 sample. Must be broadcastable with `beta`. 

616 beta: A Tensor or Python value or N-D array of type `dtype`. Defaults to 1. 

617 `beta` provides the inverse scale parameter(s) of the gamma 

618 distribution(s) to sample. Must be broadcastable with `alpha`. 

619 dtype: The type of alpha, beta, and the output: `float16`, `float32`, or 

620 `float64`. 

621 seed: A Python integer. Used to create a random seed for the distributions. 

622 See 

623 `tf.random.set_seed` 

624 for behavior. 

625 name: Optional name for the operation. 

626 

627 Returns: 

628 samples: a `Tensor` of shape 

629 `tf.concat([shape, tf.shape(alpha + beta)], axis=0)` with values of type 

630 `dtype`. 

631 

632 References: 

633 Implicit Reparameterization Gradients: 

634 [Figurnov et al., 2018] 

635 (http://papers.nips.cc/paper/7326-implicit-reparameterization-gradients) 

636 ([pdf] 

637 (http://papers.nips.cc/paper/7326-implicit-reparameterization-gradients.pdf)) 

638 """ 

639 with ops.name_scope(name, "random_gamma", [shape, alpha, beta]): 

640 shape = ops.convert_to_tensor(shape, name="shape", dtype=dtypes.int32) 

641 alpha = ops.convert_to_tensor(alpha, name="alpha", dtype=dtype) 

642 beta = ops.convert_to_tensor( 

643 beta if beta is not None else 1, name="beta", dtype=dtype) 

644 broadcast_shape = array_ops.broadcast_dynamic_shape( 

645 array_ops.shape(alpha), array_ops.shape(beta)) 

646 alpha_broadcast = array_ops.broadcast_to(alpha, broadcast_shape) 

647 seed1, seed2 = random_seed.get_seed(seed) 

648 result = math_ops.maximum( 

649 np.finfo(alpha.dtype.as_numpy_dtype).tiny, 

650 gen_random_ops.random_gamma( 

651 shape, alpha_broadcast, seed=seed1, seed2=seed2) / beta) 

652 _maybe_set_static_shape_helper(result, shape, alpha_broadcast) 

653 return result 

654 

655 

656@tf_export(v1=["random.poisson", "random_poisson"]) 

657@dispatch.add_dispatch_support 

658@deprecation.deprecated_endpoints("random_poisson") 

659def random_poisson(lam, shape, dtype=dtypes.float32, seed=None, name=None): 

660 """Draws `shape` samples from each of the given Poisson distribution(s). 

661 

662 `lam` is the rate parameter describing the distribution(s). 

663 

664 Example: 

665 

666 ```python 

667 samples = tf.random.poisson([0.5, 1.5], [10]) 

668 # samples has shape [10, 2], where each slice [:, 0] and [:, 1] represents 

669 # the samples drawn from each distribution 

670 

671 samples = tf.random.poisson([12.2, 3.3], [7, 5]) 

672 # samples has shape [7, 5, 2], where each slice [:, :, 0] and [:, :, 1] 

673 # represents the 7x5 samples drawn from each of the two distributions 

674 ``` 

675 

676 Args: 

677 lam: A Tensor or Python value or N-D array of type `dtype`. 

678 `lam` provides the rate parameter(s) describing the poisson 

679 distribution(s) to sample. 

680 shape: A 1-D integer Tensor or Python array. The shape of the output samples 

681 to be drawn per "rate"-parameterized distribution. 

682 dtype: The type of the output: `float16`, `float32`, `float64`, `int32` or 

683 `int64`. 

684 seed: A Python integer. Used to create a random seed for the distributions. 

685 See 

686 `tf.random.set_seed` 

687 for behavior. 

688 name: Optional name for the operation. 

689 

690 Returns: 

691 samples: a `Tensor` of shape `tf.concat([shape, tf.shape(lam)], axis=0)` 

692 with values of type `dtype`. 

693 """ 

694 return random_poisson_v2(shape, lam, dtype, seed, name) 

695 

696 

697@tf_export("random.poisson", v1=[]) 

698@dispatch.add_dispatch_support 

699def random_poisson_v2(shape, lam, dtype=dtypes.float32, seed=None, name=None): 

700 """Draws `shape` samples from each of the given Poisson distribution(s). 

701 

702 `lam` is the rate parameter describing the distribution(s). 

703 

704 Example: 

705 

706 ```python 

707 samples = tf.random.poisson([10], [0.5, 1.5]) 

708 # samples has shape [10, 2], where each slice [:, 0] and [:, 1] represents 

709 # the samples drawn from each distribution 

710 

711 samples = tf.random.poisson([7, 5], [12.2, 3.3]) 

712 # samples has shape [7, 5, 2], where each slice [:, :, 0] and [:, :, 1] 

713 # represents the 7x5 samples drawn from each of the two distributions 

714 ``` 

715 

716 Args: 

717 shape: A 1-D integer Tensor or Python array. The shape of the output samples 

718 to be drawn per "rate"-parameterized distribution. 

719 lam: A Tensor or Python value or N-D array of type `dtype`. 

720 `lam` provides the rate parameter(s) describing the poisson 

721 distribution(s) to sample. 

722 dtype: The type of the output: `float16`, `float32`, `float64`, `int32` or 

723 `int64`. 

724 seed: A Python integer. Used to create a random seed for the distributions. 

725 See 

726 `tf.random.set_seed` 

727 for behavior. 

728 name: Optional name for the operation. 

729 

730 Returns: 

731 samples: a `Tensor` of shape `tf.concat([shape, tf.shape(lam)], axis=0)` 

732 with values of type `dtype`. 

733 """ 

734 with ops.name_scope(name, "random_poisson", [lam, shape]): 

735 shape = ops.convert_to_tensor(shape, name="shape", dtype=dtypes.int32) 

736 seed1, seed2 = random_seed.get_seed(seed) 

737 result = gen_random_ops.random_poisson_v2( 

738 shape, lam, dtype=dtype, seed=seed1, seed2=seed2) 

739 _maybe_set_static_shape_helper(result, shape, lam) 

740 return result