python/numpy中的浮点数学不能在机器之间复制

2024-04-16 03:53:12 发布

您现在位置:Python中文网/ 问答频道 /正文

比较两台不同机器上浮点运算的结果,它们总是产生不同的结果。下面是一个简单的示例,它再现了这种行为:

import numpy as np
from numpy.random import randn as rand

M = 1024
N = 2048
np.random.seed(0)

a = rand(M,N).astype(dtype=np.float32)
w = rand(N,M).astype(dtype=np.float32)

b = np.dot(a, w)
for i in range(10):
    b = b + np.dot(b, a)[:, :1024]
    np.divide(b, 100., out=b)

print b[0,:3]

不同的机器产生不同的结果

  • [-2.85753540e-05-5.94204867e-05-2.62337649e-04]
  • [-2.85751412e-05-5.94208468e-05-2.62336689e-04]
  • [-2.85754559e-05-5.94202756e-05-2.62337562e-04]

但我也可以得到相同的结果,比如在两台同一年份的macbook上运行。这种情况发生在具有相同版本Python和numpy的机器上,但不一定与相同的BLAS库链接(例如Mac上的accelerate framework,Ubuntu上的OpenBLAS)。然而,不同的数值库不应该都符合相同的IEEE浮点标准并给出完全相同的结果吗?在


Tags: fromimportnumpy机器示例asnprandom
1条回答
网友
1楼 · 发布于 2024-04-16 03:53:12

浮点计算并不总是可重复的。在

如果您使用相同的可执行映像、输入、用相同的编译器和相同的编译器设置(开关)构建的库,则可以在不同的机器上获得可重复的浮动计算结果。在

但是,如果使用动态链接库,则可能会得到不同的结果,原因有很多。首先,作为Veedracpointed in comments,它可能在不同的架构上为其例程使用不同的算法。其次,编译器可能根据开关(各种优化、控件设置)生成不同的代码。即使a+b+c也会产生跨机器和编译器的不确定性结果,因为我们无法确定中间计算中求值的顺序、精度。在

阅读here为什么不能保证在不同的IEEE 754-1985实现上得到相同的结果。新标准(IEEE 754-2008)试图更进一步,但它仍然不能保证不同实现之间的结果相同,因为例如,它允许实现者选择何时检测到tinynes(下溢异常)

有关浮点决定论的更多信息可以在this article中找到。在

相关问题 更多 >