python - Numpy:随机种子和多线程导致不同的结果

标签 python multithreading numpy random thread-safety

在 python 3.7、numpy 1.17.3 上测试:

看起来,当使用固定种子和多线程时,使用 numpy 生成随机数并不能提供一致的结果。 scipy 没有提出这个问题。以下代码片段显示了问题:

import numpy as np
from scipy.stats import nbinom 

from concurrent.futures import ThreadPoolExecutor, as_completed


def load_data_np():
    np.random.seed(0)
    return np.random.negative_binomial(5, 0.3, size=2)
def load_data_scipy():
    return nbinom.rvs(5, 0.3, size=2, random_state=0)

因此,这两种方法应该始终生成相同的数字。 但是当在线程循环中生成数据时......

with ThreadPoolExecutor() as executor:
   futures = list(
       (executor.submit(load_data_np)
        for i in range(1000))
   )
   print(np.diff([future.result() for future in as_completed(futures)]))

可以在 numpy 的输出中找到这样的值:

...
 [  4]
 [ -3]
 [-15]
 [ -3]
 [  5]
 [ -6]
 [  0]
 [  6]
 [  1]
 [-13]
 [ -7]
 [  3]
 [  6]
 [ -2]
 [ -1]
 [-11]
 [  3]
...

这必定意味着,在 2 个样本(大小=2)的后续计算之间,随机种子必须已由另一个线程重置,这会导致其他线程的 rng 计数失效。 只是将其与 scipy 进行比较:

with ThreadPoolExecutor(max_workers=cpu_count()) as executor:
    futures = list(
        (executor.submit(load_data_scipy)
         for i in range(1000))
    )
    print(np.diff([future.result() for future in as_completed(futures)]))

每次迭代都会产生相同的值

...
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
...

那么在 numpy 中具有固定种子的线程安全 rng 的正确方法是什么?谷歌搜索这个问题让我回到了 np.random.seed。

干杯, 迈克尔

最佳答案

我修改了您的 load_data_np 方法,使其不使用 np.random.seed

正如我在其他一些文章中发现的那样 SO thread seed 已知不是线程安全的,建议使用您自己的 RandomState 实例。

def load_data_np():
    rs = np.random.RandomState(0)
    return rs.negative_binomial(5, 0.3, size=2)

现在的输出看起来符合预期

...
 [-11]
 [-11]
 [-11]
 [-11]
 [-11]
...

这应该有帮助。

关于python - Numpy:随机种子和多线程导致不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58875076/

相关文章:

python - start_command()缺少1个位置参数?

C# 秒表显示不正确的时间

Java:线程在所有类都没有 public void run() 的情况下工作?

python - 正弦计算比余弦慢几个数量级

python - TypeError : object. __new__(int) 不安全,使用 int.__new__()

python - pandas 在每个组中找到满足特定条件的行的索引并为这些行分配值

Python Markdown nl2br 扩展

c++ - 是否需要使用互斥锁来锁定 thread_local 变量?

python - Numpy:高级索引的转置结果

python - Scikit 学习 : Randomized Logistic Regression gives ValueError: output array is read-only