小编典典

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

python

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

所以我的问题是如何在父环境中与子进程环境共享numpy的随机状态?请注意,我想Process用于自己的工作,需要使用一个 单独的类
import numpy在该类中单独进行操作。我尝试使用multiprocessing.Manager来共享随机状态,但是似乎事情没有按预期进行,并且我总是得到相同的结果。同样,将for循环移入内部drawNumpySamples还是保留在循环中都没有关系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页面上发布了一个问题。只需在此处发送问题链接以供将来参考。


阅读 266

收藏
2020-12-20

共1个答案

小编典典

即使您设法做到这一点,我也不认为它会做您想要的。一旦有多个进程并行地从同一个随机状态中拉出,就不再确定它们各自到达状态的顺序,这意味着您的运行实际上不会重复。可能有一些解决方法,但这似乎是一个不小的问题。

同时,有一个解决方案应同时解决您想要的问题和不确定性问题:

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

如果您的主流程执行了可能不确定地依赖于子流程执行的任何其他RNG工作,那么您将需要在提取任何其他随机数之前按顺序为所有子流程预先生成种子。


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

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

2020-12-20