我有非常简单的案例,可以将工作分解并分配给工人。我尝试了here:
中一个非常简单的多处理示例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个cpus)。这是最好/最简单的方法吗?
答案 0 :(得分:13)
我认为您需要在do_calculation
函数中使用numpy.random.seed重新播种随机数生成器。
我的猜测是,在导入模块时,随机数生成器(RNG)会被播种。然后,当您使用多处理时,您使用已经播种的RNG分叉当前进程 - 因此,您的所有进程都为RNG共享相同的种子值,因此它们将生成相同的数字序列。
e.g:
def do_calculation(data):
np.random.seed()
rand=np.random.randint(10)
print data, rand
return data * 2
答案 1 :(得分:0)
此blog post提供了使用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模块时仅创建一次种子。
答案 2 :(得分: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 documentation on this 实际上很有帮助。 See also。