22

我有非常简单的案例,可以将要完成的工作分解并分配给工人。我从这里尝试了一个非常简单的多处理示例:

import multiprocessing
import numpy as np
import time

def do_calculation(data):
    rand=np.random.randint(10)
    print data, rand
    time.sleep(rand)
    return data * 2

if __name__ == '__main__':
    pool_size = multiprocessing.cpu_count() * 2
    pool = multiprocessing.Pool(processes=pool_size)

    inputs = list(range(10))
    print 'Input   :', inputs

    pool_outputs = pool.map(do_calculation, inputs)
    print 'Pool    :', pool_outputs

上面的程序产生以下输出:

Input   : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0 7
1 7
2 7
5 7
3 7
4 7
6 7
7 7
8 6
9 6
Pool    : [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

为什么要打印相同的随机数?(我的机器上有 4 个 CPU)。这是最好/最简单的方法吗?

4

3 回答 3

21

我认为您需要在函数中使用numpy.random.seeddo_calculation重新播种随机数生成器。

我的猜测是,当您导入模块时,随机数生成器 (RNG) 会被播种。然后,当您使用多处理时,您将当前进程与已经播种的 RNG 分叉——因此,您的所有进程都为 RNG 共享相同的种子值,因此它们将生成相同的数字序列。

例如:

def do_calculation(data):
    np.random.seed()
    rand=np.random.randint(10)
    print data, rand
    return data * 2
于 2012-10-16T12:55:07.003 回答
2

这篇文提供了使用 numpy.random 和多处理时的好坏做法示例。更重要的是了解何时创建伪随机数生成器 (PRNG) 的种子:

import numpy as np
import pprint
from multiprocessing import Pool

pp = pprint.PrettyPrinter()

def bad_practice(index):
    return np.random.randint(0,10,size=10)

def good_practice(index):
    return np.random.RandomState().randint(0,10,size=10)

p = Pool(5)

pp.pprint("Bad practice: ")
pp.pprint(p.map(bad_practice, range(5)))
pp.pprint("Good practice: ")
pp.pprint(p.map(good_practice, range(5)))

输出:

'Bad practice: '
[array([4, 2, 8, 0, 1, 1, 6, 1, 2, 9]),
 array([4, 2, 8, 0, 1, 1, 6, 1, 2, 9]),
 array([4, 2, 8, 0, 1, 1, 6, 1, 2, 9]),
 array([4, 2, 8, 0, 1, 1, 6, 1, 2, 9]),
 array([4, 2, 8, 0, 1, 1, 6, 1, 2, 9])]
'Good practice: '
[array([8, 9, 4, 5, 1, 0, 8, 1, 5, 4]),
 array([5, 1, 3, 3, 3, 0, 0, 1, 0, 8]),
 array([1, 9, 9, 9, 2, 9, 4, 3, 2, 1]),
 array([4, 3, 6, 2, 6, 1, 2, 9, 5, 2]),
 array([6, 3, 5, 9, 7, 1, 7, 4, 8, 5])]

在好的做法中,每个线程创建一次种子,而在不好的做法中,只在导入 numpy.random 模块时创建一次种子。

于 2019-02-03T19:13:06.037 回答
0

这是我使用的(可能需要更新版本的 NumPy):

import numpy as np
from multiprocessing import Pool

entropy = 42
seed_sequence = np.random.SeedSequence(entropy)

number_processes = 5

seeds = seed_sequence.spawn(number_processes)

def good_practice(seed):
    rng = np.random.default_rng(seed)
    return rng.integers(0,10,size=10)

pool = Pool(number_processes)


print(pool.map(good_practice, seeds))

输出:

[array([4, 9, 5, 9, 2, 8, 3, 3, 5, 9]), 
 array([0, 4, 1, 0, 6, 5, 3, 1, 7, 9]), 
 array([7, 0, 7, 7, 1, 0, 1, 3, 9, 6]), 
 array([8, 7, 9, 9, 1, 7, 4, 0, 5, 2]), 
 array([9, 0, 8, 9, 3, 8, 6, 6, 7, 9])]

有关这方面的NumPy 文档实际上很有帮助。另请参阅

于 2021-05-25T15:49:02.983 回答