python中使用numpy的多线性映射
在python中,我有一个大小为python中使用numpy的多线性映射,python,arrays,performance,numpy,Python,Arrays,Performance,Numpy,在python中,我有一个大小为(n,n,n)的三维数组T,和一个大小为(n,k)的二维数组 在线性代数中,由T定义并应用于W的多线性映射在code中为: X3 = np.zeros((k,k,k)) for i in xrange(k): for j in xrange(k): for t in xrange(k): for l in xrange(n): for m in xrang
(n,n,n)
的三维数组T
,和一个大小为(n,k)
的二维数组
在线性代数中,由T
定义并应用于W
的多线性映射在code中为:
X3 = np.zeros((k,k,k))
for i in xrange(k):
for j in xrange(k):
for t in xrange(k):
for l in xrange(n):
for m in xrange(n)
for h in xrange(n):
X3[i, j, t] += M3[l, m, h] * W[l, i] * W[m, j] * W[h, t]
看
供参考
这很慢。我想知道numpy中是否有任何替代或预构建函数可以加速运算。爱因斯坦求和约定?使用 编辑: 出于好奇,我刚刚运行了一些基准测试,将
np.einsum
与Divakar的方法进行比较。这种差异与np.einsum
有很大的不同
import numpy as np
def approach1(a, b):
x = np.einsum('lmh,li,mj,ht->ijt', a, b, b, b)
def approach2(a, b):
p1 = np.tensordot(b, a, axes=(0,0))
p2 = np.tensordot(p1, b, axes=(1,0))
x = np.tensordot(p2, b, axes=(1,0))
n = 100
k = 10
a = np.random.random((n, n, n))
b = np.random.random((n, k))
%timeit approach1(a, b) # => 1 loop, best of 3: 26 s per loop
%timeit approach2(a, b) # => 100 loops, best of 3: 4.23 ms per loop
有一些关于它的讨论。这一切似乎都归结为
np.einsum
试图实现的通用性,其代价是能够将计算转移到低级线性代数包中。下面是一种使用一系列点积的方法-
# Get partial products and thus reach to final output
p1 = np.tensordot(W,M3,axes=(0,0))
p2 = np.tensordot(p1,W,axes=(1,0))
X3out = np.tensordot(p2,W,axes=(1,0))
您典型的
n
和k
是什么?n可以是大的(高达100000)k可以是1000,或多或少。因此,您可以使用一个形状为(10000100001000010000)
的数组M3
作为输入?这不是太大以至于不能适应RAM吗?@ UlderiqueDemoitre,如果下面的任何一个答案都解决了你的问题,请点击检查标记来考虑。这向更广泛的社区表明,你已经找到了一个解决方案,并给回答者和你自己带来了一些声誉。没有义务这么做。对不起,我对我的帖子进行了编辑,以避免使用Swapax,这既是为了性能,也是为了简洁。你能更新一下计时测试吗?我不期望有很大的变化,但主要是与适当的职位。谢谢@迪瓦卡:完成了!与以前的代码相差10倍。
# Get partial products and thus reach to final output
p1 = np.tensordot(W,M3,axes=(0,0))
p2 = np.tensordot(p1,W,axes=(1,0))
X3out = np.tensordot(p2,W,axes=(1,0))