【发布时间】:2018-04-25 16:04:53
【问题描述】:
在计算sigmoid function 时,由于缺乏浮点精度,x 的小值或大值将分别返回 0 和 1。在numpy 中,函数np.expm1 将计算exp(x)-1,对于x 的极值具有更高的精度。但是,不存在用于计算exp(x)+1(sigmoid 函数中的分母)的等效函数。我不知道如何使用np.expm1 来计算在极值处精度更高的 sigmoid。有办法吗?
1/(np.exp(-20)+1)==1.0
#False
1/(np.exp(-50)+1)==1.0
# True
【问题讨论】:
-
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.9999999999999999999998071250152036082216。可表示为 64 位浮点数的最接近值是 1.0。如果您需要比这更高的精度,则必须使用提供比标准 64 位浮点数更精确的数字表示的库。例如,我使用mpmath来计算这 40 位数字。 -
或者,当 x > 0 时不计算
sigmoid(x),只计算 1 和sigmoid(x)之间的差,根据对称性,是sigmoid(-x)。例如,1 - sigmoid(50) = sigmoid(-50) = 1.928749...e-22。但是随后您必须修改其余代码以处理这种差异。这是否值得(甚至可能)取决于您将如何处理sigmoid(x)的值。 -
顺便说一下,对于计算sigmoid函数,我推荐
scipy.special.expit而不是基于exp创建自己的实现;例如,参见stackoverflow.com/questions/21106134/… -
@EricPostpischil 好的,我现在明白了,所以显然这同样适用于
np.log1p
标签: numpy floating-point