If you call TensorFlow’s random options (e.g., tf.random.uniform
) inside a TF graph function (e.g., @tf.function
) and pass an op-level seed, you won’t get a reproducible sequence of varied values as you might expect. Instead, every seeded call will return the exact same number each time.
If you want to produce a true reproducible sequence of random numbers (different draws that are nevertheless identical across program runs), use TensorFlow’s global RNG (Random Number Generator) seed via tf.random.set_seed()
.
See the following example:
import tensorflow as tf
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], seed=1)
b = tf.random.uniform([1], seed=1)
return a, b
def h():
a = tf.random.uniform([1], seed=1)
b = tf.random.uniform([1], seed=1)
return a, b
print(f()) # prints '(A1, A2)' ✅ Different results
print(g()) # prints '(A1, A1)' ❌ YOU WILL GET THE SAME RESULTS !!!
print(h()) # prints '(A1, A2)' ✅ Different results
不要在 TensorFlow 的图函数中使用随机数种子!
“图函数”(Graph Function)是 TensorFlow 在“图模式”(Graph Mode)下执行的函数形式。图函数包括:
- 使用
@tf.function
装饰的 Python 函数, - 一些默认会运行在图模式下的函数,比如
kera.Model
类的train_step()
方法。
在
@tf.function
下,带有seed=
的随机操作会被编译成“无状态(stateless)随机 op”,也就是说每次执行图的时候,它们并不维护一个内部的、自增的随机状态,而是直接把你给的那个固定种子当作“钥匙”去算出一组伪随机值。有状态 vs. 无状态
from ChatGPT 老师
- 有状态随机 op(比如不带
seed
的tf.random.uniform
):它会在图里维护一个全局的 RNG 状态,每次调用都会推进这个状态,产出“序列化”的随机数。(可以通过tf.random.set_seed()
进行全局设置)- 无状态随机 op(带
seed
的,或底层的stateless_*
):它每次都只看“输入的种子”,不关心先前调用过什么,于是同一个种子 → 同一组输出。