numpy sum()出现“ keepdims”错误

Leo*_*Leo 1 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)
    ...
Run Code Online (Sandbox Code Playgroud)

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

<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'
Run Code Online (Sandbox Code Playgroud)

还有一个类似的问题Numpy sum keepdims错误,它表示numpy的版本应大于1.7。我已经检查了我的numpy版本:

import numpy
numpy.version.version
>> 1.12.1
Run Code Online (Sandbox Code Playgroud)

现在,我对该错误的发生方式感到困惑。

alk*_*asm 5

请注意,在文档的keepdims变量下指出:numpy.sum()

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

因此在这里说明,如果您使用的子类numpy.ndarray,那么如果sum尚未为该子类定义相应的函数,则会收到此错误。

请注意,在你的错误,它引用行1812numpy/core/fromnumeric.py。在实际的numpy1.12.x源代码中看一下上下文:

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)
Run Code Online (Sandbox Code Playgroud)

这里需要注意两点:sum函数确实解析了keepdims变量,因为它将变量拉到了行上方1812并试图将其放在另一个函数中,所以您知道错误不是您使用变量的方式。另一个重要的事情是,行1812,你要示数上只执行,如果 type(a) is not mu.ndarray您正在使用不同的类,即ndarray。这正是文档所引用的内容。如果您有其他类,则他们需要使用keepdims参数来实现此sum功能,否则,将引发错误。

诸如此类的其他类np.matrix将具有不同的sum函数,并且即使在in中numpy 1.13.xsum对于np.matrix类型也似乎不支持该keepdim参数(因为in中numpy,矩阵始终是2D的)。例如,它可以与配合使用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.]])
Run Code Online (Sandbox Code Playgroud)

但是使用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'
Run Code Online (Sandbox Code Playgroud)

但是,大多数阵列/矩阵类型对象可以很容易地转换为一个数组中numpynp.array(<object>),而本应解决在大多数子类对象的问题numpy,并有可能您的问题。np.matrix如果需要,您也可以简单地将结果包装回a 中。

>>> B = np.matlib.eye(4)
>>> B = np.array(B)
>>> np.sum(B, axis=1, keepdims=True)
array([[ 1.],
       [ 1.],
       [ 1.],
       [ 1.]])
Run Code Online (Sandbox Code Playgroud)

但是,如果你的类的对象一个np.matrix类型,那么keepdims争论是没有意义的。矩阵始终是 2D的,因此该sum函数不会缩小维,因此该参数不会执行任何操作。这就是为什么它不用于矩阵的原因。