14

在 中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

4

3 回答 3

10

这实际上只是为了稳定 - 输入数量级非常大的值可能会返回意想不到的结果。

Ifexpit的实现就像1 / (1 + exp(-x))then 将值-710放入函数中一样 return nan,而-709将给出一个接近零的值,如预期的那样。这是因为exp(710)太大而不能成为双倍。

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

另请参阅Stack Overflow 上的这个问题和答案。

于 2016-05-06T14:50:54.223 回答
4

似乎使用它会更有效:

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
于 2016-07-20T09:34:45.997 回答
1

另一种方法是

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))但对于负值更稳定

于 2017-02-01T18:15:47.110 回答