在 python 中设置随机种子会干扰多处理
Setting random seed in python disturbs multiprocessing
我观察到在 python 中使用多处理之前设置随机种子会导致奇怪的行为。
在python 3.5.2 中,只使用了2 或3 个内核,使用率很低CPU。
在 python 2.7.13 中,所有请求的核心都以 100% 使用,但代码似乎永远不会完成。当我删除随机种子的初始化时,并行化工作正常。
即使在并行函数中没有明确使用 random,也会发生这种情况。我现在假设种子在进程之间共享,这会阻止 运行 多处理的顺利进行,但是有人可以提供正确的答案吗?
我已经 运行 Linux 上的代码,这里是一个最小的代码示例:
from multiprocessing import Pool
import numpy as np
import random
random.seed = 2018
NB_CPUS = 4
def test(x):
return x**2
pool = Pool(NB_CPUS)
args = [np.random.rand() for _ in range(100000)]
results = pool.map(test, args)
pool.terminate()
results[-5:]
回答有点晚了,但是你通过将 random.seed
function 设置为 int
来破坏事情。你应该改为:
random.seed(2018)
追溯的最后几行提供了应该使这一点显而易见的上下文:
File "/usr/lib64/python2.7/multiprocessing/process.py", line 130, in start
self._popen = Popen(self)
File "/usr/lib64/python2.7/multiprocessing/forking.py", line 125, in __init__
random.seed()
TypeError: 'int' object is not callable
这导致 Pool
继续尝试创建新的工作进程,但由于每次都发生这种情况,因此无法取得进展。
这背后的原因是 multiprocessing
知道它应该 re-seed 分叉时的随机模块,这样子进程就不会共享相同的 RNG 状态。为此,它会尝试调用 random.seed
函数,但您已将其设置为不可调用的 int
--- 因此出现错误!
与此相关的另一个问题是 multiprocessing
不知道 re-seed NumPy RNG,所以下面的代码:
from multiprocessing import Pool
import numpy as np
def test(i):
print(i, np.random.rand())
with Pool(4) as pool:
pool.map(test, range(4))
将导致每个工人打印相同的值。 This issue 已经有一段时间了,但仍然开放。您可以使用 worker initializer
来解决这个问题,例如:
def initfn():
np.random.seed()
with Pool(4, initializer=initfn) as pool:
pool.map(test, range(4))
现在将导致上面的 test
函数打印不同的值。请注意,如果您不进行任何其他工作级别初始化,您甚至可以使用 Pool(4, initializer=np.random.seed)
。
我观察到在 python 中使用多处理之前设置随机种子会导致奇怪的行为。
在python 3.5.2 中,只使用了2 或3 个内核,使用率很低CPU。 在 python 2.7.13 中,所有请求的核心都以 100% 使用,但代码似乎永远不会完成。当我删除随机种子的初始化时,并行化工作正常。
即使在并行函数中没有明确使用 random,也会发生这种情况。我现在假设种子在进程之间共享,这会阻止 运行 多处理的顺利进行,但是有人可以提供正确的答案吗?
我已经 运行 Linux 上的代码,这里是一个最小的代码示例:
from multiprocessing import Pool
import numpy as np
import random
random.seed = 2018
NB_CPUS = 4
def test(x):
return x**2
pool = Pool(NB_CPUS)
args = [np.random.rand() for _ in range(100000)]
results = pool.map(test, args)
pool.terminate()
results[-5:]
回答有点晚了,但是你通过将 random.seed
function 设置为 int
来破坏事情。你应该改为:
random.seed(2018)
追溯的最后几行提供了应该使这一点显而易见的上下文:
File "/usr/lib64/python2.7/multiprocessing/process.py", line 130, in start
self._popen = Popen(self)
File "/usr/lib64/python2.7/multiprocessing/forking.py", line 125, in __init__
random.seed()
TypeError: 'int' object is not callable
这导致 Pool
继续尝试创建新的工作进程,但由于每次都发生这种情况,因此无法取得进展。
这背后的原因是 multiprocessing
知道它应该 re-seed 分叉时的随机模块,这样子进程就不会共享相同的 RNG 状态。为此,它会尝试调用 random.seed
函数,但您已将其设置为不可调用的 int
--- 因此出现错误!
与此相关的另一个问题是 multiprocessing
不知道 re-seed NumPy RNG,所以下面的代码:
from multiprocessing import Pool
import numpy as np
def test(i):
print(i, np.random.rand())
with Pool(4) as pool:
pool.map(test, range(4))
将导致每个工人打印相同的值。 This issue 已经有一段时间了,但仍然开放。您可以使用 worker initializer
来解决这个问题,例如:
def initfn():
np.random.seed()
with Pool(4, initializer=initfn) as pool:
pool.map(test, range(4))
现在将导致上面的 test
函数打印不同的值。请注意,如果您不进行任何其他工作级别初始化,您甚至可以使用 Pool(4, initializer=np.random.seed)
。