【问题标题】:How to spawn seeds of NumPy SeedSequence during Parallel Random Number Generation?如何在并行随机数生成期间产生 NumPy SeedSequence 的种子?
【发布时间】:2020-12-15 04:21:13
【问题描述】:

NumPy 在Parallel Random Number Generation 上的文档展示了如何使用SeedSequence 产生孙子种子(见下文)。

from numpy.random import SeedSequence, default_rng

ss = SeedSequence(12345)

# Spawn off 10 child SeedSequences to pass to child processes.
child_seeds = ss.spawn(10)
streams = [default_rng(s) for s in child_seeds]

子 SeedSequence 对象也可以生成孙子,并且 很快。每个 SeedSequence 在 spawned 树中都有自己的位置 SeedSequence 对象与用户提供的种子混合以生成 独立(概率很高)流。

grandchildren = child_seeds[0].spawn(4)
grand_streams = [default_rng(s) for s in grandchildren]

我的问题:

要创建下一代种子,我应该使用:

 great_grandchildren = grandchildren[0].spawn(4)
 great_grand_streams = [default_rng(s) for s in great_grandchildren]

还是应该总是引用child_seeds[0]:

great_grandchildren = child_seeds[0].spawn(4)
great_grand_streams = [default_rng(s) for s in great_grandchildren]

我的问题的上下文涉及实现种子和一个由concurrent.futures.ProcessPoolExecutor 对象组成的函数,该对象在可能“无休止”的while循环场景中为每个进程使用种子。我想知道下面是否是从SeedSequence 产生种子的正确方法,假设我已经使用了 NumPy 示例中提到的grandchildrengrand_streams 术语。例如:

 from numpy.random import SeedSequence, default_rng
 
 ss = SeedSequence(12345)
 
 # Spawn off 10 child SeedSequences to pass to child processes.
 child_seeds = ss.spawn(10)
 streams = [default_rng(s) for s in child_seeds]
 
 run_func1( streams ) #child_seeds is consummed

 grandchildren = child_seeds[0].spawn(4)
 grand_streams = [default_rng(s) for s in grandchildren]

 while True:
     run_concurrent_futures_ProcessPoolExecutor_func( grand_streams )
     if condition_not_met:
         grandchildren = grandchildren[0].spawn(4) #Do I use grandchildren[0] or child_seeds[0] to ensure randomness?
         grand_streams = [default_rng(s) for s in grandchildren]
     else:
         break

【问题讨论】:

    标签: python numpy random-seed concurrent.futures


    【解决方案1】:

    没关系。您正在构建一棵树,其结构无关紧要,唯一不同的是您的树最终是 3 层还是 2 层。

    【讨论】:

    • 对不起,我不明白你的回答。我在我的问题中添加了更多信息。您可以查看它们并更新您的答案吗?谢谢。
    • 您不应该在每次循环中都生成一个新的 SeedSequence。像这样反复播种相同的 PRNG 是没有意义的。
    • 我的意思是从 SeedSequence 产生种子,而不是产生新的 SeedSequence。你误解了我的问题。我不明白你的回答。您能否明确回答我的问题以帮助我理解?干杯。
    • 让我问你一个问题:你是否试图在每次运行程序时生成相同的随机数?也就是说,结果是可重现的,或者每次运行时它们是随机的且不同的,这对您来说是否重要?
    • 我想用一个已知的种子启动我的程序,并在每个 while 循环中为每个进程分配不同的种子。在使用 Python 的 concurrent.futures.ProcessPoolExecutor 对象的上下文中,相同的种子将被传递给每个进程`。我试图避免这种情况。
    【解决方案2】:

    spawn 旨在为并行进程创建独立的 RNG。但是,您没有并行过程:它是顺序的,因为您每次都在检查条件。所以不管你做什么。

    请注意,您可以不断从每个序列中生成新序列,因此您可以将代码更改为:

    from numpy.random import SeedSequence, default_rng
    
    ss = SeedSequence(12345)
    
    # Spawn off 10 child SeedSequences to pass to child processes.
    child_seeds = ss.spawn(10)
    streams = [default_rng(s) for s in child_seeds]
    
    run_func1( streams ) #  child_seeds is consumed
    
    while condition_not_met:
        child_seeds = ss.spawn(4)
        streams = [child_seeds (s) for s in grandchildren]
        run_concurrent_futures_ProcessPoolExecutor_func(streams)
    

    但实际上,您还需要考虑应该由哪个函数负责决定需要多少流。

    from numpy.random import SeedSequence
    
    ss = SeedSequence(12345)
    run_func1(ss.spawn(1)[0]) #  creates as many child seeds as it needs
    
    while condition_not_met:
        #  creates as many child seeds as it needs
        run_concurrent_futures_ProcessPoolExecutor_func(ss.spawn(1)[0])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-15
      • 2015-11-17
      • 2017-08-29
      • 1970-01-01
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 2013-08-23
      相关资源
      最近更新 更多