tf.random.set_seed:设置全局随机种子。
上面写法是tensorflow2.0的写法,如果是tensorflow1.0则为:set_random_seed()
#tensorflow2.0
tf.random.set_seed(
seed
)
#tensorflow1.0
tf.set_random_seed(
seed
)
依赖随机种子的操作实上是从两个种子派生的:全局种子和操作级别种子。这个设置了全局种子。
它与操作级种子的交互如下:
- 如果既未设置全局种子也未设置操作种子:此操作使用随机选择的种子。
- 如果设置了图级别的种子(graph-level seed),但未设置操作种子(operation seed):系统确定性地选择一个操作种子和图级别的种子,以便获得唯一的随机序列。在tensorflow和用户代码的相同版本中,此序列是确定性的。但是,在不同版本中,此序列可能会更改。如果代码依赖特定的种子来工作,则明确指定图级别和操作级别种子。
- 如果设置了操作种子,但未设置全局种子:使用默认的全局种子和指定的操作种子来确定随机序列。
- 如果同时设置了全局种子和操作种子:将两个种子一起使用以确定随机序列。
为了说明用户可见的效果,请考虑以下示例:
如果既未设置全局种子也未设置操作种子,则每次调用随机操作和每次重新运行程序都会得到不同的结果:
import tensorflow as tf
a = tf.random.uniform([1])
print(a) # generates 'A1'
print(a) # generates 'A2'
with tf.Session() as sess:
print(a) # generates 'A1'
print(a) # generates 'A2'
print(sess.run(a))
print(sess.run(a))
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# [0.5243385]
# [0.07725751]
(现在关闭程序,然后再次运行)
import tensorflow as tf
a = tf.random.uniform([1])
print(a) # generates 'A1'
print(a) # generates 'A2'
with tf.Session() as sess:
print(a) # generates 'A1'
print(a) # generates 'A2'
print(sess.run(a))
print(sess.run(a))
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# [0.988395]
# [0.30105543]
如果设置了全局种子,但未设置操作种子,则每次对随机操作的调用都会得到不同的结果,但是对于程序的每次重新运行,其结果都是相同的:
import tensorflow as tf
tf.set_random_seed(1234) # 全局种子
a = tf.random.uniform([1])
print(a) # generates 'A1'
print(a) # generates 'A2'
with tf.Session() as sess:
print(a) # generates 'A1'
print(a) # generates 'A2'
print(sess.run(a))
print(sess.run(a))
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# [0.96046877]
# [0.8362156]
(现在关闭程序,然后再次运行)
import tensorflow as tf
tf.set_random_seed(1234) # 全局种子
a = tf.random.uniform([1])
print(a) # generates 'A1'
print(a) # generates 'A2'
with tf.Session() as sess:
print(a) # generates 'A1'
print(a) # generates 'A2'
print(sess.run(a))
print(sess.run(a))
print(sess.run(a))
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# Tensor("random_uniform:0", shape=(1,), dtype=float32)
# [0.96046877]
# [0.8362156]
之所以在上述tf.random.uniform
的第二次调用中获得“ A2”而不是“ A1”,是因为第二次调用使用了不同的操作种子。
请注意,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'
tf.random.uniform
的第二次调用中得到'A2'而不是'A1'的原因是因为TensorFlow使用相同的tf.random.uniform
内核(即内部表示形式)对其所有的调用使用相同的参数,并且内核维护一个内部计数器,即每次执行时递增,产生不同的结果。
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)' 这里我认为应该是prints '(A1, A2)'
print(foo()) # prints '(A2, A2)' 这里我认为应该是prints '(A1, 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 | 整数。 |
tf.compat.v1.set_random_seed(tensorflow1.x)用法:
要跨会话生成不同的序列,请既不设置图级种子,也不设置操作级种子:
import tensorflow as tf
a = tf.random.uniform([1])
b = tf.random.normal([1])
print("Session 1")
with tf.compat.v1.Session() as sess1:
print(sess1.run(a)) # generates 'A1'
print(sess1.run(a)) # generates 'A2'
print(sess1.run(b)) # generates 'B1'
print(sess1.run(b)) # generates 'B2'
print("Session 2")
with tf.compat.v1.Session() as sess2:
print(sess2.run(a)) # generates 'A3'
print(sess2.run(a)) # generates 'A4'
print(sess2.run(b)) # generates 'B3'
print(sess2.run(b)) # generates 'B4'
# 输出结果:会输出不同的值
# Session 1
# [0.8852068]
# [0.8638005]
# [1.2372621]
# [0.36395615]
# Session 2
# [0.49982667]
# [0.95483243]
# [0.03915504]
# [-0.04923742]
要为跨会话的操作生成相同的可重复序列,请为操作设置种子:
import tensorflow as tf
a = tf.random.uniform([1], seed=1)
b = tf.random.normal([1])
# 重复使用同一图运行此块将为“ a”生成相同的值序列,但为“ b”生成不同的值序列。
print("Session 1")
with tf.compat.v1.Session() as sess1:
print(sess1.run(a)) # generates 'A1'
print(sess1.run(a)) # generates 'A2'
print(sess1.run(b)) # generates 'B1'
print(sess1.run(b)) # generates 'B2'
print("Session 2")
with tf.compat.v1.Session() as sess2:
print(sess2.run(a)) # generates 'A1'
print(sess2.run(a)) # generates 'A2'
print(sess2.run(b)) # generates 'B3'
print(sess2.run(b)) # generates 'B4'
# Session 1
# [0.2390374]
# [0.22267115]
# [0.9864384]
# [-0.00564655]
# Session 2
# [0.2390374]
# [0.22267115]
# [-1.6779417]
# [0.20480973]
为了使所有操作生成的随机序列在会话之间可重复,请设置一个图级种子:
import tensorflow as tf
tf.compat.v1.random.set_random_seed(1234)
a = tf.random.uniform([1])
b = tf.random.normal([1])
# Repeatedly running this block with the same graph will generate the same
# sequences of 'a' and 'b'.
print("Session 1")
with tf.compat.v1.Session() as sess1:
print(sess1.run(a)) # generates 'A1'
print(sess1.run(a)) # generates 'A2'
print(sess1.run(b)) # generates 'B1'
print(sess1.run(b)) # generates 'B2'
print("Session 2")
with tf.compat.v1.Session() as sess2:
print(sess2.run(a)) # generates 'A1'
print(sess2.run(a)) # generates 'A2'
print(sess2.run(b)) # generates 'B1'
print(sess2.run(b)) # generates 'B2'
# Session 1
# [0.96046877]
# [0.8362156]
# [0.49875996]
# [0.54880583]
# Session 2
# [0.96046877]
# [0.8362156]
# [0.49875996]
# [0.54880583]