2

我试图理解为什么当输入为 37 时我的 sigmoid 函数会输出 1. sigmoid 函数:

import math

def sigmoid(x):
    return 1 / (1 + math.e ** -x)

我数学不好,但我认为永远不应该有 f(x) 等于 1 的时刻,对吧?也许是因为 e 常数不够精确但是我真正的问题是我想将 0 和 1 之间的数字映射到当 f(x) 为 0 时 x 是什么以及 f(x) 为 1 时 x 是什么。我的地图功能:

def p5map(n, start1, stop1, start2, stop2):
    return ((float(n)-start1)/(stop1-start1))*(stop2-start2)+start2

所以例如我想做

p5map(y, 0, 1, -37, 37)

其中 y 在 sigmoid 曲线中为 f(x),-37 和 37 分别为 f(x) 为 0 和 1。使用 -37 和 37 对我不起作用,所以我要问的是为什么它是 37,我该如何解决它,例如它在 -1 和 1 之间

4

1 回答 1

6

您正在使用只能包含 15 或 16 位有效数字的常规浮点数。当你评估math.e**-37结果是

8.533047625744083e-17

当您将其添加到一个时,您可能希望得到

1.00000000000000008533047625744083

但是计算机实际上删除了除前 16 位之外的所有数字并给出

1.000000000000000

这很简单1。事实上,添加1e-161只是给出1. 当您添加时,您确实得到了其他的东西,1e-15但这比您尝试的要大。

有几种方法可以得到你想要的。一种方法是使用 Python 的十进制模块,它为您的数字和计算添加更多有效数字,您可以添加任意数量的数字。使用十进制,

from decimal import Decimal
print(1 / (1 + Decimal(-37).exp()))

你得到

Decimal('0.9999999999999999146695237430')

和得到的 sigmoid 函数1/(1+D(37).exp())给出-37

Decimal('8.533047625744065066149031992E-17')

这不是零。

另一种解决方案是使用另一个 sigmoid 函数,与您使用的函数不同,它比您的函数更慢地接近 1。1慢慢接近的一个是

0.5 * (1 + x / (1 + abs(x)))

这样做可以37产生

0.986842105263158

远非1,结果-37

0.01315789473684209

选择您想要的解决方案。

于 2017-06-09T22:36:12.627 回答