问题:
在使用sigmoid函数的时候遇到了这个错误:
yyh=1/(1+np.power(np.e,-yh))
问题分析:
溢出就是数太大,计算机已经表示不了了。我们当然会想,怎么会溢出呢?因为我们注意到这里使用了指数,指数的增长速度是非常块的, e 1000 e^{1000} e1000这个数估计计算机都表示不了,因为太大了。
我们猜测:是否是我们的 y h yh yh有一个非常小的负数,然后取负号就变成特别大的正数,然后指数一下就溢出。
果然如此,这里相当于计算了
e
1151
e^{1151}
e1151,所以当然会溢出了。
理论分析:
y = 1 1 + e − x y=\frac{1}{1+e^{-x}} y=1+e−x1
当x为正数,很大的时候,不会溢出,因为
e
−
x
e^{-x}
e−x趋近于0,没什么好溢出的。
当x为负数,很小的时候,会溢出,如上面的情况。
所以我们修正一下我们的sigmoid函数,不要直接上面这么用。将
yyh=1/(1+np.power(np.e,-yh))
换成:
def sigmoid(x):
if x>=0:
return 1.0/(1+np.power(np.e,-x))
else:#为负数的时候,对sigmoid函数的优化,避免了出现极大的数据溢出
return np.power(np.e,x)/(1+np.power(np.e,x))
yyh=sigmoid(yh)
注意:上面并没有修改sigmoid函数,只是把公式换了一种等价描述,但是却克服了计算机会溢出的缺点。
即:
y = 1 1 + e − x = e x e x + 1 y=\frac{1}{1+e^{-x}}=\frac{e^{x}}{e^{x}+1} y=1+e−x1=ex+1ex
但是当x为正的时候,不要使用第2种公式形式,不然溢出。当x为负的时候,才使用,但不使用第一种公式形式,这就是优化的sigmoid函数(仅仅在计算机中才需要优化,数学中是完全等价的)。