我在Numpy中有四个多维张量v[i,j,k]
,a[i,s,l]
,w[j,s,t,m]
,x[k,t,n]
,我试图计算张量z[l,m,n]
,由下式给出:
z[l,m,n] = sum_{i,j,k,s,t} v[i,j,k] * a[i,s,l] * w[j,s,t,m] * x[k,t,n]
所有的张量都相对较小(比如说总共少于32k个元素),但是我需要多次执行此计算,因此我希望函数的开销尽可能小。你知道吗
我尝试使用numpy.einsum
实现它,如下所示:
z = np.einsum('ijk,isl,jstm,ktn', v, a, w, x)
但是速度很慢。我还尝试了以下numpy.tensordot
调用序列:
z = np.zeros((a.shape[-1],w.shape[-1],x.shape[-1]))
for s in range(a.shape[1]):
for t in range(x.shape[1]):
res = np.tensordot(v, a[:,s,:], (0,0))
res = np.tensordot(res, w[:,s,t,:], (0,0))
z += np.tensordot(res, x[:,s,:], (0,0))
在双for循环的内部对s
和t
求和(这两个s
和t
都很小,所以这不是太大的问题)。这样做效果更好,但仍然没有我预期的那么快。我认为这可能是因为tensordot
在获取实际产品之前需要在内部执行的所有操作(例如,排列轴)。你知道吗
我想知道是否有一种更有效的方法来实现Numpy中的这种操作。我也不介意在Cython中实现这一部分,但是我不确定应该使用什么样的算法。你知道吗
部分使用^{} ,你可以像这样矢量化-
运行时测试和验证输出-
案例1:
案例2(更大的数据量):
相关问题 更多 >
编程相关推荐