Numpy 数组浮点精度不确定
Numpy array float precision is not deterministic
所以当运行下面的片段
import numpy as np
X = np.array([-0.20000008], dtype=np.float32)
np.floor((X + 1) / 0.04)
array([20.], dtype=float32)
输出显然是错误的,因为结果应该低于 20,应该降到 19
我知道这是精度错误,但是 运行 下面的所有样本都产生了正确的结果,尽管它们应该具有相似的精度
X = np.array([-0.20000008], dtype=np.float32).item()
np.floor((X + 1) / 0.04) # 19.0
X = np.float32(-0.20000008)
np.floor((X + 1) / 0.04) # 19.0
X = np.array([-0.20000008], dtype=np.float32)
np.floor(X / 0.04 + 1 / 0.04) # array([19.], dtype=float32)
np.floor(np.multiply((X + 1), 1/0.04)) # array([19.], dtype=float32)
如果我将其转换为 float64,它也可以工作,但对于我的应用程序来说,转换成本非常高。坚持使用 float32 时有什么解决方案吗?
让我们先尝试理解底部三个示例中的前两个:
在第一个例子中
np.array([-0.20000008], dtype=np.float32).item()
将生成原生的 python float()
,它是 64 位的,所以这里没有惊喜。
在第二个示例中,您创建了一个 numpy 32 位 标量 (shape==(), type==np.float32
),它或多或少会像其他标量一样被对待:所以只要您添加一个 int
(1),结果将是一个 64 位数字。
现在有趣的情况实际上是您的初始代码段和第三个示例:在这两种情况下,您现在都有一个 array (shape==(1,), type=np.ndarray
)。在使用数组和标量进行操作的情况下,数组的类型将被保留。所以现在我们实际上遇到的问题是 分配 定律不适用于浮点数。您在这里进行的计算依赖于浮点数的最低有效位。
所以当运行下面的片段
import numpy as np
X = np.array([-0.20000008], dtype=np.float32)
np.floor((X + 1) / 0.04)
array([20.], dtype=float32)
输出显然是错误的,因为结果应该低于 20,应该降到 19
我知道这是精度错误,但是 运行 下面的所有样本都产生了正确的结果,尽管它们应该具有相似的精度
X = np.array([-0.20000008], dtype=np.float32).item()
np.floor((X + 1) / 0.04) # 19.0
X = np.float32(-0.20000008)
np.floor((X + 1) / 0.04) # 19.0
X = np.array([-0.20000008], dtype=np.float32)
np.floor(X / 0.04 + 1 / 0.04) # array([19.], dtype=float32)
np.floor(np.multiply((X + 1), 1/0.04)) # array([19.], dtype=float32)
如果我将其转换为 float64,它也可以工作,但对于我的应用程序来说,转换成本非常高。坚持使用 float32 时有什么解决方案吗?
让我们先尝试理解底部三个示例中的前两个:
在第一个例子中
np.array([-0.20000008], dtype=np.float32).item()
将生成原生的 python float()
,它是 64 位的,所以这里没有惊喜。
在第二个示例中,您创建了一个 numpy 32 位 标量 (shape==(), type==np.float32
),它或多或少会像其他标量一样被对待:所以只要您添加一个 int
(1),结果将是一个 64 位数字。
现在有趣的情况实际上是您的初始代码段和第三个示例:在这两种情况下,您现在都有一个 array (shape==(1,), type=np.ndarray
)。在使用数组和标量进行操作的情况下,数组的类型将被保留。所以现在我们实际上遇到的问题是 分配 定律不适用于浮点数。您在这里进行的计算依赖于浮点数的最低有效位。