在 中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
。
在 中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
。
这实际上只是为了稳定 - 输入数量级非常大的值可能会返回意想不到的结果。
Ifexpit
的实现就像1 / (1 + exp(-x))
then 将值-710
放入函数中一样 return nan
,而-709
将给出一个接近零的值,如预期的那样。这是因为exp(710)
太大而不能成为双倍。
代码中的分支只是意味着避免了这种情况。
另请参阅Stack Overflow 上的这个问题和答案。
似乎使用它会更有效:
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))
但对于负值更稳定