python - 关于 np.einsum
问题描述
不明白下面的代码是如何实现维度的转换的?C 的形状是 [2, 3, 3, 4]。没有einsum函数如何实现下面的矩阵运算?
import numpy as np
a = np.random.randint(0, 10, (2,3,4))
b = np.random.randint(0, 10, (3, 6, 4))
c = np.einsum('bld,hid-> blhd', a,b)
解决方案
您可以在有关爱因斯坦符号的维基百科中找到更多详细信息
这意味着您有索引,b,l,h,i,d
这将迭代索引以覆盖所有输入并构建输入
我将在这里的数组使用大写字母以与索引区分开来。
C[b,l,h,d] += A[b,l,d] * B[h,i,d]
输出的形状可以如下确定。您获取每个输出轴的索引并在输入中查找相同的索引。例如,第一个轴C
被索引b
,也用于索引 的第一个轴A
,因此assert C.shape[0] == A.shape[0]
。对我们拥有的其他轴重复assert C.shape[1] == A.shape[1]
, assert C.shape[2] == B.shape[0]
, 和assert C.shape[3] == A.shape[2]
, 还有assert C.shape[3] == B.shape[2]
。
请注意,索引i
不影响将添加术语的位置,输出的每个元素都可以写为
C[b,l,h,d] = sum(A[b,l,d] * B[h,i,d] for i in range(B.shape[1]))
另请注意,i
它不用于索引A
。所以这也可以写成
C[b,l,h,d] = A[b,l,d] * B[h,:,d].sum();
或者如果你想使用矢量化操作
先扩大后缩小
C = A[:,:,None,:] * B[None,None,:,:,:].sum(-2)
扩展减少然后扩展,可能因为A
不使用i
C = A[:,:,None,:] * B.sum(-2)[None,None,:,:]
推荐阅读
- android - 使用 Cloud Firestore 的全球和仅限朋友的排行榜排名
- ruby - mac上的ruby版本的奇怪问题
- eiffel - twin vs deep_twin,is_equal vs is_deep_equal
- arrays - 可以从变量创建 PS 自定义对象吗?
- flutter - Flutter 中的圆角 LinearProgressIndicator
- java - 使登录易受 SQL 注入登录绕过
- linux - 尝试运行 xdotool 但得到“无法打开显示:(空)”
- java - 为什么 JMockit 抛出没有堆栈跟踪的 NullPointerException?
- sql - 从一个表中选择相关表中没有相应记录的所有记录不起作用
- javascript - 我的键盘事件快捷方式没有触发,我不知道为什么