在计算1/(1+;exp(x))python时避免数值不稳定

在计算1/(1+;exp(x))python时避免数值不稳定,python,numpy,floating-point,scipy,expansion,Python,Numpy,Floating Point,Scipy,Expansion,我想计算(可能大的)x的1/(1+exp(x))。这是一个介于0和1之间的性能良好的函数。我可以这么做 import numpy as np 1.0/(1.0+np.exp(x)) 但是在这个简单的实现中,np.exp(x)很可能只返回0或无穷大,这取决于符号。python中是否有可以帮助我解决问题的函数 我正在考虑实施串联扩展和串联加速,但我想知道这个问题是否已经解决 基本上,您受到浮点精度的限制。例如,如果使用64位浮点: fmax_64 = np.finfo(np.float64).ma

我想计算(可能大的)x的1/(1+exp(x))。这是一个介于0和1之间的性能良好的函数。我可以这么做

import numpy as np
1.0/(1.0+np.exp(x))
但是在这个简单的实现中,np.exp(x)很可能只返回0或无穷大,这取决于符号。python中是否有可以帮助我解决问题的函数


我正在考虑实施串联扩展和串联加速,但我想知道这个问题是否已经解决

基本上,您受到浮点精度的限制。例如,如果使用64位浮点:

fmax_64 = np.finfo(np.float64).max  # the largest representable 64 bit float
print(np.log(fmax_64))
# 709.782712893
如果
x
大于约709,则无法使用64位浮点表示
np.exp(x)
(或
1./(1+np.exp(x))

您可以使用扩展精度浮点(即
np.longdouble
):

np.longdouble
的精度可能因您的平台而异,这将允许您使用
x
值,最高可达11356:

func = lambda x: 1. / (1. + np.exp(np.longdouble(x)))
print(func(11356))
# 1.41861159972e-4932

除此之外,您还需要重新考虑如何计算扩展,或者使用类似的支持任意精度算法的工具。然而,这通常是以运行时性能比numpy差得多为代价的,因为矢量化已经不可能了。

您可以使用。它将避免由
1.0/(1.0+exp(x))
生成的溢出警告

谢谢,我来看看mpmath。我必须弄清楚我的任务真正需要什么样的精度。如果你问另一个问题来解释你试图解决的全部问题,你可能会得到一个更有用的答案-也许有一种方法可以避免计算
exp(x)
?你能举个例子说明你的输入输出很差,除了您希望为这些输入获得的输出之外?对于几乎所有的
x
,您给出的表达式实际上在数值上表现得相当好。(我能想到的唯一困难的地方是,
np.exp(x)
只会溢出一个double,最终得到的是零而不是正确的次正常值。)Nice-
expit
也适用于
np.longdouble
,并且溢出的
x
值比我天真的回答稍大一些。@ali\m感谢您的检查。我从答案中删除了“仍然是64位浮点”。谢谢,我不知道存在
scipy.special.expit(-x)
。伟大的发现!
func = lambda x: 1. / (1. + np.exp(np.longdouble(x)))
print(func(11356))
# 1.41861159972e-4932