如何与子进程共享父进程的numpy随机状态?

我在程序开始时设置了numpy随机种子.在程序执行期间,我使用multiprocessing.Process多次运行一个函数.该函数使用numpy随机函数绘制随机数.问题是Process获取当前环境的副本.因此,每个进程都独立运行,它们都以与父环境相同的随机种子开始.

所以我的问题是如何在子环境中与父进程环境共享numpy的随机状态?请注意,我想在我的工作中使用Process,需要使用一个单独的类,并分别在该类中导入numpy.我尝试使用multiprocessing.Manager来共享随机状态,但似乎事情没有按预期工作,我总是得到相同的结果.此外,如果我在drawNumpySamples中移动for循环或将其保留在main.py中也没关系;我仍然无法得到不同的数字,随机状态总是一样的.这是我的代码的简化版本:

# randomClass.py
import numpy as np
class myClass(self):
    def __init__(self, randomSt):
        print ('setup the object')
        np.random.set_state(randomSt)
    def drawNumpySamples(self, idx)
        np.random.uniform()

并在主文件中:

    # main.py
    import numpy as np
    from multiprocessing import Process, Manager
    from randomClass import myClass

    np.random.seed(1) # set random seed
    mng = Manager()
    randomState = mng.list(np.random.get_state())
    myC = myClass(randomSt = randomState)

    for i in range(10):
        myC.drawNumpySamples() # this will always return the same results

注意:我使用的是Python 3.5.我还在Numpy的GitHub页面上发布了一个问题.只需发送问题链接here以供将来参考.

最佳答案 即使你设法使这个工作,我不认为它会做你想要的.一旦你有多个进程并行地从相同的随机状态拉出,它们就不再确定它们每个进入状态的顺序,这意味着你的运行实际上不可重复.可能有办法,但这似乎是一个非常重要的问题.

同时,有一个解决方案可以解决你想要的问题和非确定性问题:

在产生子进程之前,请向RNG索取一个随机数,并将其传递给孩子.然后孩子可以用这个数字播种.然后,每个孩子将具有与其他孩子不同的随机序列,但是如果您使用固定种子重新运行整个应用程序,则该子项具有相同的随机序列.

如果您的主要流程执行任何其他可能非确定性地依赖于子项执行的RNG工作,则您需要在拉出任何其他随机数之前按顺序为所有子进程预生成种子.

正如发送者在评论中指出的那样:如果你不需要多次不同的运行,只需要一次固定运行,你甚至不需要从种子RNG中提取种子;只需使用从1开始的计数器并为每个新进程递增计数器,并将其用作种子.我不知道这是否可以接受,但如果是,那就很难比这简单.

正如Amir在评论中指出的:更好的方法是每次生成一个新进程时绘制一个随机整数,并将该随机整数传递给新进程,以便用该整数设置numpy的随机种子.这个整数确实可以来自np.random.randint().

点赞