【问题标题】:difference between numpy dot() and inner()numpy dot() 和 inner() 之间的区别
【发布时间】:2012-06-17 12:20:30
【问题描述】:

有什么区别

import numpy as np
np.dot(a,b)

import numpy as np
np.inner(a,b)

我尝试的所有示例都返回了相同的结果。 Wikipedia 两者都有同一篇文章?!在inner()the description 中,它说它的行为在更高维度上是不同的,但我无法产生任何不同的输出。我应该使用哪一个?

【问题讨论】:

    标签: python matrix numpy


    【解决方案1】:

    numpy.dot:

    对于二维数组,它相当于矩阵乘法,对于一维数组,它相当于向量的内积(没有复共轭)。对于 N 维,它是 a 的 最后一个轴 和 b 的 倒数第二个 的和积:

    numpy.inner:

    一维数组向量的普通内积(没有复共轭),在更高维度上是最后一个轴的和积。

    (强调我的。)

    作为一个例子,考虑这个带有二维数组的例子:

    >>> a=np.array([[1,2],[3,4]])
    >>> b=np.array([[11,12],[13,14]])
    >>> np.dot(a,b)
    array([[37, 40],
           [85, 92]])
    >>> np.inner(a,b)
    array([[35, 41],
           [81, 95]])
    

    因此,您应该使用的那个是为您的应用程序提供正确行为的那个。


    性能测试

    (请注意,我只测试一维情况,因为这是.dot.inner 给出相同结果的唯一情况。)

    >>> import timeit
    >>> setup = 'import numpy as np; a=np.random.random(1000); b = np.random.random(1000)'
    
    >>> [timeit.timeit('np.dot(a,b)',setup,number=1000000) for _ in range(3)]
    [2.6920320987701416, 2.676928997039795, 2.633111000061035]
    
    >>> [timeit.timeit('np.inner(a,b)',setup,number=1000000) for _ in range(3)]
    [2.588860034942627, 2.5845699310302734, 2.6556360721588135]
    

    所以也许.inner 更快,但我的机器目前负载相当大,所以时间不一致,也不一定非常准确。

    【讨论】:

    • @MillaWell,即使对于 2D 数组,它们也是不同的:它们仅在 1D 中是相同的。我不知道任何性能差异,有两种测试方法:reading the source(不容易)或使用timeit 进行一些分析(更容易)。
    • 我想总的来说我什么都懂。例如,在您的示例中,您将 .dot 的第一个值计算为 (1*11+2*13)。您将如何计算示例中.inner 的第一个值?
    • @MillaWell,你是对的。让c = np.dot(a,b)d = np.inner(a,b) 然后c[i,j] == sum(a[i,:] * b[:,j])d[i,j] == sum(a[i,:] * b[j,:])
    • 表达差异的另一种方式是说它们对于向量是相同的,但对于二维数组,np.dot(a, b) == np.inner(a, b.T)np.dot(a, b.T) == np.inner(a, b)
    【解决方案2】:

    np.dotnp.inner 对于一维数组是相同的,所以这可能就是您没有注意到任何差异的原因。对于 N 维数组,它们对应于常见的张量运算。

    np.inner 有时被称为高阶和低阶张量之间的“向量积”,特别是张量乘以向量,并经常导致“张量收缩”。它包括矩阵向量乘法。

    np.dot 对应于“张量积”,包括维基百科页面底部提到的情况。它通常用于将两个相似的张量相乘以产生一个新的张量。它包括矩阵-矩阵乘法。

    如果您不使用张量,则无需担心这些情况,它们的行为相同。

    【讨论】:

    • 看起来np.dot 现在(即在 Python 3 中)无论维度如何都是矩阵乘法。因此,即使对于一维数组,它也不同于 np.inner
    • 我在 NumPy 1.13.3 和 Python 3.6.3 中看到了相同的结果。你用的是什么版本?举个例子也不错。
    【解决方案3】:

    inner 无法正常处理复杂的二维数组,请尝试相乘

    及其转置

    array([[ 1.+1.j,  4.+4.j,  7.+7.j],
           [ 2.+2.j,  5.+5.j,  8.+8.j],
           [ 3.+3.j,  6.+6.j,  9.+9.j]])
    

    你会得到

    array([[ 0. +60.j,  0. +72.j,  0. +84.j],
           [ 0.+132.j,  0.+162.j,  0.+192.j],
           [ 0.+204.j,  0.+252.j,  0.+300.j]])
    

    有效地将行乘以行,而不是行乘以列

    【讨论】:

      【解决方案4】:

      对于 1 维和 2 维数组,numpy.inner 用作转置第二个矩阵然后相乘。 所以对于:

      A = [[a1,b1],[c1,d1]]
      B = [[a2,b2],[c2,d2]]
      numpy.inner(A,B)
      array([[a1*a2 + b1*b2, a1*c2 + b1*d2],
             [c1*a2 + d1*b2, c1*c2 + d1*d2])
      

      我使用以下示例解决了这个问题:

      A=[[1  ,10], [100,1000]]
      B=[[1,2], [3,4]]
      numpy.inner(A,B)
      array([[  21,   43],
             [2100, 4300]])
      

      这也解释了一维的行为,numpy.inner([a,b],[c,b]) = ac+bdnumpy.inner([[a],[b]], [[c],[d]]) = [[ac,ad],[bc,bd]]。 这是我的知识范围,不知道它对更高维度有什么作用。

      【讨论】:

        【解决方案5】:

        在高维空间中,内积和点积有很大的不同。下面是 2x2 矩阵和 3x2 矩阵的示例 x = [[a1,b1],[c1,d1]] y= [[a2,b2].[c2,d2],[e2,f2]

        np.inner(x,y)

        输出 = [[a1xa2+b1xb2 ,a1xc2+b1xd2, a1xe2+b1f2],[c1xa2+d1xb2, c1xc2+d1xd2, c1xe2+d1xf2]]

        但在点积的情况下,输出显示以下错误,因为您不能将 2x2 矩阵与 3x2 相乘。

        ValueError:形状 (2,2) 和 (3,2) 未对齐:2 (dim 1) != 3 (dim 0)

        【讨论】:

          【解决方案6】:

          我编写了一个快速脚本来练习内积和点积数学。它真的帮助我感受到了不同之处:

          你可以在这里找到代码:

          https://github.com/geofflangenderfer/practice_inner_dot

          【讨论】:

          • 对否决票有什么解释吗?这帮助了我,我认为它也会帮助其他人。
          • 您能否在答案中包含基本代码。
          猜你喜欢
          • 2011-09-09
          • 1970-01-01
          • 2013-07-04
          • 2018-02-09
          • 2022-01-04
          • 2016-11-16
          • 2014-05-25
          • 2018-05-01
          • 2021-09-06
          相关资源
          最近更新 更多