gpt4 book ai didi

python - 使用 tf.set_random_seed 在 Tensorflow 中可重现结果

转载 作者:太空狗 更新时间:2023-10-29 20:41:26 25 4
gpt4 key购买 nike

我正在尝试生成 N 组独立的随机数。我有一个简单的代码,它显示了 3 组 10 个随机数的问题。我注意到即使我使用 tf.set_random_seed 设置种子,不同运行的结果看起来也不一样。非常感谢任何帮助或评论。

(py3p6) bash-3.2$ cat test.py 
import tensorflow as tf
for i in range(3):
tf.set_random_seed(1234)
generate = tf.random_uniform((10,), 0, 10)
with tf.Session() as sess:
b = sess.run(generate)
print(b)

这是代码的输出:

# output :
[9.604688 5.811516 6.4159 9.621765 0.5434954 4.1893444 5.8865128
7.9785547 8.296125 8.388672 ]
[8.559105 3.2390785 6.447526 8.316823 1.6297233 1.4103293 2.647568
2.954973 6.5975866 7.494894 ]
[2.0277488 6.6134906 0.7579422 4.6359386 6.97507 3.3192968 2.866236
2.2205782 6.7940736 7.2391043]

我想要类似的东西

[9.604688  5.811516  6.4159    9.621765  0.5434954 4.1893444 5.8865128
7.9785547 8.296125 8.388672 ]
[9.604688 5.811516 6.4159 9.621765 0.5434954 4.1893444 5.8865128
7.9785547 8.296125 8.388672 ]
[9.604688 5.811516 6.4159 9.621765 0.5434954 4.1893444 5.8865128
7.9785547 8.296125 8.388672 ]

更新 1: 事实上,我将种子初始值设定项放在 for 循环中的原因是因为我想对它们进行不同的设置(例如,将其视为不同的 MCMC 运行)。这是我完成这项工作的代码,但我不确定它是否有效。基本上我在 0 和 2^32-1 之间生成几个随机种子,并在每次运行中更改种子。非常感谢任何有助于提高内存/RAM 效率的帮助或评论。

import numpy as np
import tensorflow as tf
global_seed = 42
N_chains = 5
np.random.seed(global_seed)
seeds = np.random.randint(0, 4294967295, size=N_chains)

for i in range(N_chains):
tf.set_random_seed(seeds[i])
.... some stuff ....
kernel_initializer = tf.random_normal_initializer(seed=seeds[i])
.... some stuff
with tf.Session() as sess:
.... some stuff .....
.
.
.

最佳答案

在 tensorflow 中,随机操作依赖于两个不同的种子:全局种子,由 tf.set_random_seed 设置,以及操作种子,作为操作的参数提供。您会找到有关它们如何关联的更多详细信息 in the docs .

每个随机操作都有不同的种子,因为每个随机操作都维护自己的内部状态以生成伪随机数。让每个随机生成器保持其自己的状态的原因是为了能够稳健地改变:如果它们共享相同的状态,那么在你的图中的某个地方添加一个新的随机生成器会改变所有其他生成器产生的值,从而违背了使用种子。

现在,为什么我们有这种全局每个操作种子的双重系统?好吧,实际上全局种子不是必需的。它的存在是为了方便:它允许一次将所有随机操作种子设置为不同的和确定的(如果未知)值,而不必详尽地遍历所有这些。

根据文档,现在设置全局种子而不是操作种子时,

The system deterministically picks an operation seed in conjunction with the graph-level seed so that it gets a unique random sequence.

更准确地说,提供的种子是在当前图中创建的最后一个操作的 ID。因此,全局播种的随机操作对图中的变化极其敏感,尤其是那些在其自身之前创建的。

例如,

import tensorflow as tf
tf.set_random_seed(1234)
generate = tf.random_uniform(())
with tf.Session() as sess:
print(generate.eval())
# 0.96046877

现在如果我们之前创建一个节点,结果会改变:

import tensorflow as tf
tf.set_random_seed(1234)
tf.zeros(()) # new op added before
generate = tf.random_uniform(())
with tf.Session() as sess:
print(generate.eval())
# 0.29252338

但是,如果一个节点是在之后创建的,它不会影响操作种子:

import tensorflow as tf
tf.set_random_seed(1234)
generate = tf.random_uniform(())
tf.zeros(()) # new op added after
with tf.Session() as sess:
print(generate.eval())
# 0.96046877

显然,对于您的情况,如果您生成多个操作,它们将具有不同的种子:

import tensorflow as tf
tf.set_random_seed(1234)
gen1 = tf.random_uniform(())
gen2 = tf.random_uniform(())
with tf.Session() as sess:
print(gen1.eval())
print(gen2.eval())
# 0.96046877
# 0.85591054

出于好奇,为了验证种子只是图中最后使用的 id 这一事实,您可以将 gen2 的种子与 gen1 对齐

import tensorflow as tf
tf.set_random_seed(1234)
gen1 = tf.random_uniform(())
# 4 operations seems to be created after seed has been picked
seed = tf.get_default_graph()._last_id - 4
gen2 = tf.random_uniform((), seed=seed)
with tf.Session() as sess:
print(gen1.eval())
print(gen2.eval())
# 0.96046877
# 0.96046877

很明显,这不应该通过代码审查。

关于python - 使用 tf.set_random_seed 在 Tensorflow 中可重现结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51249811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com