Python的numpy.exp函数中的溢出错误

时间:2016-11-21 17:58:33

标签: python numpy scipy

我想像这样使用numpy.exp

cc = np.array([
    [0.120,0.34,-1234.1]
])

print 1/(1+np.exp(-cc))

但是这给了我错误:

/usr/local/lib/python2.7/site-packages/ipykernel/__main__.py:5: RuntimeWarning: overflow encountered in exp

我不明白为什么?我怎样才能解决这个问题?问题似乎是第三个数字(-1234.1)

5 个答案:

答案 0 :(得分:10)

正如fuglede所说,问题在于FILEGROUP_NAME()无法处理与np.float64一样大的数字。请尝试使用exp(1234.1)

np.float128

但请注意,使用扩展精度存在某些怪癖。它可能无法在Windows上运行;你实际上并没有获得完整的128位精度;当数字通过纯python时你可能会失去精度。您可以详细了解详情MSDN definition

对于大多数实际用途,您可以将>>> cc = np.array([[0.120,0.34,-1234.1]], dtype=np.float128) >>> cc array([[ 0.12, 0.34, -1234.1]], dtype=float128) >>> 1 / (1 + np.exp(-cc)) array([[ 0.52996405, 0.58419052, 1.0893812e-536]], dtype=float128) 近似为零。也就是说,只需忽略警告并继续前进。 Numpy会为您提供近似值(使用1 / (1 + <a large number>)时):

np.float64

如果你想取消警告,你可以使用here,正如WarrenWeckesser在对该问题的评论中所建议的那样:

>>> 1 / (1 + np.exp(-cc))
/usr/local/bin/ipython3:1: RuntimeWarning: overflow encountered in exp
  #!/usr/local/bin/python3.4
array([[ 0.52996405,  0.58419052,  0.        ]])

答案 1 :(得分:5)

numpy float表示的最大值是1.7976931348623157e + 308,其对数约为709.782,因此无法表示np.exp(1234.1)

In [1]: import numpy as np

In [2]: np.finfo('d').max
Out[2]: 1.7976931348623157e+308

In [3]: np.log(_)
Out[3]: 709.78271289338397

In [4]: np.exp(709)
Out[4]: 8.2184074615549724e+307

In [5]: np.exp(710)
/usr/local/bin/ipython:1: RuntimeWarning: overflow encountered in exp
  #!/usr/local/bin/python3.5
Out[5]: inf

答案 2 :(得分:2)

一种可能的解决方案是使用decimal模块,它允许您使用任意精度浮点数。下面是一个示例,其中使用了一个精度为100位的numpy浮点数组:

import numpy as np
import decimal

# Precision to use
decimal.getcontext().prec = 100

# Original array
cc = np.array(
    [0.120,0.34,-1234.1]
)
# Fails
print(1/(1 + np.exp(-cc)))    

# New array with the specified precision
ccd = np.asarray([decimal.Decimal(el) for el in cc], dtype=object)
# Works!
print(1/(1 + np.exp(-ccd)))

答案 3 :(得分:0)

对于32位或64位浮点数,

exp(-1234.1)太小。由于无法表示,因此numpy会产生正确的警告。

使用IEEE 754 32bit floating-point数字,它可以表示的最小正数是2^(-149),大约为1e-45。

如果使用IEEE 754 64 bit floating-point数字,则最小的正数为2^(-1074),大约为1e-327。

在任何一种情况下,它都不能表示小于exp(-1234.1)的数字,该数字约为1e-535。

您应该使用scipy中的expit函数来计算Sigmoid函数。这样可以提高精度。

出于实际目的,exp(-1234.1)是一个非常小的数字。如果在您的用例中四舍五入是有意义的,则numpy通过将其四舍五入产生良性结果。

答案 4 :(得分:0)

如果您不关心精度,可以使用 numpy.clip

float64中:

cc = np.clip(cc, -709.78, 709.78)

float32中:

cc = np.clip(cc, -88.72, 88.72)