Python:使用上下文管理器临时更改随机种子的危险?
Python: dangers of temporarily changing the random seed using a context manager?
当使用随机数生成器在 Python 代码中实现可重复性时,推荐的方法似乎是构建单独的 RandomState 对象。不幸的是,一些基本包如 scipy.stats 不能(据我所知)设置为使用特定的 RandomState,而只会使用 numpy.random 的当前状态。
我当前的解决方法是使用上下文管理器来保存 RNG 的状态,然后在退出时重置它,如下所示:
class FixedSeed:
def __init__(self, seed):
self.seed = seed
self.state = None
def __enter__(self):
self.state = rng.get_state()
np.random.seed(self.seed)
def __exit__(self, exc_type, exc_value, traceback):
np.random.set_state(self.state)
文档中有很多关于以任何方式更改状态的警告 - 上述方法通常安全吗? (从某种意义上说,更改是上下文的本地更改,我的其余代码将不受影响)
set_state and get_state are not needed to work with any of the random
distributions in NumPy. If the internal state is manually altered, the
user should know exactly what he/she is doing.
听起来确实很吓人。 public 文档化界面上此警告的可能解释是 "know exactly" 表示 "knows that reseeding a PRNG willy-nilly severely reduces the randomness"。但是您知道您想要非常具体地针对您的上下文期间减少随机性。
为了支持这个猜想,我查看了 numpy/test_random.py,其中包含如下代码:
class TestSeed(TestCase):
def test_scalar(self):
s = np.random.RandomState(0)
assert_equal(s.randint(1000), 684)
s = np.random.RandomState(4294967295)
assert_equal(s.randint(1000), 419)
因为他们确实需要确定性的结果。请注意,他们创建了一个 np.random.RandomState
的实例,但我在代码中找不到任何迹象表明 set_state()
会破坏任何东西。
如有疑问,请编写一个测试套件
- 将默认 RNG 设置为固定值
- 每次检查默认 RNG returns 是否相同,预期值
- 使用上下文管理器
- 确认生成了新的值序列
- 确认来自 (1) 的原始种子 RNG 继续发出其预期序列
当使用随机数生成器在 Python 代码中实现可重复性时,推荐的方法似乎是构建单独的 RandomState 对象。不幸的是,一些基本包如 scipy.stats 不能(据我所知)设置为使用特定的 RandomState,而只会使用 numpy.random 的当前状态。 我当前的解决方法是使用上下文管理器来保存 RNG 的状态,然后在退出时重置它,如下所示:
class FixedSeed:
def __init__(self, seed):
self.seed = seed
self.state = None
def __enter__(self):
self.state = rng.get_state()
np.random.seed(self.seed)
def __exit__(self, exc_type, exc_value, traceback):
np.random.set_state(self.state)
文档中有很多关于以任何方式更改状态的警告 - 上述方法通常安全吗? (从某种意义上说,更改是上下文的本地更改,我的其余代码将不受影响)
set_state and get_state are not needed to work with any of the random distributions in NumPy. If the internal state is manually altered, the user should know exactly what he/she is doing.
听起来确实很吓人。 public 文档化界面上此警告的可能解释是 "know exactly" 表示 "knows that reseeding a PRNG willy-nilly severely reduces the randomness"。但是您知道您想要非常具体地针对您的上下文期间减少随机性。
为了支持这个猜想,我查看了 numpy/test_random.py,其中包含如下代码:
class TestSeed(TestCase):
def test_scalar(self):
s = np.random.RandomState(0)
assert_equal(s.randint(1000), 684)
s = np.random.RandomState(4294967295)
assert_equal(s.randint(1000), 419)
因为他们确实需要确定性的结果。请注意,他们创建了一个 np.random.RandomState
的实例,但我在代码中找不到任何迹象表明 set_state()
会破坏任何东西。
如有疑问,请编写一个测试套件
- 将默认 RNG 设置为固定值
- 每次检查默认 RNG returns 是否相同,预期值
- 使用上下文管理器
- 确认生成了新的值序列
- 确认来自 (1) 的原始种子 RNG 继续发出其预期序列