如何避免numpy.exp()中的溢出

时间:2017-10-31 21:06:19

标签: python numpy exp

我在堆栈溢出上阅读了很多,但我仍然无法理解如何避免溢出错误。我正在建立一个使用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))

4 个答案:

答案 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. 使用x> 0,您可以安全地使用表达式:1/(1+exp(-x))
  2. 对于x <0,您可以通过将分子和分母乘以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)))