【问题标题】:Numpy matrix multiplication instability across rows跨行的 Numpy 矩阵乘法不稳定性
【发布时间】:2021-11-14 07:16:55
【问题描述】:

我将两个 float64 矩阵与以下值相乘:

import numpy as np


# 4x5 matrix with identical columns.
x = np.zeros((4, 5,), dtype=np.float64)
x[1] = 1
x[3] = -3

w = np.array([1, 1, -1, 1 / 3], dtype=np.float64)

# The result should be an array of size 5 with equal values.
result = np.matmul(w, x)

print(x)

>>> 
[[ 0.  0.  0.  0.  0.]
 [ 1.  1.  1.  1.  1.]
 [ 0.  0.  0.  0.  0.]
 [-3. -3. -3. -3. -3.]]

print(w)

>>> [ 1.          1.         -1.          0.33333333]

print(result)

>>> [5.55111512e-17 5.55111512e-17 5.55111512e-17 5.55111512e-17 0.00000000e+00]

result 数组应该包含相同的值,因为每个项目都是具有相同列的w 数组的点积。但是,最后一项是 0.0,与其他非常接近 0 的值不同。这对下游计算有很大影响。

我猜这与 1/3 的值有关,因为用 1/2 替换它会得到稳定的结果。但是如何解决这种不稳定性?

附加信息,因为问题不会在所有机器上重现

我在 MacOS 上使用 numpy 1.18.2 和 Python 3.7.3。 该问题在另一台运行具有相同 Python 和 numpy 版本的 Ubuntu 的机器上重现。

【问题讨论】:

  • 我在 google colab 上运行了相同的代码,它给出了 result 的预期值。
  • 虽然我觉得这很有趣,但是如果这对下游有很大的影响,那么你实际上有更大的问题,我会说你的算法通常不可信。
  • 这是计算机中浮点数表示的本质(也是它依赖于平台的原因)。相关问题:onetwo
  • 计算机内存中的@NurL 位表示 2 的幂。一些数字,如 1/4,可以在不损失精度的情况下存储,一些 (1/3) 必须稍微四舍五入以适应这种表示.确切的舍入误差取决于 CPU,有时还取决于操作系统(或者更确切地说,它附带的编译器)。在某些情况下,这些小的舍入误差足以影响最终结果。根据问题,可能有办法解决这个问题,例如通过使用对数刻度值来代替
  • @Marat:不,这不是浮点数的本质。浮点数的性质不会导致相同的计算产生不同的结果。必须发生的事情是numpy 没有以简单的定义方式计算matmul,即对行与列进行点积。它必须在做其他事情,涉及对不同位置的不同计算,并导致不同的结果。同样的情况也发生在整数运算中,就好像有人试图用7/3*37*3/3 计算7/3•3。

标签: python arrays numpy floating-point matrix-multiplication


【解决方案1】:

在运行 macOS 11.6、python 3.9.7 和 numpy 1.21.2 的 i7 Mac 上更改了数组大小并更改了哪些行设置为 1 和 -3 和 1/3 5.5e-17 值仅在第 0 行时出现为 1,第 2 行为 -3,当第 1 行为 1,第 3 行为 -3。 5.5e-17 和 0 值的数量取决于列数。某些列数(例如 16)产生所有 5.5e-17 值。将 -3 和 1/3 替换为不是 2 倍的值(例如 12 和 1/12)时的行为相同,但 5.5e-17 有时会更改为不同的 e-17 值。

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 2017-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-19
  • 2020-11-05
  • 2022-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多