我正在比较在两个不同系统上使用np.random.normal
生成的数字(详见下文)并使用以下代码进行比较(我使用旧版np.random.seed
,因为另一个程序使用它来产生输出,我最终想要验证这个输出)(1):
import numpy as np
np.random.seed(0)
x = np.random.normal(scale=1e-3, size=10**5)
np.save('test.npy', x)
然后我将test.npy
从一个系统复制到另一个系统,然后比较这两个版本:
>>> other = np.load('test.npy')
>>> (x != other).sum(), len(x)
(29, 100000)
>>> mask = x != other
>>> np.abs(x[mask] - other[mask])
array([5.42101086e-20, 1.35525272e-20, 2.71050543e-20, 5.42101086e-20,
1.08420217e-19, 1.08420217e-19, 2.16840434e-19, 2.16840434e-19,
1.35525272e-20, 1.08420217e-19, 1.08420217e-19, 5.42101086e-20,
2.71050543e-20, 1.08420217e-19, 2.16840434e-19, 5.42101086e-20,
2.71050543e-20, 2.16840434e-19, 2.16840434e-19, 2.71050543e-20,
2.71050543e-20, 1.08420217e-19, 1.08420217e-19, 1.08420217e-19,
5.42101086e-20, 1.08420217e-19, 1.08420217e-19, 5.42101086e-20,
2.71050543e-20])
>>> x[mask]
array([ 4.52489093e-04, 9.78961454e-05, -1.47113076e-04, -3.67859222e-04,
-5.33279620e-04, 8.40794952e-04, -7.75987295e-04, 1.34205479e-03,
6.34459482e-05, 5.07109360e-04, -7.68363366e-04, 3.33350262e-04,
-2.19367067e-04, 6.11402140e-04, -1.30486526e-03, -4.42699624e-04,
1.45463287e-04, -1.22491651e-03, 1.05226781e-03, -2.43032730e-04,
-2.40551279e-04, 4.95396595e-04, -7.25454745e-04, -8.50779215e-04,
-2.66274662e-04, 7.28854386e-04, 8.38515107e-04, 3.36152654e-04,
-1.26550328e-04])
所以有29个元素在100,000个元素中稍微有所不同。但是,我不明白这种差异来自何处。我确认我在两个系统上都安装了相同版本的Python和NumPy:
python==3.9.4
和 numpy==1.20.2
(通过python -m pip install numpy==1.20.2
获取;但我也检查了最新版本的numpy==1.23.0
,结果完全相同)。我验证了RNG状态(通过np.random.get_state()
)在调用np.random.normal
之前和之后在两个系统上是相同的。我多次保存和复制了test.npy
文件,并且还通过MD5校验进行了验证,因此差异必须源于随机数生成本身(1)。然而,我看不出这是可能的,因为两者都使用相同的随机状态进行初始化。
关于系统的信息
A系统(保存test.npy
的系统):
$ uname -a
Linux SystemA 3.10.0-1160.31.1.el7.x86_64 #1 SMP Thu Jun 10 13:32:12 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
我也在系统A2上进行了测试,该系统的操作系统版本与系统A相同,但配备了不同的CPU,但结果从A到A2并未发生变化,因此我怀疑是操作系统版本问题。
系统B(加载test.npy
文件的系统):
$ uname -a
Linux SystemB 5.4.0-113-generic #127-Ubuntu SMP Wed May 18 14:30:56 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
注释 (1): 当我按照文档中建议的方式使用 np.random.seed
,即 rs = RandomState(MT19937(SeedSequence(0)))
时,我发现两个系统之间的差异仍然存在。但是,当我使用 np.random.default_rng(seed=0)
,也就是新的 PCG64
时,我发现这种差异消失了。
uname -a
的输出感到困惑。 - Michael Szczesny