logistic / sigmoid函数实现数值精度

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了logistic / sigmoid函数实现数值精度相关的知识,希望对你有一定的参考价值。

scipy.special.expit中,逻辑函数的实现方式如下:

if x < 0
    a = exp(x) 
    a / (1 + a) 
else 
    1 / (1 + exp(-x))

但是,我已经看到了其他语言/框架中的实现

1 / (1 + exp(-x))

我想知道scipy版本实际带来了多少好处。

对于非常小的x,结果接近0.即使exp(-x)溢出到Inf,它仍然有效。

答案

它实际上只是为了稳定性 - 放入幅度非常大的值可能会返回意外的结果。

如果expit被实现为1 / (1 + exp(-x))然后将-710的值放入函数将返回nan,而-709将给出接近零的值,如预期的那样。这是因为exp(710)太大而不能成为双倍。

代码中的分支只意味着避免了这种情况。

另请参阅Stack Overflow上的this question and answer

另一答案

似乎使用效率更高:

if x < -709
  sigmoid = 0.0
else
  sigmoid = 1.0 / (1.0 + exp(-x))

除非你需要10 ^ -309精度的数字(见下文),这似乎有点过分!

>>> 1 / (1 + math.exp(709.78))
5.5777796105262746e-309
另一答案

另一种方法是

python np.where(x > 0, 1. / (1. + np.exp(-x)), np.exp(x) / (np.exp(x) + np.exp(0)))

由于np.exp(x) / (np.exp(x) + np.exp(0))相当于1. / (1. + np.exp(-x)),但对负值更稳定

以上是关于logistic / sigmoid函数实现数值精度的主要内容,如果未能解决你的问题,请参考以下文章

[机器学习实战] Logistic回归

R语言实现sigmoid激活函数并可视化

回归1——Logistic回归

Logistic函数(sigmoid函数)

1.2 Logistic回归

机器学习实战精读--------logistic回归