logistic / sigmoid function implementation numerical precision

懵懂的女人 提交于 2019-12-05 01:37:36
Alex Riley

It's really just for stability - putting in values that are very large in magnitude might return unexpected results otherwise.

If expit was implemented just as 1 / (1 + exp(-x)) then putting a value of -710 into the function would return nan, whereas -709 would give a value close to zero as expected. This is because exp(710) is too big to be a double.

The branching in the code just means that this scenario is avoided.

See also this question and answer on Stack Overflow.

Seems it would be more efficient to use:

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

unless you need number with 10^-309 precision (see below) which seems overkill!

>>> 1 / (1 + math.exp(709.78))
5.5777796105262746e-309

Another way to do it would be

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

Since np.exp(x) / (np.exp(x) + np.exp(0)) is equivalent to 1. / (1. + np.exp(-x)) but more stable for negative values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!