为啥 numpy.random 和 multiprocessing 不能很好玩? [复制]

Posted

技术标签:

【中文标题】为啥 numpy.random 和 multiprocessing 不能很好玩? [复制]【英文标题】:Why doesn't numpy.random and multiprocessing play nice? [duplicate]为什么 numpy.random 和 multiprocessing 不能很好玩? [复制] 【发布时间】:2014-08-12 07:05:57 【问题描述】:

我有一个随机游走功能,它使用numpy.random 来执行随机步骤。 walk 函数本身就可以正常工作。同时,它在大多数情况下都按预期工作,但是与multiprocessing 结合使用时,它会失败。 为什么multiprocessing 弄错了?

import numpy as np

def walk(x, n=100, box=.5, delta=.2):
    "perform a random walk"
    w = np.cumsum(x + np.random.uniform(-delta,delta,n))
    w = np.where(abs(w) > box)[0]
    return w[0] if len(w) else n

N = 10

# run N trials, all starting from x=0
pwalk = np.vectorize(walk)
print pwalk(np.zeros(N))

# run again, using list comprehension instead of ufunc
print [walk(0) for i in range(N)]

# run again, using multiprocessing's map
import multiprocessing as mp
p = mp.Pool()
print p.map(walk, [0]*N)

结果,通常类似于...

[47 16 72  8 15  4 38 52 12 41]
[7, 45, 25, 13, 16, 19, 12, 30, 23, 4]
[3, 3, 3, 3, 3, 3, 3, 14, 3, 14]

前两种方法显然显示出随机性,而后一种则没有。 怎么回事,以至于multiprocessing 搞错了?

如果您添加了 sleep,所以它是 sleepwalk 并且有明显的延迟,multiprocessing 仍然会出错。

但是,如果您将调用 np.random.uniform 替换为像 [(random.random()-.5) for i in range(n)] 这样的非数组方法,那么它会按预期工作。

那么为什么numpy.randommultiprocessing 不能很好玩呢?

【问题讨论】:

我的猜测是 numpy 每次初始化时都会为其随机数生成器播种相同的值,因此所有子进程都在随机图上的同一点上,并将生成相同的一组随机数。尝试调用 numpy.random.seed 并传递一些值,这些值在步行开始时会因非确定性步行(例如当前系统时间)的调用而异。 也许吧,但我希望最后一行都是相同的……但事实并非如此。 另见here 嗯……有趣。而且似乎已经被问过了。哎呀。 @aruisdante:你基本上回答了我的问题......不是我该怎么做,而是它为什么要这样做......所以如果可以的话,我会给你检查。 【参考方案1】:

发生了什么,导致多处理不正确?

您需要在每个进程中reseed 以确保伪随机流彼此独立。

我使用os.urandom 来生成种子。

【讨论】:

np.random.seed(int.from_bytes(os.urandom(4), byteorder='little')) 在 python 3 中。

以上是关于为啥 numpy.random 和 multiprocessing 不能很好玩? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

numpy.random.randn()和numpy.random.rand()

Python 中 numpy.random.rand 与 numpy.random.randn 之间的区别

Python中numpy.random和random.random的区别

numpy.random.choice和random.choice的输入参数有区别吗?

numpy.random

numpy.random 与 numpy.random.Generate 有啥区别