gpt4 book ai didi

python - 为 concurrent.futures.ProcessPoolExecutor 播种 numpy.random 的 default_rng 和 SeedSequence 对象

转载 作者:行者123 更新时间:2023-12-04 13:55:42 27 4
gpt4 key购买 nike

我正在学习为 Python 3.6 设置 NumPy 1.19 版伪随机数生成器的种子 concurrent.futures.ProcessPoolExecutor分析。阅读 NumPy 关于 Random sampling 的文档后和 Parallel Random Number Generation ,我写了以下脚本来评估我的理解。
我的目标:我想确保每个并发进程使用相同的种子来启动随机进程。
我从结果中学到了什么?

  • (a) 使用全局种子,(b) 预定义 numpy.random.default_rngnumpy.random.SeedSequence在将种子传递给并发进程之前使用种子和 (c) 将种子作为参数传递给并发进程给出相同的结果并确保每个并发进程使用相同的种子来启动随机进程。也就是说,不需要为每个并发进程重新创建一个 BitGenerator。
  • 使用种子 numpy.random.SeedSequence() 的衍生子种子object 不能确保每个并发进程使用相同的种子来启动随机进程。 spawn()的工作SeedSequence()的方法目的是确保使用 BitGenerator 结果的不同部分以避免重复?

  • 问题:我的结论正确吗?
    测试脚本:
    import numpy as np
    from numpy.random import default_rng, SeedSequence
    import concurrent.futures as cf

    def random( loop ):
    rg = default_rng()
    return loop, [rg.random() for x in range(5)]

    def random_global( loop ):
    rg = default_rng(SEED)
    return loop, [rg.random() for x in range(5)]

    def random_rg( loop, rg ):
    return loop, [rg.random() for x in range(5)]

    def random_wseed( loop, seed ):
    rg = default_rng( seed )
    return loop, [rg.random() for x in range(5)]

    def printresults( futures ):
    for future in cf.as_completed( futures ):
    print( future.result() )


    SEED = 1234
    nworkers = 4
    nloops = 4

    rg = default_rng(SEED)

    ss = SeedSequence(SEED)
    child_seeds = ss.spawn(nloops) # Spawn off 4 child SeedSequences to pass to child processes.

    futures_noseed = []
    futures_global = []
    futures_rg = []
    futures_wseed = []
    futures_seedseq = []
    futures_seedseq_childseeds = []
    with cf.ProcessPoolExecutor( max_workers=nworkers ) as executor:
    for nl in range(nloops):
    futures_noseed.append( executor.submit( random, nl ) )
    futures_global.append( executor.submit( random_global, nl ) )
    futures_rg.append( executor.submit( random_rg, nl, rg ) )
    futures_wseed.append( executor.submit( random_wseed, nl, SEED ) )
    futures_seedseq.append( executor.submit( random_wseed, nl, ss) )
    futures_seedseq_childseeds.append( executor.submit( random_wseed, nl, child_seeds[nl]) )

    print( f'\nNO SEED')
    printresults(futures_noseed)

    print( f'\nGLOBAL SEED')
    printresults(futures_global)

    print( f'\nRG PREDEFINED WITH SEED PASS INTO FUNCTION')
    printresults(futures_rg)

    print(f'\nPASS SEED INTO FUNCTION')
    printresults(futures_wseed)

    print(f'\nWITH SEEDSEQUENCE')
    printresults(futures_seedseq)

    print(f'\nWITH SEEDSEQUENCE CHILD SEEDS')
    printresults(futures_seedseq_childseeds)
    输出:
    NO SEED
    (0, [0.739015261152181, 0.14451069021561325, 0.350594672768367, 0.20752211613920601, 0.795523682962996])
    (2, [0.7984800506892198, 0.8583726299238038, 0.06791593362457293, 0.53430686768646, 0.0961085560717182])
    (3, [0.5277372591285804, 0.33460069291263295, 0.8784128027557904, 0.9050110393243033, 0.6994660907632239])
    (1, [0.5819290163279096, 0.9126020141058546, 0.17326463037949713, 0.8475223328152056, 0.23048284365911964])

    GLOBAL SEED
    (3, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (2, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (1, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (0, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])

    RG PREDEFINED WITH SEED PASS INTO FUNCTION
    (3, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (2, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (1, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (0, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])

    PASS SEED INTO FUNCTION
    (1, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (0, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (2, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (3, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])

    WITH SEEDSEQUENCE
    (2, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (3, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (1, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])
    (0, [0.9766997666981422, 0.3801957350196178, 0.9232462337639554, 0.2616924238635442, 0.31909705841419755])

    WITH SEEDSEQUENCE CHILD SEEDS
    (2, [0.07734677155697511, 0.8570271790573564, 0.10048845220790636, 0.0478704579870608, 0.30020477671271684])
    (3, [0.22148724095124595, 0.09787195733339815, 0.17127991416955768, 0.4819142922814075, 0.7368117871750866])
    (1, [0.7137868247717851, 0.5945483974175882, 0.3889492785448826, 0.32053552182074196, 0.6488990935363684])
    (0, [0.5293458940996787, 0.2331172694518996, 0.7607005642504421, 0.9940522082501517, 0.6181026121532509])

    最佳答案

    问题的答案 2 并不完全正确。使用传递种子 numpy.random.SeedSequence() 的相同产生的子种子针对不同的并发进程,可以使用相同的种子来启动随机进程。
    下面的代码显示了一个应用程序,其中每个并发进程使用相同的种子来启动随机进程。

    import numpy as np
    from numpy.random import default_rng, SeedSequence
    import concurrent.futures as cf


    def random_wseed( batch, loop, seed ):
    rg = default_rng( seed )
    return batch, loop, [rg.random() for x in range(5)]

    SEED=1234
    ss = SeedSequence(SEED)
    nworkers = 4
    nloops = 4
    nbatch = 5

    futures_seedseq_childseeds = []
    with cf.ProcessPoolExecutor( max_workers=nworkers ) as executor:
    for batch in range(nbatch):
    child_seed = ss.spawn(1)
    for nl in range(nloops):
    futures_seedseq_childseeds.append( executor.submit( random_wseed, batch, nl, child_seed[0]) )

    print(f'\nFor each batch, each concurrent process uses the same seed to start the random process.')
    for future in cf.as_completed( futures_seedseq_childseeds ):
    print( future.result() )

    ##Code should achieve this result:
    ##For each batch, each concurrent process uses the same seed to start the random process.
    ##(0, 0, [0.5293458940996787, 0.2331172694518996, 0.7607005642504421, 0.9940522082501517, 0.6181026121532509])
    ##(0, 1, [0.5293458940996787, 0.2331172694518996, 0.7607005642504421, 0.9940522082501517, 0.6181026121532509])
    ##(0, 2, [0.5293458940996787, 0.2331172694518996, 0.7607005642504421, 0.9940522082501517, 0.6181026121532509])
    ##(0, 3, [0.5293458940996787, 0.2331172694518996, 0.7607005642504421, 0.9940522082501517, 0.6181026121532509])
    ##(1, 0, [0.7137868247717851, 0.5945483974175882, 0.3889492785448826, 0.32053552182074196, 0.6488990935363684])
    ##(1, 1, [0.7137868247717851, 0.5945483974175882, 0.3889492785448826, 0.32053552182074196, 0.6488990935363684])
    ##(1, 2, [0.7137868247717851, 0.5945483974175882, 0.3889492785448826, 0.32053552182074196, 0.6488990935363684])
    ##(1, 3, [0.7137868247717851, 0.5945483974175882, 0.3889492785448826, 0.32053552182074196, 0.6488990935363684])
    ##(2, 0, [0.07734677155697511, 0.8570271790573564, 0.10048845220790636, 0.0478704579870608, 0.30020477671271684])
    ##(2, 1, [0.07734677155697511, 0.8570271790573564, 0.10048845220790636, 0.0478704579870608, 0.30020477671271684])
    ##(2, 2, [0.07734677155697511, 0.8570271790573564, 0.10048845220790636, 0.0478704579870608, 0.30020477671271684])
    ##(2, 3, [0.07734677155697511, 0.8570271790573564, 0.10048845220790636, 0.0478704579870608, 0.30020477671271684])
    ##(3, 0, [0.22148724095124595, 0.09787195733339815, 0.17127991416955768, 0.4819142922814075, 0.7368117871750866])
    ##(3, 1, [0.22148724095124595, 0.09787195733339815, 0.17127991416955768, 0.4819142922814075, 0.7368117871750866])
    ##(3, 2, [0.22148724095124595, 0.09787195733339815, 0.17127991416955768, 0.4819142922814075, 0.7368117871750866])
    ##(3, 3, [0.22148724095124595, 0.09787195733339815, 0.17127991416955768, 0.4819142922814075, 0.7368117871750866])
    ##(4, 0, [0.96083157225477, 0.5340463204254748, 0.028932799912096963, 0.4711509829841223, 0.20344219135413988])
    ##(4, 1, [0.96083157225477, 0.5340463204254748, 0.028932799912096963, 0.4711509829841223, 0.20344219135413988])
    ##(4, 2, [0.96083157225477, 0.5340463204254748, 0.028932799912096963, 0.4711509829841223, 0.20344219135413988])
    ##(4, 3, [0.96083157225477, 0.5340463204254748, 0.028932799912096963, 0.4711509829841223, 0.20344219135413988])
    结果:
    For each batch, each concurrent process uses the same seed to start the random process.
    (4, 0, [0.96083157225477, 0.5340463204254748, 0.028932799912096963, 0.4711509829841223, 0.20344219135413988])
    (2, 1, [0.07734677155697511, 0.8570271790573564, 0.10048845220790636, 0.0478704579870608, 0.30020477671271684])
    (0, 0, [0.5293458940996787, 0.2331172694518996, 0.7607005642504421, 0.9940522082501517, 0.6181026121532509])
    (0, 2, [0.5293458940996787, 0.2331172694518996, 0.7607005642504421, 0.9940522082501517, 0.6181026121532509])
    (3, 3, [0.22148724095124595, 0.09787195733339815, 0.17127991416955768, 0.4819142922814075, 0.7368117871750866])
    (2, 0, [0.07734677155697511, 0.8570271790573564, 0.10048845220790636, 0.0478704579870608, 0.30020477671271684])
    (3, 2, [0.22148724095124595, 0.09787195733339815, 0.17127991416955768, 0.4819142922814075, 0.7368117871750866])
    (1, 3, [0.7137868247717851, 0.5945483974175882, 0.3889492785448826, 0.32053552182074196, 0.6488990935363684])
    (3, 1, [0.22148724095124595, 0.09787195733339815, 0.17127991416955768, 0.4819142922814075, 0.7368117871750866])
    (1, 2, [0.7137868247717851, 0.5945483974175882, 0.3889492785448826, 0.32053552182074196, 0.6488990935363684])
    (4, 3, [0.96083157225477, 0.5340463204254748, 0.028932799912096963, 0.4711509829841223, 0.20344219135413988])
    (3, 0, [0.22148724095124595, 0.09787195733339815, 0.17127991416955768, 0.4819142922814075, 0.7368117871750866])
    (1, 1, [0.7137868247717851, 0.5945483974175882, 0.3889492785448826, 0.32053552182074196, 0.6488990935363684])
    (0, 1, [0.5293458940996787, 0.2331172694518996, 0.7607005642504421, 0.9940522082501517, 0.6181026121532509])
    (4, 2, [0.96083157225477, 0.5340463204254748, 0.028932799912096963, 0.4711509829841223, 0.20344219135413988])
    (2, 3, [0.07734677155697511, 0.8570271790573564, 0.10048845220790636, 0.0478704579870608, 0.30020477671271684])
    (1, 0, [0.7137868247717851, 0.5945483974175882, 0.3889492785448826, 0.32053552182074196, 0.6488990935363684])
    (4, 1, [0.96083157225477, 0.5340463204254748, 0.028932799912096963, 0.4711509829841223, 0.20344219135413988])
    (2, 2, [0.07734677155697511, 0.8570271790573564, 0.10048845220790636, 0.0478704579870608, 0.30020477671271684])
    (0, 3, [0.5293458940996787, 0.2331172694518996, 0.7607005642504421, 0.9940522082501517, 0.6181026121532509])

    关于python - 为 concurrent.futures.ProcessPoolExecutor 播种 numpy.random 的 default_rng 和 SeedSequence 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62960419/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com