tf.random.Generator
Генератор псевдослучайных чисел.
tf.random.Generator(
copy_from=None, state=None, alg=None
)
Пример:
Создание генератора из семян:
g = tf.random.Generator.from_seed(1234)
g.normal(shape=(2, 3))
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[ 0.9356609 , 1.0854305 , -0.93788373],
[-0.5061547 , 1.3169702 , 0.7137579 ]], dtype=float32)>
Создание генератора из недетерминированного состояния:
g = tf.random.Generator.from_non_deterministic_state() g.normal(shape=(2, 3)) <tf.Tensor: shape=(2, 3), dtype=float32, numpy=...>
Все конструкторы позволяют явно выбрать алгоритм генерации псевдослучайных чисел (RNG). Поддерживаемые алгоритмы — "philox" и "threefry". Например:
g = tf.random.Generator.from_seed(123, alg="philox")
g.normal(shape=(2, 3))
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[ 0.8673864 , -0.29899067, -0.9310337 ],
[-1.5828488 , 1.2481191 , -0.6770643 ]], dtype=float32)>
Процессор, графический процессор и TPU с одинаковым алгоритмом и семенами будут генерировать одинаковые целые случайные числа. Результаты с плавающей запятой (например, результат normal) могут иметь небольшие числовые расхождения между различными устройствами.
Этот класс использует tf.Variable для управления своим внутренним состоянием. Каждый раз, когда генерируются случайные числа, состояние генератора изменяется. Например:
g = tf.random.Generator.from_seed(1234) g.state <tf.Variable ... numpy=array([1234, 0, 0])> g.normal(shape=(2, 3)) <...> g.state <tf.Variable ... numpy=array([2770, 0, 0])>
Форма состояния зависит от алгоритма.
Также существует глобальный генератор:
g = tf.random.get_global_generator() g.normal(shape=(2, 3)) <tf.Tensor: shape=(2, 3), dtype=float32, numpy=...>
При создании генератора внутри области tf.distribute.Strategy каждый экземпляр получит различную последовательность случайных чисел.
Например, в этом коде:
strat = tf.distribute.MirroredStrategy(devices=["cpu:0", "cpu:1"])
with strat.scope():
g = tf.random.Generator.from_seed(1)
def f():
return g.normal([])
results = strat.run(f).values
results[0] и results[1] будут иметь разные значения.
Если генератор имеет seed (например, созданный с помощью Generator.from_seed), случайные числа будут определяться этим seed, даже если разные экземпляры получают разные числа. Можно представить случайное число, сгенерированное в экземпляре, как хэш идентификатора экземпляра и "главного" случайного числа, которое может быть общим для всех экземпляров. Таким образом, вся система по-прежнему детерминирована.
(Обратите внимание, что случайные числа в разных экземплярах не коррелированы, даже если они детерминированно определяются одним и тем же seed. Они не коррелированы в том смысле, что независимо от того, какие статистические данные вычислите, никакой заметной корреляции не будет.)
Генераторы можно свободно сохранять и восстанавливать, используя tf.train.Checkpoint. Точка сохранения может быть восстановлена в стратегии распределения с другим количеством экземпляров, чем в исходной стратегии. Если идентификатор экземпляра присутствует как в исходной, так и в новой стратегии распределения, его состояние будет корректно восстановлено (т.е. последовательность случайных чисел с точки восстановления будет такой же, как с точки сохранения), если только экземпляры не разошлись в своих вызовах RNG до сохранения (например, один экземпляр выполнил один вызов RNG, а другой — два). Такой гарантии нет, если генератор сохранен в области стратегии и восстановлен вне любой области стратегии или наоборот.
Когда генератор создается в области tf.distribute.experimental.ParameterServerStrategy, рабочие узлы будут совместно использовать состояние генератора (размещенного на одном из серверов параметров). Таким образом, рабочие узлы по-прежнему будут получать разные потоки случайных чисел, как указано выше. (Это аналогично экземплярам в tf.distribute.MirroredStrategy, последовательно обращающимся к генератору, созданному вне стратегии.) Каждый вызов RNG на рабочем узле потребует обмен с сервером параметров, что может повлиять на производительность. При создании tf.distribute.experimental.ParameterServerStrategy, убедитесь, что аргумент variable_partitioner не будет фрагментировать переменные небольшого размера с формой [2] или [3] (поскольку состояния генераторов не должны фрагментироваться). Способы избежать фрагментации небольших переменных включают установку variable_partitioner на None или на tf.distribute.experimental.partitioners.MinSizePartitioner с достаточно большим значением min_shard_bytes (см. документацию tf.distribute.experimental.ParameterServerStrategy для получения дополнительной информации).
| Args | |
|---|---|
copy_from | генератор, который нужно скопировать. |
state | вектор типа STATE_TYPE, представляющий начальное состояние RNG, длина и семантика которого зависят от алгоритма. Если это переменная, генератор будет использовать ее вместо создания новой переменной. |
alg | алгоритм RNG. Возможные значения — tf.random.Algorithm.PHILOX для алгоритма Philox и tf.random.Algorithm.THREEFRY для алгоритма ThreeFry (см. статью 'Parallel Random Numbers: As Easy as 1, 2, 3' [https://www.thesalmons.org/john/random123/papers/random123sc11.pdf]). Также можно использовать строковые имена "philox" и "threefry". Обратите внимание, что PHILOX гарантирует, что на всех архитектурах (CPU, GPU, XLA и т. д.) будут получаться одни и те же числа (при одинаковом состоянии случайных чисел). |
| Атрибуты | |
|---|---|
algorithm | Идентификатор алгоритма RNG (целое число Python или скалярное целое число Tensor). |
key | Часть "ключ" состояния генератора на основе счетчика. Для алгоритма RNG на основе счетчика, такого как Philox и ThreeFry (как описано в статье 'Parallel Random Numbers: As Easy as 1, 2, 3' [https://www.thesalmons.org/john/random123/papers/random123sc11.pdf]), состояние RNG состоит из двух частей: счетчик и ключ. Вывод генерируется по формуле: output=hash(key, counter), т.е. хэширование счетчика, параметризованного ключом. Два RNG с двумя разными ключами можно рассматривать как генерирующие два независимых потока случайных чисел (поток формируется путем увеличения счетчика). |
state | Внутреннее состояние RNG. |
Методы
binomial
binomial(
shape,
counts,
probs,
dtype=tf.dtypes.int32,
name=None
)
Выводит случайные значения из биномиального распределения.
Сгенерированные значения следуют биномиальному распределению со значениями заданных параметров: количество испытаний и вероятность успеха.
Пример:
counts = [10., 20.] # Probability of success. probs = [0.8] rng = tf.random.Generator.from_seed(seed=234) binomial_samples = rng.binomial(shape=[2], counts=counts, probs=probs) counts = ... # Shape [3, 1, 2] probs = ... # Shape [1, 4, 2] shape = [3, 4, 3, 4, 2] rng = tf.random.Generator.from_seed(seed=1717) # Sample shape will be [3, 4, 3, 4, 2] binomial_samples = rng.binomial(shape=shape, counts=counts, probs=probs)
| Args | |
|---|---|
shape | 1-мерный целочисленный Tensor или Python-массив. Форма тензора вывода. |
counts | Tensor. Количество испытаний в биномиальном распределении. Должно быть совместимо по форме с probs, и совместимо по форме с правыми измерениями shape. |
probs | Tensor. Вероятность успеха в биномиальном распределении. Должно быть совместимо по форме с counts и совместимо по форме с правыми измерениями shape. |
dtype | Тип вывода. По умолчанию: tf.int32 |
name | Имя операции (необязательно). |
| Возвращаемое значение | |
|---|---|
samples | Tensor заданной формы, заполненный случайными биномиальными значениями. Для каждого i, samples[i, ...] — независимое значение из биномиального распределения для counts[i] испытаний с вероятностью успеха probs[i]. |
from_key_counter
@classmethod
from_key_counter(
key, counter, alg
)
Создаёт генератор из ключа и счетчика.
Этот конструктор применяется только для алгоритмов на основе счетчика. Значение "ключ" и "счетчик" см. в методе key.
| Args | |
|---|---|
key | ключ для RNG, скаляр типа STATE_TYPE. |
counter | вектор типа STATE_TYPE, представляющий начальный счетчик для RNG, длина которого зависит от алгоритма. |
alg | алгоритм RNG. Если None, он будет выбран автоматически. Возможные значения см. в __init__. |
| Возвращаемое значение | |
|---|---|
| Новый генератор. |
from_non_deterministic_state
@classmethod
from_non_deterministic_state(
alg=None
)
Создает генератор, не детерминированно инициализируя его состояние.
Источник недетерминизма будет зависеть от платформы и времени.
| Args | |
|---|---|
alg | (необязательно) алгоритм RNG. Если None, он будет выбран автоматически. Возможные значения см. в __init__. |
| Возвращаемое значение | |
|---|---|
| Новый генератор. |
from_seed
@classmethod
from_seed(
seed, alg=None
)
Создает генератор из seed.
Seed — это 1024-битовое целое без знака, представленное либо целым числом Python, либо вектором целых чисел. Seeds, длина которых меньше 1024 бит, будут дополнены. Дополнение, внутренняя структура seed и способ преобразования seed в состояние — всё не определено (не указано). Единственное семантическое требование к seed — это то, что два разных seed, скорее всего, приведут к двум независимым генераторам (но никакой гарантии нет).
| Аргументы | |
|---|---|
seed | семя для генератора псевдослучайных чисел. |
alg | (необязательно) алгоритм генератора псевдослучайных чисел. Если None, он будет выбран автоматически. Смотрите __init__ для возможных значений. |
| Возвращаемое значение | |
|---|---|
| Новый генератор. |
from_state
@classmethod
from_state(
state, alg
)
Создает генератор из состояния.
См. __init__ для описания state и alg.
| Аргументы | |
|---|---|
state | новое состояние. |
alg | алгоритм генератора псевдослучайных чисел. |
| Возвращаемое значение | |
|---|---|
| Новый генератор. |
make_seeds
make_seeds(
count=1
)
Генерирует семена для бессеменных операций с случайными числами.
Например:
seeds = get_global_generator().make_seeds(count=10) for i in range(10): seed = seeds[:, i] numbers = stateless_random_normal(shape=[2, 3], seed=seed) ...
| Аргументы | |
|---|---|
count | количество пар семян (обратите внимание, что бессеменные операции с случайными числами требуют пару семян для вызова). |
| Возвращаемое значение | |
|---|---|
| Массив формы [2, count] и типа int64. |
normal
normal(
shape,
mean=0.0,
stddev=1.0,
dtype=tf.dtypes.float32,
name=None
)
Выводит случайные значения из нормального распределения.
| Аргументы | |
|---|---|
shape | 1-мерный целочисленный тензор или Python-массив. Форма выходного тензора. |
mean | 0-мерный тензор или Python-значение типа dtype. Математическое ожидание нормального распределения. |
stddev | 0-мерный тензор или Python-значение типа dtype. Стандартное отклонение нормального распределения. |
dtype | Тип выходного значения. |
name | Имя операции (необязательно). |
| Возвращаемое значение | |
|---|---|
| Тензор заданной формы, заполненный случайными значениями из нормального распределения. |
reset
reset(
state
)
Сбрасывает генератор новым состоянием.
См. __init__ для определения "состояния".
| Аргументы | |
|---|---|
state | новое состояние. |
reset_from_key_counter
reset_from_key_counter(
key, counter
)
Сбрасывает генератор новой парой "ключ-счетчик".
См. from_key_counter для определения "ключа" и "счетчика".
| Аргументы | |
|---|---|
key | новый ключ. |
counter | новый счетчик. |
reset_from_seed
reset_from_seed(
seed
)
Сбрасывает генератор новым семением.
См. from_seed для определения "семени".
| Аргументы | |
|---|---|
seed | новое семя. |
skip
skip(
delta
)
Перемещает счетчик генератора на основе счетчика.
| Аргументы | |
|---|---|
delta | величина перемещения. Состояние генератора после skip(n) будет таким же, как после normal([n]) (или любого другого распределения). Фактическое приращение к счетчику является неопределенным деталью реализации. |
| Возвращаемое значение | |
|---|---|
Тензор типа int64. |
split
split(
count=1
)
Возвращает список независимых объектов генераторов.
Два генератора независимы друг от друга в том смысле, что потоки случайных чисел, которые они генерируют, не имеют статистически обнаруживаемых корреляций. Новые генераторы также независимы от старого. Состояние старого генератора будет изменено (как и другие методы генерации случайных чисел), поэтому два вызова split вернут разные новые генераторы.
Например:
gens = get_global_generator().split(count=10) for gen in gens: numbers = gen.normal(shape=[2, 3]) # ... gens2 = get_global_generator().split(count=10) # gens2 will be different from gens
Новые генераторы будут размещены на текущем устройстве (возможно, отличном от устройства старого генератора), например:
with tf.device("/device:CPU:0"):
gen = Generator(seed=1234) # gen is on CPU
with tf.device("/device:GPU:0"):
gens = gen.split(count=10) # gens are on GPU
| Аргументы | |
|---|---|
count | количество возвращаемых генераторов. |
| Возвращаемое значение | |
|---|---|
Список (длина count) объектов генераторов, независимых друг от друга. Новые генераторы имеют тот же алгоритм генерации псевдослучайных чисел, что и старый. |
truncated_normal
truncated_normal(
shape,
mean=0.0,
stddev=1.0,
dtype=tf.dtypes.float32,
name=None
)
Выводит случайные значения из усеченного нормального распределения.
Сгенерированные значения следуют нормальному распределению с указанным средним значением и стандартным отклонением, за исключением того, что значения, абсолютное значение которых больше, чем 2 стандартных отклонения от среднего значения, отбрасываются и перебираются.
| Аргументы | |
|---|---|
shape | 1-мерный целочисленный тензор или Python-массив. Форма выходного тензора. |
mean | 0-мерный тензор или Python-значение типа dtype. Среднее значение усеченного нормального распределения. |
stddev | 0-мерный тензор или Python-значение типа dtype. Стандартное отклонение нормального распределения до усечения. |
dtype | Тип выходного значения. |
name | Имя операции (необязательно). |
| Возвращаемое значение | |
|---|---|
| Тензор заданной формы, заполненный случайными усечёнными нормальными значениями. |
uniform
uniform(
shape,
minval=0,
maxval=None,
dtype=tf.dtypes.float32,
name=None
)
Выводит случайные значения из равномерного распределения.
Сгенерированные значения следуют равномерному распределению в диапазоне [minval, maxval). Нижняя граница minval включена в диапазон, а верхняя граница maxval исключена. (Для чисел с плавающей запятой, особенно для типов с малой точностью, таких как bfloat16, из-за округления, результат иногда может включать maxval.)
Для чисел с плавающей точкой, по умолчанию диапазон [0, 1). Для целых чисел, по крайней мере, maxval должны быть явно указаны.
В целочисленном случае случайные целые числа незначительно смещены, если maxval - minval не является точной степенью двойки. Смещение невелико для значений maxval - minval значительно меньше диапазона выходного значения (либо 2**32 либо 2**64).
Для случайных целых чисел полного диапазона передайте minval=None и maxval=None с целочисленным dtype (для целочисленных типов данных, minval и maxval должны быть оба None или оба не None).
| Аргументы | |
|---|---|
shape | Целочисленный тензор 1-D или массив Python. Форма выходного тензора. |
minval | Тензор или Python-значение типа dtype, совместимое по трансляции с shape (для целочисленных типов трансляция не поддерживается, поэтому должно быть скалярное значение). Нижняя граница (включая) диапазона случайных значений для генерации. Для генерации случайных целых чисел в полном диапазоне передайте None. По умолчанию 0. |
maxval | Тензор или Python-значение типа dtype, совместимое по трансляции с shape (для целочисленных типов трансляция не поддерживается, поэтому должно быть скалярное значение). Верхняя граница (исключая) диапазона случайных значений для генерации. Для генерации случайных целых чисел в полном диапазоне передайте None. По умолчанию 1, если dtype с плавающей точкой. |
dtype | Тип выходного значения. |
name | Имя операции (необязательно). |
| Возвращаемое значение | |
|---|---|
| Тензор указанной формы, заполненный случайными значениями равномерного распределения. |
| Исключения | |
|---|---|
ValueError | Если dtype целочисленное, а maxval не указано. |
uniform_full_int
uniform_full_int(
shape,
dtype=tf.dtypes.uint64,
name=None
)
Равномерное распределение по всему диапазону целочисленного типа.
Этот метод эквивалентен установке minval и maxval на None в методе uniform.
| Аргументы | |
|---|---|
shape | форма выходного значения. |
dtype | (необязательно) целочисленный тип, по умолчанию uint64. |
name | (необязательно) имя узла. |
| Возвращаемое значение | |
|---|---|
| Тензор случайных чисел требуемой формы. |
© 2022 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 4.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/random/Generator