需要解决浮点精度不足的问题

时间:2019-08-16 16:50:19

标签: python numpy

到目前为止,我不仅对现在,而且现在又读了很多关于这个主题的书... 而且我以为我明白要点,可以肯定的是,我不得不问这个问题有点尴尬,但是我缺乏合适的解决方案,我觉得自己很正确并且可以保存。

我使用了numpy和dtype numpy.flaot64,我将其理解为双精度,只是为了防止常见的浮动问题。但是现在通过测试它是一样的。 我要进行数十亿次(真的)计算((为什么要选择np),所以速度至关重要,我不希望在计算的每一步都执行np.round()……这将是准确的结果,因为我在该点之后只有这3位数字。 您当然可以争论,为什么不将问题乘以1000或10000,而numpy马上就做了这样的事情。但这会在进一步的计算中导致更多的问题,因为此后会有更多的计算。 让我们看一下问题:

a = np.array([[7.125], [5.233]], dtype=np.float64)
b = np.array([[7.124], [5.232]], dtype=np.float64)
c = a - b
print(repr(c))


array([[0.001000000000000334 ],
       [0.0009999999999994458]])

足够容易!!! 我不需要解释为什么会发生这种情况,我不会在np.round()或np.set_printoptions()上寻找解决方法,我知道这不会改变我的数据,而只是改变了我的显示方式。 我以为是numpy-64bit-double-precision(很难实现128,因为我要做的所有大处理都发生在我的室友Win-PC xD上,现在,我怀疑它是否可以解决我的问题,但是请纠正我的问题。我错了!!!!!!如果以前保存的位数不超过10位,就足以精确地做到这一点。 看看如果我这样做会发生什么:

a = np.random.randint(1000, 1000000,(5, 2))
b = np.random.randint(1000, 1000000,(5, 2))
a = a / 1000
b = b / 1000
c = a - b
print(a.dtype)
print(c)

>>>float64
[[ 375.929 -833.91 ]
 [ 482.509 -106.411]
 [  -2.08   -64.672]
 [ 395.236 -383.997]
 [ 213.829 -101.08 ]]

没有这样的精度“崩溃”,这就是我想要的。

那么有没有一种“正确”的方法呢? 多谢听我的故事^^,很抱歉再次将此问题提上桌^^ 最好的问候

1 个答案:

答案 0 :(得分:0)

双精度浮点数具有很高的精度,您只需要获取何时何地重要的经验即可。一些最大的模型使用32位浮点数(主要是为了提高运行时性能)甚至16bit variants

进行训练

还有一些类似log1p and expm1的函数可以在晦涩难懂的地方提供帮助(尽管我编写了使用上述函数的代码,但我不确定我是否具有在实际起作用的值) ,并且我已经编写了运行了许多CPU多年的数字代码)。要知道的另一件事是catastrophic cancellation。重写数学/方程式对数值稳定性有很大帮助,尽管知道在何时何地执行此操作可能很困难。使用标准算法确实有帮助,例如花了一些时间来检查numpy.linalg,因为大量工作已投入到确保他们表现良好的行为中

round几乎从来都不是正确的选择,而且会使情况变得更糟,尤其是在获得中间结果时。舍入应该几乎总是最终显示。例如您可以通过在错误的时间四舍五入,轻松地使计算结果差15个数量级。例如其中a=1.5b=1.499999999999999a-b〜1e-15,而round(a) - round(b)是1。请注意,这些只是一点点不同,您应该期望累积误差,很容易将值推到圆形边界的任一侧。同样,对于不能很好地编码为二进制浮点数的值,这可能会在尴尬的地方发生

0.001之类的值无法准确表示,并且始终略有“错误”。例如尝试decimal.Decimal(0.001)  或0.001.hex()来获取实际代表的值