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
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)))
5条答案
按热度按时间csbfibhn1#
正如fuglede所说,这里的问题是
np.float64
不能处理像exp(1234.1)
那么大的数,请尝试使用np.float128
:但是请注意,使用扩展精度有一些怪癖,它可能在Windows上不起作用;你并没有得到128位的精度并且当数字经过纯Python时,您可能会丢失精度。您可以在这里阅读更多有关细节的信息。
对于大多数实际应用,你可以将
1 / (1 + <a large number>)
近似为零,也就是说,忽略警告,继续下一步,Numpy会为你处理近似值(当使用np.float64
时):如果您想隐藏警告,可以使用
scipy.special.expit
,如WarrenWeckesser在问题的注解中所建议的:vshtjzan2#
numpy
浮点数可表示的最大值是1.7976931348623157e+308,其对数约为709.782,因此无法表示np.exp(1234.1)
。mtb9vblg3#
一个可能的解决方案是使用
decimal
模块,它允许您使用任意精度的浮点数。下面是一个使用numpy
浮点数数组(精度为100位)的示例:ulydmbyx4#
exp(-1234.1)对于32位或64位浮点数太小。由于无法表示,numpy将生成正确的警告。
使用
IEEE 754 32bit floating-point
数,它可以表示的最小正数是2^(-149)
,大约是1 e-45。如果你使用
IEEE 754 64 bit floating-point
数,最小的正数是2^(-1074)
,大约是1 e-327。在这两种情况下,它都不能表示像exp(-1234.1)这样小的数,exp(-1234.1)大约为1 e-535。
你应该使用scipy中的
expit
函数来计算sigmoid函数,这样可以提高精度。实际上,exp(-1234.1)是一个非常小的数字。如果在您的用例中舍入到零是有意义的,numpy通过将其舍入到零产生良性结果。
hfwmuf9z5#
如果不关心精度,可以使用
numpy.clip
。在
float64
中:在
float32
中: