关于python:numpy dot()和inner()之间的区别

difference between numpy dot() and inner()

之间有什么区别

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

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

我尝试过的所有示例都返回了相同的结果。 维基百科上有相同的文章吗? 在inner()的描述中,它说它的行为在更高维度上是不同的,但是我无法产生任何不同的输出。 我应该使用哪一个?


numpy.dot

For 2-D arrays it is equivalent to matrix multiplication, and for 1-D arrays to inner product of vectors (without complex conjugation). For N dimensions it is a sum product over the last axis of a and the second-to-last of b:

numpy.inner

Ordinary inner product of vectors for 1-D arrays (without complex conjugation), in higher dimensions a sum product over the last axes.

(强调我的。)

作为示例,请考虑具有2D数组的示例:

1
2
3
4
5
6
7
8
>>> 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给出相同结果的唯一情况。)

1
2
3
4
5
6
7
8
>>> 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也许更快,但是目前我的机器已经加载了很多东西,所以时间安排不一致,也不一定很准确。


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

np.inner有时被称为高阶和低阶张量之间的"向量积",尤其是张量乘以向量,通常会导致"张量收缩"。它包括矩阵向量乘法。

np.dot对应于"张量积",并且包括Wikipedia页面底部提到的情况。它通常用于两个相似张量的乘法以产生新的张量。它包括矩阵矩阵乘法。

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


对于一维和二维数组,numpy.inner用作转置第二个矩阵,然后相乘。
因此对于:

1
2
3
4
5
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])

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

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

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


内部无法正常处理复杂的2D数组,请尝试相乘

及其转置

1
2
3
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]])

你会得到

1
2
3
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]])

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


高维空间中的内积和点积之间存在很大差异。以下是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)


我编写了一个快速的脚本来练习内部和点积数学。它确实帮助我了解了这种差异:

enter image description here

您可以在此处找到代码:

https://github.com/geofflangenderfer/practice_inner_dot