tf.random.set_seed用法

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
)

依赖随机种子的操作实上是从两个种子派生的:全局种子操作级别种子这个设置了全局种子

它与操作级种子的交互如下:

  1. 如果既未设置全局种子也未设置操作种子:此操作使用随机选择的种子
  2. 如果设置了图级别的种子(graph-level seed),但未设置操作种子(operation seed):系统确定性地选择一个操作种子和图级别的种子,以便获得唯一的随机序列。在tensorflow和用户代码的相同版本中,此序列是确定性的。但是,在不同版本中,此序列可能会更改。如果代码依赖特定的种子来工作,则明确指定图级别和操作级别种子
  3. 如果设置了操作种子,但未设置全局种子:使用默认的全局种子指定的操作种子来确定随机序列。
  4. 如果同时设置了全局种子和操作种子将两个种子一起使用以确定随机序列

为了说明用户可见的效果,请考虑以下示例:

如果既未设置全局种子也未设置操作种子,则每次调用随机操作和每次重新运行程序都会得到不同的结果

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]

猜你喜欢

转载自blog.csdn.net/qq_36201400/article/details/108512368