np.random.integers()如何移动当前的rng种子?

问题描述 投票:0回答:1

我正在尝试尽可能仔细地保留随机数生成器的序列。然而,以下代码显示当前随机种子的进展似乎存在一些问题。 我不明白为什么前两个循环对 random_arr 给出相同的答案。

import numpy as np

def train_test_split(X,rint):
    print('rint = ',rint)
    return X

def index_split(X,rng):
    X_train = train_test_split(X, rng.integers(65536))
    return X_train

def new_rng():
    rng = np.random.default_rng(seed)
    return rng

seed = 1234
n_params = 4

extranls = [0, 1, 2]
X = [0]

print('np.__version__ = ',np.__version__)
for ind, extran in enumerate(extranls):
    print('\n\n----------')
    print('rng #: ',ind)
    RNG = new_rng()
    X_train = index_split(X, RNG)
    for i in range(extran):
        print('Extra: rng.integers(65536) = ',RNG.integers(65536))

    initial_parameters = np.zeros(n_params, dtype=np.float32)
    random_arr = RNG.random(n_params)
    print('extran = ',extran)
    print('random_arr is ',random_arr)

# 
# np.__version__ =  1.26.4
# 
# 
# ----------
# rng #:  0
# rint =  64182
# extran =  0
# random_arr is  [0.38019574 0.92324623 0.26169242 0.31909706]
# 
# 
# ----------
# rng #:  1
# rint =  64182
# Extra: rng.integers(65536) =  64008
# extran =  1
# random_arr is  [0.38019574 0.92324623 0.26169242 0.31909706]
# 
# 
# ----------
# rng #:  2
# rint =  64182
# Extra: rng.integers(65536) =  64008
# Extra: rng.integers(65536) =  64745
# extran =  2
# random_arr is  [0.92324623 0.26169242 0.31909706 0.11809123]

第一个和第二个循环给出 [0.38019574 0.92324623 0.26169242 0.31909706]

python numpy random
1个回答
0
投票

默认 PCG64 BitGenerator 底层的算法生成 64 位值,但生成 0 到 65535 之间的数字不需要 64 位随机值。 大多数对随机整数的请求不需要 64 位随机值。所以,NumPy 有一个优化。为了满足 32 位就足够的请求,PCG64 BitGenerator 会分割其底层 64 位输出,每次生成 2 个 32 位值。

RNG.integers(65536)
内调用
index_split
会生成 2 个 32 位值,使用其中一个生成您请求的输出,并缓存另一个。再次调用它会使用缓存的值,而不推进底层状态。调用
RNG.random(n_params)
无法使用缓存,因此无论您在
index_split
之后立即调用它,还是在进行一次额外的
RNG.integers(65536)
调用之后,其行为都是相同的。

您可以在 NumPy 源存储库中查看负责的代码,特别是hereherehere

请注意,这是所有实现细节。文档提到这种事情可能会发生,但不承诺它会发生:

© www.soinside.com 2019 - 2024. All rights reserved.