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

2023-11-26

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

所以我的问题是如何与子进程环境共享父环境中 numpy 的随机状态?请注意,我想使用Process为了我的工作并且需要使用单独的班级 and do 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

Note:我使用Python 3.5。我还在 Numpy 的 GitHub 页面上发布了一个问题。只需发送问题链接here备查。


即使你设法让它工作,我也不认为它会达到你想要的效果。一旦您有多个进程并行地从同一随机状态拉取,它们各自进入该状态的顺序就不再是确定的,这意味着您的运行实际上将不可重复。可能有办法解决这个问题,但这似乎是一个不平凡的问题。

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

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

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


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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐