代码之家  ›  专栏  ›  技术社区  ›  Leo

Numpy sum()出现“keepdims”错误

  •  5
  • Leo  · 技术社区  · 7 年前

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

    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

    import numpy
    numpy.version.version
    >> 1.12.1
    

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

    1 回复  |  直到 4 年前
        1
  •  9
  •   smci    4 年前

    注意,在 keepdims 中的参数 docs for numpy.sum()

    keepdims公司 : 布尔,可选
    如果设置为True,则减少的轴将保留在结果中,作为尺寸为1的尺寸。使用此选项,结果将针对输入阵列正确广播。
    如果传递了默认值,则 keepdims公司 sum 子类方法 ndarray 总和 方法未实现 keepdims公司 将提出任何例外情况。

    numpy.ndarray ,则如果相应的 尚未使用它定义子类的函数。

    注意,在您的错误中,它引用了行 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)
    

    这里有两件事需要注意:一是 总和 作用 分析您的 keepdims公司 变量,因为它将其拉到了线以上 1812 然后把它放到另一个函数中,这样你就知道错误不是你使用变量的方式。另一个重要的是 1812 你犯的错误只是在执行 type(a) is not mu.ndarray ,即,如果您使用的类与 恩达赖 . 这正是文件所引用的内容。如果你有一个不同的类,那么他们需要实现这个 总和 使用keepdims参数

    其他类,如 np.matrix 例如,将有一个不同的和函数,而且似乎,即使在 numpy 1.13.x , 总和 对于 np。矩阵 类型不支持 keepdim 参数(因为在 ,矩阵 总是 是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.]])
    

    但是有一个 np。矩阵 ,它没有:

    >>> 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'
    

    但是,大多数数组/矩阵类型的对象可以轻松地在 努比 具有 np.array(<object>) ,这应该可以解决中大多数子类对象的问题 努比 很可能是你的问题。您也可以简单地将结果包装回 np。矩阵

    >>> B = np.matlib.eye(4)
    >>> B = np.array(B)
    >>> np.sum(B, axis=1, keepdims=True)
    array([[ 1.],
           [ 1.],
           [ 1.],
           [ 1.]])
    

    但是,如果对象的类 np。矩阵 keepdims公司 争论毫无意义。矩阵是 总是 2D,所以 函数不会降维,因此参数不会做任何事情。这就是为什么它没有为矩阵实现。