Python OverflowError:在不同的运行中引发的数学范围错误不同

2024-05-12 19:55:23 发布

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

我的程序几乎是任意地崩溃了。

我的代码包括以下两行:

z[i, j] = -math.exp(oneminusbeta[j, i])
weights[i,j] = math.exp(beta[j,i] + oneminusbeta[j,i])

我以前在有2维的数据上运行过我的全部代码,它是7341 x 648。我在运行代码时完全没有问题。

但现在我使用的数据是现在的十倍。它是71678 x 648,我得到这个错误:

OverflowError: math range error

我不想在任何具体的问题上说这些。我在每一行代码之前都会记录注释,这样我就可以看到导致崩溃的原因,而且看起来崩溃更经常发生在上面提到的第二行(weights[i,j] = math.exp(beta[j,i] + oneminusbeta[j,i]))。

问题是,它在不同的时间崩溃。 起初,它在weights[30816, 42]坠毁。然后在weights[55399, 43]。然后在z[33715,45]。但这三种情况的数据都是一样的。

有什么问题吗?这是python的内存相关问题吗?顺便说一下,我也在用Numba

编辑

我忘了提到,我设置了阈值,这样进入exp()函数的内容不会超过709或-708,所以技术上不应该出现溢出。


Tags: 数据代码程序错误记录时间情况range
2条回答

计算结果无法在计算机上表示。这可能意味着math.exp(...)大于约10308,或者传递给math.exp()的参数大于约710。

尝试在每次计算之前打印beta[j,i]oneminusbeta[j,i]的值。

实际上,您不必在每一行代码之前都打印注释。相反,尝试用try块包装计算,如下所示:

try:
  weights[i,j] = math.exp(beta[j,i] + oneminusbeta[j,i])
except OverflowError:
  print "Calculation failed! j=%d i=%d beta=%f oneminusbeta=%f"%(j,i,beta[j,i],oneminusbeta[j,i])
  raise

您的溢出几乎可以肯定是一个真正的溢出;其中一个值太大,无法放入Pythonfloat(意思是Cdouble)。


那么,为什么每次都会在不同的地方发生呢?

因为你用的是麻木。

Numba JIT编译代码。如果它检测到没有争用,它可以重新排序代码,甚至,至少在理论上,在多个内核上或在GPU上并行运行它(尽管我认为目前只有在用numba.cuda显式编码时,才能获得GPU计算)。

无论如何,这意味着通过代码的路径是不确定的。如果有多个地方可能发生溢出,则无法预测哪个地方将失败并触发异常。


无论如何,这并不重要。如果你的计算太多了,你必须修正它。而且每次都有不同的溢出不应该让调试起来困难得多,特别是考虑到通常发生在一个地方,但并不总是这样。

相关问题 更多 >