【问题标题】:Python Multiprocessing Numpy Random [duplicate]Python多处理Numpy随机[重复]
【发布时间】:2013-01-08 10:00:24
【问题描述】:

在多处理调用的函数中,numpy ndarray 函数的范围是否不同?这是一个例子:

使用 python 的多处理模块我正在调用这样的函数:

for core in range(cores):
    #target could be f() or g()
    proc = mp.Process(target=f, args=(core))
    jobs.append(proc)
for job in jobs:
    job.start()
for job in jobs:
    job.join()

def f(core):
    x = 0
    x += random.randint(0,10)
    print x

def g(core):
    #Assume an array with 4 columns and n rows
    local = np.copy(globalshared_array[:,core])
    shuffled = np.random.permutation(local)

调用f(core)x 变量是进程本地的,即。它按预期打印一个不同的随机整数。这些永远不会超过 10,表明每个进程中都有 x=0。对吗?

调用 g(core) 并排列数组的副本会返回 4 个完全相同的“混洗”数组。这似乎表明工作副本不是子进程的本地。那是对的吗?如果是这样,除了使用共享内存空间之外,当需要从共享内存空间填充时,是否可以将 ndarray 放在子进程的本地?

编辑:

更改g(core) 以添加随机整数似乎具有预期的效果。数组显示不同的值。 permutation 中一定发生了一些事情,即随机排列列(每个子进程的本地)相同...想法?

def g(core):
    #Assume an array with 4 columns and n rows
    local = np.copy(globalshared_array[:,core])
    local += random.randint(0,10)

编辑二: np.random.shuffle 也表现出相同的行为。数组的内容正在洗牌,但在每个核心上都洗牌到相同的值。

【问题讨论】:

  • 我认为这可能只是随机数生成器 + 线程 = 可能的麻烦(即,你幸运一次又一次没有)。您可能只需要确保分别为每个状态初始化一个随机状态或np.random.RandomState
  • @seberg 我也厌倦了使用np.random.random_integer,但返回的数组在各个进程中是相同的。您是否引用了`np.random.mtrand.RandomState?所以为每个子进程实例化一个随机类,因为它们可能正在实例化一个类或相互覆盖?
  • 不确定它们何时被实例化,但我不确定它们是否不能偶然实例化完全相同(它们可能使用系统时间),或者只是在分叉时复制相同的状态,并且应该再次实例化。
  • 简而言之,至少调用一次np.random.seed()
  • np.random.mtrand.RandomState 表现出同样的问题。文档看起来像该类使用机器时钟。与种子()相同的问题。看来我要么需要插入延迟,要么接受“随机性”。

标签: python numpy multiprocessing


【解决方案1】:

播种随机数组this post 是最有用的。以下g(core) 函数成功为每个核心生成随机排列。

def g(core):
    pid = mp.current_process()._identity[0]
    randst = np.random.mtrand.RandomState(pid)
    randarray = randst.randint(0,100, size=(1,100)

【讨论】:

    【解决方案2】:

    调用 g(core) 并排列数组的副本会返回 4 个完全相同的“混洗”数组。这似乎表明工作副本不是本地子进程。

    这可能表明随机数生成器在每个子进程中被相同地初始化,产生相同的序列。您需要为每个孩子的生成器播种(也许将孩子的进程 id 混入其中)。

    【讨论】:

    • 这进入了 OP 的 cmets。使用 pid 或 randomint(0,1000) 播种不会改变随机解。
    • @Jzl5325 在状态相同时使用随机整数播种是毫无意义的...请尝试使用函数np.random.seed(pid) 或类似函数中的 pid 播种?
    • 我想与子进程共享父进程的 numpy 随机状态。我尝试过使用 Manager,但仍然没有运气。你能看看我的问题here,看看你能不能提供一个解决方案?如果我每次生成随机数时都执行 np.random.seed(None),我仍然可以获得不同的随机数,但这不允许我使用父进程的随机状态,这不是我想要的。非常感谢任何帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 2012-01-20
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    相关资源
    最近更新 更多