我在Python中编写了以下函数来计算标量,向量或矩阵的sigmoid函数。
def sigmoid(z):
sig = 1.0/(1.0 + np.exp(-z))
return sig
对于z的相对大的正值,e^-z
返回接近零(0)的非常小的值,因此sig的值四舍五入为1.我的最终目标是确定逻辑回归算法的成本函数。由于sigmoid正好返回1,log(1-1)
返回'nan'。如何以这样的方式解决问题:sigmoid()函数将返回正确的值而不是将e^-z
舍入为0?
当我使用均值和标准偏差对输入要素进行标准化时,它工作正常。但有没有办法让它与更大的z值一起工作?
此外,我在Matlab上尝试了同样的方法,并且在没有规范化的情况下工作正常。
>>> Z = np.array([[60, 100],[20, 80]])
>>> Z
array([[ 60, 100],
[ 20, 80]])
>>> np.exp(-Z)
array([[8.75651076e-27, 3.72007598e-44],
[2.06115362e-09, 1.80485139e-35]])
>>> 1.0/(1.0 + np.exp(-Z))
array([[1., 1.],
[1., 1.]])
正如jdehesa已经提到的,你的问题是精度限制。你可以在这里阅读更多:https://docs.python.org/2/tutorial/floatingpoint.html
您可以尝试使用Decimal类来避免舍入:
from decimal import Decimal
import numpy as np
import math
def sigmoid(z):
sig = Decimal(1.0)/(Decimal(1.0) + Decimal(np.exp(-z)))
return sig
math.log(Decimal(1)-sigmoid(60))
>>> -59.97257293350302
但这只会达到一定程度(我认为它已经失败了80)。我做了一些阅读,如果你真的需要更高的精度,你可以通过从默认值28增加以下值来改变Decimal对象的精度:
from decimal import *
getcontext().prec = 28
更多细节在这里:
https://docs.python.org/2/library/decimal.html
但是,对于大多数情况,通过逻辑检查手动处理小结果的建议可能是最好的。