python - 为什么 numpy 随机种子没有保持固定但 RandomState 在并行运行时是?

标签 python numpy parallel-processing random-seed

我正在使用 joblib 并行运行蒙特卡罗模拟.然而,我注意到虽然我的种子是固定的,但我的结果一直在变化。但是,当我连续运行该过程时,它如我所料保持不变。

下面我实现了一个小例子,模拟具有较高方差的正态分布的均值。

加载库并定义函数

import numpy as np
from joblib import Parallel, delayed

def _estimate_mean():
    np.random.seed(0)
    x = np.random.normal(0, 2, size=100)
    return np.mean(x)

我实现的第一个例子 系列 - 结果都和预期的一样。
tst = [_estimate_mean() for i in range(8)]
In [28]: tst
Out[28]:
[0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897]

第二个例子我实现了并行 :(注意有时手段都一样,有时不一样)
tst = Parallel(n_jobs=-1, backend="threading")(delayed(_estimate_mean)() for i in range(8))

In [26]: tst
Out[26]:
[0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.1640259414956747,
 -0.11846452111932627,
 -0.3935934130918206]

我希望并行运行与固定种子相同。我发现如果我实现 RandomState修复种子似乎可以解决问题:
def _estimate_mean():
    local_state = np.random.RandomState(0)
    x = local_state.normal(0, 2, size=100)
    return np.mean(x)
tst = Parallel(n_jobs=-1, backend="threading")(delayed(_estimate_mean)() for i in range(8))

In [28]: tst
Out[28]:
[0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897,
 0.11961603106897]

What is the difference between using RandomState and just seed when fixing the seeds using numpy.random and why would the latter not reliably work when running in parallel ?



系统信息

操作系统:Windows 10

Python:3.7.3(默认,2019 年 4 月 24 日,15:29:51)[MSC v.1915 64 位 (AMD64)]

NumPy :1.17.2

最佳答案

你得到的结果 numpy.random.*正在发生是因为 竞争条件 . numpy.random.*仅使用一个全局 PRNG,在没有同步的情况下在所有线程之间共享。由于线程同时并行运行,并且它们对这个全局 PRNG 的访问在它们之间不同步,它们都争先恐后地访问 PRNG 状态(因此 PRNG 的状态可能会在其他线程的背后改变)。为每个线程提供自己的 PRNG ( RandomState ) 解决了这个问题,因为在没有同步的情况下,多个线程不再共享任何状态。

由于您使用的是 NumPy 1.17,您应该知道有一个更好的选择:NumPy 1.17 引入了 new random number generation system ;它使用所谓的位生成器,例如 PCG 和随机生成器,例如新的 numpy.random.Generator .

这是 proposal to change the RNG policy 的结果,其中指出 numpy.random.*通常不应再使用函数。这尤其是因为 numpy.random.*在全局状态上运行。

NumPy 文档现在有关于以下方面的详细信息——

  • seeding RNGs in parallel , 和
  • multithreading RNGs ,

  • 在新的RNG系统中。另请参阅“Seed Generation for Noncryptographic PRNGs ”,来自我的一篇文章,其中包含有关 RNG 选择的一般建议。

    关于python - 为什么 numpy 随机种子没有保持固定但 RandomState 在并行运行时是?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59105921/

    相关文章:

    python - 如何使用 python 取 -1 的平方根?

    python - 添加 Django 模型约束?

    Python 多处理进程静默崩溃

    c++ - OpenMP 通过 std::set 使用迭代器

    python - 在 Ubuntu (12.04) 下安装 Numpy 导致 Python ImportError

    parallel-processing - 什么是OpenMP中的“隐式同步”

    python - Django 。没有名为 reportlab.pdfgen 的模块

    python - 获取完整的unicode句子

    python - 在mongodb中保存numpy数组

    python - 计算 python 中重叠滑动窗口中的值