Numpy sum()得到了'keepdims'错误

时间:2017-09-26 07:16:51

标签: python numpy

这是神经网络代码示例的一段:

def forward_step(X, W, b, W2, b2):
    hidden_layer = np.maximum(0, np.dot(X, W) + b)
    scores = np.dot(hidden_layer, W2) + b2
    exp_scores = np.exp(scores)
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
    ...

上面显示的代码的最后一行引发了错误:

<ipython-input-49-d97cff51c360> in forward_step(X, W, b, W2, b2)
     14     scores = np.dot(hidden_layer, W2) + b2
     15     exp_scores = np.exp(scores)
---> 16     probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
     17     corect_logprobs = -np.log(probs[range(X.shape[0]), y])

/Users/###/anaconda/lib/python3.6/site-packages/numpy/core/fromnumeric.py in sum(a, axis, dtype, out, keepdims)
   1810             pass
   1811         else:
-> 1812             return sum(axis=axis, dtype=dtype, out=out, **kwargs)
   1813     return _methods._sum(a, axis=axis, dtype=dtype,
   1814                          out=out, **kwargs)

TypeError: sum() got an unexpected keyword argument 'keepdims'

有一个类似的问题Numpy sum keepdims error表示numpy的版本应该大于1.7。我查看了我的numpy版本:

import numpy
numpy.version.version
>> 1.12.1

现在我对这个错误是如何发生感到困惑。

1 个答案:

答案 0 :(得分:3)

请注意,docs for numpy.sum()下的keepdims参数指出:

  

keepdims bool,可选
  如果将其设置为True,则缩小的轴将作为尺寸为1的尺寸保留在结果中。使用此选项,结果将正确地对输入数组进行广播   如果传递了默认值,那么 keepdims 将不会传递给sum子类的ndarray方法,但任何非默认值都将是。{如果子类sum方法未实现 keepdims ,则会引发任何异常。

所以它在此声明,如果你正在使用numpy.ndarray的子类,那么如果子类的相应sum函数没有&那么你就会得到这个错误已经定义了它。

请注意,在您的错误中,它会引用1812中的行numpy/core/fromnumeric.py。在实际numpy 1.12.x source

中查看上下文中的内容
kwargs = {}
if keepdims is not np._NoValue:
    kwargs['keepdims'] = keepdims
if isinstance(a, _gentype):
    res = _sum_(a)
    if out is not None:
        out[...] = res
        return out
    return res
if type(a) is not mu.ndarray:
    try:
        sum = a.sum
    except AttributeError:
        pass
    else:
        return sum(axis=axis, dtype=dtype, out=out, **kwargs)
return _methods._sum(a, axis=axis, dtype=dtype,
                     out=out, **kwargs)

这里有两件事需要注意:sum函数已经解析了您的keepdims变量,因为它将其拉到了行1812之上并试图放入它在另一个函数中,所以你知道错误不是你使用变量的方式。另一个重要的事情是,您错误的行1812仅在 type(a) is not mu.ndarray时执行,即如果您正在使用其他类比ndarray。这正是文档引用的内容。如果你有不同的类,那么他们需要使用keepdims参数实现这个sum函数,如果他们不这样做会引发错误。

例如np.matrix之类的其他类将具有不同的求和函数,即使在numpy 1.13.x中,sum类型的np.matrix似乎也不支持{ {1}}参数(因为在keepdim中,矩阵总是是2D)。例如,它适用于numpy

np.array

但是使用>>> import numpy as np >>> A = np.eye(4) >>> A array([[ 1., 0., 0., 0.], [ 0., 1., 0., 0.], [ 0., 0., 1., 0.], [ 0., 0., 0., 1.]]) >>> np.sum(A, axis=1, keepdims=True) array([[ 1.], [ 1.], [ 1.], [ 1.]]) ,它不会:

np.matrix

但是,大多数数组/矩阵类型对象可以很容易地转换为>>> import numpy.matlib >>> B = np.matlib.eye(4) >>> np.sum(B, axis=1, keepdims=True) Traceback (most recent call last): File "<stdin>", line 1, in <module> File ".../numpy/core/fromnumeric.py", line 1832, in sum return sum(axis=axis, dtype=dtype, out=out, **kwargs) TypeError: sum() got an unexpected keyword argument 'keepdims' 中带有numpy的数组,这可以解决np.array(<object>)中大多数子类对象的问题。可能是你的问题。如果需要,您还可以将结果简单地包装回numpy

np.matrix

但是,如果您的对象>>> B = np.matlib.eye(4) >>> B = np.array(B) >>> np.sum(B, axis=1, keepdims=True) array([[ 1.], [ 1.], [ 1.], [ 1.]]) 类型,那么np.matrix参数是没有意义的。矩阵总是 2D,因此keepdims函数不会减少维度,因此参数不会做任何事情。这就是为什么它没有为矩阵实现的原因。