我正在尝试生成 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 .....
.
.
.
原文由 Mehdi Rezaie 发布,翻译遵循 CC BY-SA 4.0 许可协议
在 tensorflow 中,随机操作依赖于两个不同的种子:全局种子,由
tf.set_random_seed
设置,以及操作种子,作为操作的参数提供。您将 在文档中 找到有关它们如何关联的更多详细信息。每个随机操作都有不同的种子,因为每个随机操作都维护自己的内部状态以生成伪随机数。让每个随机生成器保持其自己的状态的原因是为了能够稳健地改变:如果它们共享相同的状态,那么在你的图中的某个地方添加一个新的随机生成器会改变所有其他生成器产生的值,从而违背了使用种子。
现在,为什么我们有这种全局 和 per-op 种子的双重系统?好吧,实际上全局种子不是必需的。它的存在是为了方便:它允许一次将所有随机操作种子设置为不同的和确定的(如果未知)值,而不必详尽地遍历所有这些。
现在,根据文档,当设置了全局种子而不是操作种子时,
更准确地说,提供的种子是在当前图中创建的最后一个操作的 ID。因此,全局播种的随机操作对图中的变化非常敏感,特别是那些在它之前创建的。
例如,
现在如果我们之前创建一个节点,结果会改变:
但是,如果一个节点是在之后创建的,它不会影响操作种子:
显然,就像您的情况一样,如果您生成多个操作,它们将具有不同的种子:
出于好奇,为了验证种子只是图中最后使用的 id 这一事实,您可以将 — 的种子与
gen2
gen1
显然,这不应该通过代码审查。