tf.random.set_seed
Устанавливает глобальное семя случайных чисел.
tf.random.set_seed(
seed
)
Операции, которые полагаются на семя случайных чисел, фактически получают его из двух семян: глобального и на уровне операции. Это устанавливает глобальное семя.
Взаимодействие с операциями на уровне операции таково:
- Если не задано ни глобальное семя, ни семя операции: для этой операции используется случайное семя.
- Если задано глобальное семя, но не задано семя операции: система детерминированно выбирает семя операции в сочетании с глобальным семенем, чтобы получить уникальную последовательность случайных чисел. В пределах одной версии TensorFlow и кода пользователя эта последовательность детерминирована. Однако в разных версиях эта последовательность может измениться. Если код зависит от конкретных семян для работы, явно укажите глобальное и операционное семена.
- Если задано семя операции, но не задано глобальное семя: для определения последовательности случайных чисел используются значение по умолчанию для глобального семени и указанное семя операции.
- Если заданы как глобальное, так и операционное семена: оба семени используются совместно для определения последовательности случайных чисел.
Для иллюстрации видимых пользователю эффектов, рассмотрим эти примеры:
Если ни глобальное семя, ни семя операции не заданы, мы получаем разные результаты для каждого вызова случайной операции и каждого повторного запуска программы:
print(tf.random.uniform([1])) # generates 'A1' print(tf.random.uniform([1])) # generates 'A2'
(теперь закройте программу и запустите ее снова)
print(tf.random.uniform([1])) # generates 'A3' print(tf.random.uniform([1])) # generates 'A4'
Если глобальное семя установлено, но семя операции не установлено, мы получаем разные результаты для каждого вызова случайной операции, но одну и ту же последовательность для каждого повторного запуска программы:
tf.random.set_seed(1234) print(tf.random.uniform([1])) # generates 'A1' print(tf.random.uniform([1])) # generates 'A2'
(теперь закройте программу и запустите ее снова)
tf.random.set_seed(1234) print(tf.random.uniform([1])) # generates 'A1' print(tf.random.uniform([1])) # generates 'A2'
Причина, по которой мы получаем «A2», а не «A1», при втором вызове tf.random.uniform выше, заключается в том, что второй вызов использует другое семя операции.
Обратите внимание, что tf.function действует как повторный запуск программы в этом случае. Когда глобальное семя задано, но семена операций не заданы, последовательность случайных чисел одинакова для каждого tf.function. Например:
tf.random.set_seed(1234) @tf.function def f(): a = tf.random.uniform([1]) b = tf.random.uniform([1]) return a, b @tf.function def g(): a = tf.random.uniform([1]) b = tf.random.uniform([1]) return a, b print(f()) # prints '(A1, A2)' print(g()) # prints '(A1, A2)'
Если семя операции задано, мы получаем разные результаты для каждого вызова случайной операции, но одну и ту же последовательность для каждого повторного запуска программы:
print(tf.random.uniform([1], seed=1)) # generates 'A1' print(tf.random.uniform([1], seed=1)) # generates 'A2'
(теперь закройте программу и запустите ее снова)
print(tf.random.uniform([1], seed=1)) # generates 'A1' print(tf.random.uniform([1], seed=1)) # generates 'A2'
Причина, по которой мы получаем «A2», а не «A1», при втором вызове tf.random.uniform выше, заключается в том, что один и тот же ядро tf.random.uniform (т.е. внутреннее представление) используется TensorFlow для всех вызовов с одинаковыми аргументами, и ядро поддерживает внутренний счётчик, который увеличивается каждый раз при выполнении, генерируя разные результаты.
Вызов tf.random.set_seed сбросит все такие счётчики:
tf.random.set_seed(1234) print(tf.random.uniform([1], seed=1)) # generates 'A1' print(tf.random.uniform([1], seed=1)) # generates 'A2' tf.random.set_seed(1234) print(tf.random.uniform([1], seed=1)) # generates 'A1' print(tf.random.uniform([1], seed=1)) # generates 'A2'
Когда несколько идентичных случайных операций заключены в tf.function, их поведение меняется, поскольку операции больше не разделяют один и тот же счётчик. Например:
@tf.function def foo(): a = tf.random.uniform([1], seed=1) b = tf.random.uniform([1], seed=1) return a, b print(foo()) # prints '(A1, A1)' print(foo()) # prints '(A2, A2)' @tf.function def bar(): a = tf.random.uniform([1]) b = tf.random.uniform([1]) return a, b print(bar()) # prints '(A1, A2)' print(bar()) # prints '(A3, A4)'
Второй вызов foo возвращает «(A2, A2)», а не «(A1, A1)», потому что tf.random.uniform поддерживает внутренний счётчик. Если вы хотите, чтобы foo возвращал «(A1, A1)» каждый раз, используйте бессостоятельные случайные операции, такие как tf.random.stateless_uniform. Также см. tf.random.experimental.Generator для нового набора состоятельных случайных операций, которые используют внешние переменные для управления своим состоянием.
| Args | |
|---|---|
seed | целое число. |
© 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/set_seed