理解 Tensordot
- 2025-02-21 08:48:00
- admin 原创
- 23
问题描述:
在我学会了如何使用之后einsum
,我现在正尝试了解np.tensordot
它的工作原理。
然而,我有点迷失,特别是关于参数的各种可能性axes
。
为了理解它,由于我从未练习过张量微积分,我使用以下示例:
A = np.random.randint(2, size=(2, 3, 5))
B = np.random.randint(2, size=(3, 2, 4))
在这种情况下,可能存在哪些不同np.tensordot
以及如何手动计算?
解决方案 1:
这个想法tensordot
很简单 - 我们输入数组和相应的轴,这些轴是要进行求和缩减的。参与求和缩减的轴在输出中被移除,输入数组中所有剩余的轴在输出中分散为不同的轴,保持输入数组的输入顺序。
让我们看几个具有一轴和两轴求和的样例,并交换输入的位置,看看输出中顺序是如何保持的。
一、和约法的一个轴
输入:
In [7]: A = np.random.randint(2, size=(2, 6, 5))
...: B = np.random.randint(2, size=(3, 2, 4))
...:
案例 #1:
In [9]: np.tensordot(A, B, axes=((0),(1))).shape
Out[9]: (6, 5, 3, 4)
A : (2, 6, 5) -> reduction of axis=0
B : (3, 2, 4) -> reduction of axis=1
Output : `(2, 6, 5)`, `(3, 2, 4)` ===(2 gone)==> `(6,5)` + `(3,4)` => `(6,5,3,4)`
案例 2(与案例 1 相同,但输入被交换):
In [8]: np.tensordot(B, A, axes=((1),(0))).shape
Out[8]: (3, 4, 6, 5)
B : (3, 2, 4) -> reduction of axis=1
A : (2, 6, 5) -> reduction of axis=0
Output : `(3, 2, 4)`, `(2, 6, 5)` ===(2 gone)==> `(3,4)` + `(6,5)` => `(3,4,6,5)`.
II. 和约的两个轴
输入:
In [11]: A = np.random.randint(2, size=(2, 3, 5))
...: B = np.random.randint(2, size=(3, 2, 4))
...:
案例 #1:
In [12]: np.tensordot(A, B, axes=((0,1),(1,0))).shape
Out[12]: (5, 4)
A : (2, 3, 5) -> reduction of axis=(0,1)
B : (3, 2, 4) -> reduction of axis=(1,0)
Output : `(2, 3, 5)`, `(3, 2, 4)` ===(2,3 gone)==> `(5)` + `(4)` => `(5,4)`
案例 #2:
In [14]: np.tensordot(B, A, axes=((1,0),(0,1))).shape
Out[14]: (4, 5)
B : (3, 2, 4) -> reduction of axis=(1,0)
A : (2, 3, 5) -> reduction of axis=(0,1)
Output : `(3, 2, 4)`, `(2, 3, 5)` ===(2,3 gone)==> `(4)` + `(5)` => `(4,5)`
我们可以将其扩展到尽可能多的轴。
解决方案 2:
tensordot
交换轴并重塑输入,以便可以应用于np.dot
2 个 2d 数组。然后交换并重塑回目标。实验可能比解释更容易。没有特殊的张量数学,只是扩展dot
到更高维度。tensor
只是意味着超过 2d 的数组。如果您已经熟悉,einsum
那么最简单的方法是将结果与之进行比较。
样本测试,对 1 对轴进行求和
In [823]: np.tensordot(A,B,[0,1]).shape
Out[823]: (3, 5, 3, 4)
In [824]: np.einsum('ijk,lim',A,B).shape
Out[824]: (3, 5, 3, 4)
In [825]: np.allclose(np.einsum('ijk,lim',A,B),np.tensordot(A,B,[0,1]))
Out[825]: True
另一个,对两个进行总结。
In [826]: np.tensordot(A,B,[(0,1),(1,0)]).shape
Out[826]: (5, 4)
In [827]: np.einsum('ijk,jim',A,B).shape
Out[827]: (5, 4)
In [828]: np.allclose(np.einsum('ijk,jim',A,B),np.tensordot(A,B,[(0,1),(1,0)]))
Out[828]: True
我们可以对这对做同样的(1,0)
事情。考虑到尺寸的混合,我认为没有其他组合。
解决方案 3:
上面的答案很棒,对我理解有很大帮助tensordot
。但它们没有展示操作背后的实际数学。这就是为什么我自己在 TF 2 中做了等效操作并决定在这里分享它们的原因:
a = tf.constant([1,2.])
b = tf.constant([2,3.])
print(f"{tf.tensordot(a, b, 0)} tf.einsum('i,j', a, b) - ((the last 0 axes of a), (the first 0 axes of b))")
print(f"{tf.tensordot(a, b, ((),()))} tf.einsum('i,j', a, b) - ((() axis of a), (() axis of b))")
print(f"{tf.tensordot(b, a, 0)} tf.einsum('i,j->ji', a, b) - ((the last 0 axes of b), (the first 0 axes of a))")
print(f"{tf.tensordot(a, b, 1)} tf.einsum('i,i', a, b) - ((the last 1 axes of a), (the first 1 axes of b))")
print(f"{tf.tensordot(a, b, ((0,), (0,)))} tf.einsum('i,i', a, b) - ((0th axis of a), (0th axis of b))")
print(f"{tf.tensordot(a, b, (0,0))} tf.einsum('i,i', a, b) - ((0th axis of a), (0th axis of b))")
[[2. 3.]
[4. 6.]] tf.einsum('i,j', a, b) - ((the last 0 axes of a), (the first 0 axes of b))
[[2. 3.]
[4. 6.]] tf.einsum('i,j', a, b) - ((() axis of a), (() axis of b))
[[2. 4.]
[3. 6.]] tf.einsum('i,j->ji', a, b) - ((the last 0 axes of b), (the first 0 axes of a))
8.0 tf.einsum('i,i', a, b) - ((the last 1 axes of a), (the first 1 axes of b))
8.0 tf.einsum('i,i', a, b) - ((0th axis of a), (0th axis of b))
8.0 tf.einsum('i,i', a, b) - ((0th axis of a), (0th axis of b))
对于(2,2)
形状:
a = tf.constant([[1,2],
[-2,3.]])
b = tf.constant([[-2,3],
[0,4.]])
print(f"{tf.tensordot(a, b, 0)} tf.einsum('ij,kl', a, b) - ((the last 0 axes of a), (the first 0 axes of b))")
print(f"{tf.tensordot(a, b, (0,0))} tf.einsum('ij,ik', a, b) - ((0th axis of a), (0th axis of b))")
print(f"{tf.tensordot(a, b, (0,1))} tf.einsum('ij,ki', a, b) - ((0th axis of a), (1st axis of b))")
print(f"{tf.tensordot(a, b, 1)} tf.matmul(a, b) - ((the last 1 axes of a), (the first 1 axes of b))")
print(f"{tf.tensordot(a, b, ((1,), (0,)))} tf.einsum('ij,jk', a, b) - ((1st axis of a), (0th axis of b))")
print(f"{tf.tensordot(a, b, (1, 0))} tf.matmul(a, b) - ((1st axis of a), (0th axis of b))")
print(f"{tf.tensordot(a, b, 2)} tf.reduce_sum(tf.multiply(a, b)) - ((the last 2 axes of a), (the first 2 axes of b))")
print(f"{tf.tensordot(a, b, ((0,1), (0,1)))} tf.einsum('ij,ij->', a, b) - ((0th axis of a, 1st axis of a), (0th axis of b, 1st axis of b))")
[[[[-2. 3.]
[ 0. 4.]]
[[-4. 6.]
[ 0. 8.]]]
[[[ 4. -6.]
[-0. -8.]]
[[-6. 9.]
[ 0. 12.]]]] tf.einsum('ij,kl', a, b) - ((the last 0 axes of a), (the first 0 axes of b))
[[-2. -5.]
[-4. 18.]] tf.einsum('ij,ik', a, b) - ((0th axis of a), (0th axis of b))
[[-8. -8.]
[ 5. 12.]] tf.einsum('ij,ki', a, b) - ((0th axis of a), (1st axis of b))
[[-2. 11.]
[ 4. 6.]] tf.matmul(a, b) - ((the last 1 axes of a), (the first 1 axes of b))
[[-2. 11.]
[ 4. 6.]] tf.einsum('ij,jk', a, b) - ((1st axis of a), (0th axis of b))
[[-2. 11.]
[ 4. 6.]] tf.matmul(a, b) - ((1st axis of a), (0th axis of b))
16.0 tf.reduce_sum(tf.multiply(a, b)) - ((the last 2 axes of a), (the first 2 axes of b))
16.0 tf.einsum('ij,ij->', a, b) - ((0th axis of a, 1st axis of a), (0th axis of b, 1st axis of b))
解决方案 4:
除了上述答案之外,如果将np.tensordot分解为嵌套循环,会更容易理解:
认为:
import numpy as np
a = np.arange(24).reshape(2,3,4)
b = np.arange(30).reshape(3,5,2)
那么a
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
并且b是
array([[[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9]],
[[10, 11],
[12, 13],
[14, 15],
[16, 17],
[18, 19]],
[[20, 21],
[22, 23],
[24, 25],
[26, 27],
[28, 29]]])
让
c = np.tensordot(a, b, axes=([0,1],[2,0]))
相当于
c = np.zeros((4,5))
for i in range(4):
for j in range(5):
for p in range(2):
for q in range(3):
c[i,j] += a[p,q,i] * b[q,j,p]
两个张量中具有相同维度(此处为 2 和 3)的轴可以通过对它们求和来减少。参数axes =([0,1],[2,0]) 与axes =([1,0],[0,2])相同。
最后一个c是
array([[ 808, 928, 1048, 1168, 1288],
[ 871, 1003, 1135, 1267, 1399],
[ 934, 1078, 1222, 1366, 1510],
[ 997, 1153, 1309, 1465, 1621]])
- 2025年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)