Numpy 用np.expm1计算sigmoid函数

Numpy 用np.expm1计算sigmoid函数,numpy,floating-point,Numpy,Floating Point,当计算a时,由于缺乏浮点精度,x的小值或大值将分别返回0和1。在numpy中,函数将以更高的精度计算x的极值exp(x)-1。但是,不存在计算exp(x)+1(sigmoid函数中的分母)的等效函数。我不知道如何使用np.expm1在极值处计算精度更高的乙状结肠。有没有办法做到这一点 1/(np.exp(-20)+1)==1.0 #False 1/(np.exp(-50)+1)==1.0 # True np.expm1减少了在取两个几乎相等的数字之间的差时发生的显著性损失(因为许多重要位置将相

当计算a时,由于缺乏浮点精度,x的小值或大值将分别返回0和1。在
numpy
中,函数将以更高的精度计算x的极值
exp(x)-1
。但是,不存在计算
exp(x)+1
(sigmoid函数中的分母)的等效函数。我不知道如何使用
np.expm1
在极值处计算精度更高的乙状结肠。有没有办法做到这一点

1/(np.exp(-20)+1)==1.0
#False
1/(np.exp(-50)+1)==1.0
# True

np.expm1
减少了在取两个几乎相等的数字之间的差时发生的显著性损失(因为许多重要位置将相互抵消,结果的重要位置将少于数据类型可以存储的位置)

是数据类型的限制,而不是算法的限制<代码>浮动无法解决与
1.0
的差异小于
exp(-50)
。实际上,
1.0
的最接近的浮动是

>>> np.nextafter(1.0, 0.0)
0.9999999999999999
>>> np.nextafter(1.0, 2.0)
1.0000000000000002

表示oom的分辨率
10^-16
,远不足以区分
1
1+/-exp(-50)

exp(x)-1有一个特殊的例程,因为当x接近零时exp(x)-1接近零。根据浮点的性质,当x接近零时,可以对其进行非常细微的更改,函数exp(x)-1反映了这些更改。相反,对于任何实x,exp(x)+1永远不会接近零。x的细微变化对计算结果没有影响,因为当x发生微小变化时,浮点格式无法表示exp(x)+1中发生的微小变化。通过计算exp(x)并加上1,您将得到相同或非常接近相同的结果。
1/(exp(-50)+1)
精确值的前40位为
0.9999999999999999998071250152036082216
。可表示为64位浮点数的最接近值为1.0。如果您需要更高的精度,则必须使用一个iLibrary,该iLibrary提供的数字表示比标准的64位浮点数精度更高。例如,我使用
mpmath
来计算这40个数字。或者,当x>0时,不计算
sigmoid(x)
,只计算1和
sigmoid(x)
之间的差,根据对称性,这是
sigmoid(-x)
。例如,
1-sigmoid(50)=sigmoid(-50)=1.928749…e-22
。但是,您必须修改代码的其余部分来处理这种差异。这是否值得(甚至可能)取决于您将如何使用
sigmoid(x)
的值。顺便说一句,对于计算sigmoid函数,我建议您不要基于
exp
创建自己的实现;比如说,@EricPostpischil好吧,我现在明白了,所以很明显,这同样适用于
>>> np.nextafter(1.0, 0.0)
0.9999999999999999
>>> np.nextafter(1.0, 2.0)
1.0000000000000002