多个 Numpy 导入的全局种子
Global Seed for Multiple Numpy Imports
假设我有一个 Python 项目结构:
main.py
which imports random_initialization.py
main.py
which imports sample_around_solution.py
random_initialization
和 sample_around_solution.py
都导入 numpy
。
现在,
random_initialization
开始一个问题的随机实例,main
运行一个算法并且 sample_around_solution
使用解决方案周围的随机样本来计算一些指标(比如解决方案的质量)。
我想要运行的可复制性,我在两个导入文件中都有 numpy.random.seed(0)
。这是正确的方法吗?我觉得在某些极端情况下,这是一个可怕的想法。
我认为永远不要让任何东西操纵随机种子是个好主意,除了最顶层的模块,它通常是
一个简短的 main.py
,只有 import
s,做一些程序选项和配置,并调用其他东西)
一个unittest
播种的单点允许做一些有用的事情,例如,
您可以控制种子的重现性设置(如您所写)。
您可以控制改变种子以获得更好的覆盖率(例如,如果您将 运行 子模块通过单元测试)。
您可以将种子存储在持久存储中,这样如果某些执行出现问题,您可以重现它。
相反,如果子模块自己进行播种,则不能。我也认为这是错误的封装:它不是执行某些定义明确的功能 X 的模块,而是执行 X + 播种。
顺便说一句,几年前我写了一篇 tiny library on PyPI - UnittestRandGenState 来为 unittest
做 "smart" 播种,然后考虑了一下。它基本上依赖于你所提议的内容的缺失。
我更喜欢让模拟的每个组件都使用自己的随机数生成器。如果每个 Monte Carlo 组件都有自己的模块,并且你想要模块的全局 rng 状态,那么你可以在模块中放置一个初始化函数:
def init_rng(seed):
global rng
rng = numpy.random.RandomState(seed=seed)
然后你就可以独立设置和控制每个进程了,即
import componentA
import componentB
import componentC
componentA.init_rng(0)
componentB.init_rng(1)
componentC.init_rng(2)
如果您不喜欢全局变量,您也可以将随机过程封装在 类 中,并带有 rng 属性和初始化函数。
如果所有进程都共享同一个生成器,那么 processA 的结果可能取决于 processB 生成的数字的数量等...
假设我有一个 Python 项目结构:
main.py
which importsrandom_initialization.py
main.py
which importssample_around_solution.py
random_initialization
和 sample_around_solution.py
都导入 numpy
。
现在,
random_initialization
开始一个问题的随机实例,main
运行一个算法并且 sample_around_solution
使用解决方案周围的随机样本来计算一些指标(比如解决方案的质量)。
我想要运行的可复制性,我在两个导入文件中都有 numpy.random.seed(0)
。这是正确的方法吗?我觉得在某些极端情况下,这是一个可怕的想法。
我认为永远不要让任何东西操纵随机种子是个好主意,除了最顶层的模块,它通常是
一个简短的
main.py
,只有import
s,做一些程序选项和配置,并调用其他东西)一个
unittest
播种的单点允许做一些有用的事情,例如,
您可以控制种子的重现性设置(如您所写)。
您可以控制改变种子以获得更好的覆盖率(例如,如果您将 运行 子模块通过单元测试)。
您可以将种子存储在持久存储中,这样如果某些执行出现问题,您可以重现它。
相反,如果子模块自己进行播种,则不能。我也认为这是错误的封装:它不是执行某些定义明确的功能 X 的模块,而是执行 X + 播种。
顺便说一句,几年前我写了一篇 tiny library on PyPI - UnittestRandGenState 来为 unittest
做 "smart" 播种,然后考虑了一下。它基本上依赖于你所提议的内容的缺失。
我更喜欢让模拟的每个组件都使用自己的随机数生成器。如果每个 Monte Carlo 组件都有自己的模块,并且你想要模块的全局 rng 状态,那么你可以在模块中放置一个初始化函数:
def init_rng(seed):
global rng
rng = numpy.random.RandomState(seed=seed)
然后你就可以独立设置和控制每个进程了,即
import componentA
import componentB
import componentC
componentA.init_rng(0)
componentB.init_rng(1)
componentC.init_rng(2)
如果您不喜欢全局变量,您也可以将随机过程封装在 类 中,并带有 rng 属性和初始化函数。
如果所有进程都共享同一个生成器,那么 processA 的结果可能取决于 processB 生成的数字的数量等...