我在堆栈溢出上阅读了很多,但我仍然无法理解如何避免溢出错误。我正在建立一个使用sigmoid function的神经网络。 但我不能继续转换或找到解决这些错误的方法。
def activation(x):
return 1/(1+np.exp(-x))
def dactivation(x):
return activation(x)*(1-activation(x))
def propagateb(self, target, lrate=8.1, momentum=0.1):
deltas = []
error = target - self.layers[-1]
delta = error*dactivation(self.layers[-1])
deltas.append(delta)
for i in range(len(self.shape)-2,0,-1):
delta =np.dot(deltas[0],self.weights[i].T)*dactivation(self.layers[i])
deltas.insert(0,delta)
for i in range(len(self.weights)):
layer = np.atleast_2d(self.layers[i])
delta = np.atleast_2d(deltas[i])
dw = np.dot(layer.T,delta)
self.weights[i] += lrate*dw + momentum*self.dw[i]
self.dw[i] = dw
# Return error
return (error**2).sum()
提高
ann.py:5: RuntimeWarning: overflow encountered in exp
return 1/(1+np.exp(-x))
答案 0 :(得分:4)
SciPy comes with a function to do that,它不会给你那个警告:
scipy.special.expit(x)
答案 1 :(得分:0)
传入的数据似乎必须是整数,尽管此激活函数应该返回一个浮点数。我认为修复就像
一样简单return 1./(1.+np.exp(-x))
我猜想如果没有这个改变,代码就会尝试进行整数除法,从而产生错误。
答案 2 :(得分:0)
使用numpy整数时必须小心,因为它们不具有任意精度,如Can Integer Operations Overflow in Python?所述
对于numpy double,该范围为(-1.79769313486e+308, 1.79769313486e+308)
。
另请查看此answer,其中描述得非常好。
Here是关于numpy dtypes及其允许范围的更多信息。
答案 3 :(得分:0)
该想法是,应避免在exp(something)
过大的情况下调用something
。因此,请避免在exp(x)
时使用x >> 0
,并避免在exp(-x)
时使用x << 0
。
为了实现这一点,您可以先编写一个适用于x> 0的表达式,再编写一个适用于x <0的表达式。
1/(1+exp(-x))
exp(x)
来重写该表达式,得出exp(x) / (1+exp(x))
。如您所见,这里不再exp(-x)
。您可以找到一种适用于两种情况的表达式:
鉴于x是一个矩阵,我在https://github.com/thirionjl/chains/blob/master/chains/operations/activation_ops.py#L42的个人实验中使用了np.exp(np.fmin(x, 0)) / (1 + np.exp(-np.abs(x)))