2017-01-14 16 views
4

私はサイズ(M、N、N)の3次元テンソルAを持っています。私はまた、私が可能効率的な方法でそれを実装するIが大きくなる可能性が最速の方法

enter image description here

寸法Nを計算する長さMの重みベクトルpを有します。私は次のコードを使用しています:

私は、これを実現するためのより高速で効率的な方法があるかどうかを知りたいと思います。これが重要な理由は、Nが大きいときには、上記の可変温度がこれらのN * N行列のMを格納するためです。だから私は "for loop"を使うことができると思っているかもしれませんが、ループについてはリスト内包よりも遅いと読んでいます。

答えて

2

少なくとも私はそれをテストしたテンソルから、このスニペットが速く3倍までです:

sum(np.einsum('ij...,i->ij...', A, p)) 

ここで共有された様々な方法についての比較です:

base  = sum(np.array([p[m]*A[m] for m in range(M)])) 
einsum1 = sum(np.einsum('ij...,i->ij...', A, p)) 
einsum2 = np.einsum('ijk,i->jk', A, p) 
einsum3 = np.einsum('ij...,i->j...', A, p) 
dot  = p.dot(A.reshape(A.shape[0],-1)).reshape(A.shape[1],-1) 
tensordot = np.tensordot(p, A, (0, 0)) 

M = 1000、N = 100(ベースと比較して):

einsum1 = 1.11x 
einsum2 = 5.83x 
einsum3 = 6.26x 
dot  = 8.60x 
tensordot = 9.83x 
+0

np.tensordot(p、A、(0,0))はどうですか? – pikachuchameleon

+0

テンソル(テンソル)は、テンソルが大きいほど高速です(M = 1000、N = 100の場合は10倍速くなります)。 –

+0

上記のエインサム法よりも速いのですか? – pikachuchameleon

0
In [24]: A=np.arange(3*2*2).reshape(3,2,2)  
In [25]: p=np.array([1,2,3]) 

In [26]: temp=np.array([p[m]*A[m] for m in range(len(p))]) 
In [27]: sum(temp) # python sum 
Out[27]: 
array([[32, 38], 
     [44, 50]]) 

In [28]: np.einsum('i...,i->...',A,p) 
Out[28]: 
array([[32, 38], 
     [44, 50]]) 

ijk,i->jkも有効です。

必ずしも速いわけではありませんが、tempは簡単なブロードキャストで計算できます。 np.sum(..., axis=0)は、Python sum()に相当します。

In [30]: (A*p[:,None,None]).sum(axis=0) 
Out[30]: 
array([[32, 38], 
     [44, 50]]) 
関連する問題