2017-09-18 7 views
1

は私がなど達成バッチ行列tensordot

私は持っていない使用してこれを翻訳していますライブラリを、ちょうどtensordot用いたドットと整形np.matmul並列行列の乗算と同じ動作を達成しようとしている使用して乗算matmulは並列乗算をサポートし、ドットとテンソードだけをサポートします。

さらに、最初のディメンションを反復しないようにしたいので、行列の乗算と再シェイプのセットを使用してこれを実行したいとします(BLAS/GPUを使用して実行するには、並行して)。ここで

は一例です:

import numpy as np 

angles = np.array([np.pi/4, 2*np.pi/4, 2*np.pi/4]) 

vectors = np.array([ [1,0],[1,-1],[-1,0]]) 

s = np.sin(angles) 
c = np.cos(angles) 

rotations = np.array([[c,s],[-s,c]]).T 

print rotations 

print vectors 

print("Correct: %s" % np.matmul(rotations, vectors.reshape(3,2,1))) 

# I want to do this using tensordot/reshaping, i.e just gemm BLAS operations underneath 
print("Wrong: %s" % np.tensordot(rotations, vectors, axes=(1,1))) 

これの出力は次のとおりです。

Correct: [[[ 7.07106781e-01] 
    [ 7.07106781e-01]] 

[[ 1.00000000e+00] 
    [ 1.00000000e+00]] 

[[ -6.12323400e-17] 
    [ -1.00000000e+00]]] 


Wrong: [[[ 7.07106781e-01 1.11022302e-16 -7.07106781e-01] 
    [ -7.07106781e-01 -1.41421356e+00 7.07106781e-01]] 

[[ 6.12323400e-17 -1.00000000e+00 -6.12323400e-17] 
    [ -1.00000000e+00 -1.00000000e+00 1.00000000e+00]] 

[[ 6.12323400e-17 -1.00000000e+00 -6.12323400e-17] 
    [ -1.00000000e+00 -1.00000000e+00 1.00000000e+00]]] 

私は同じ結果を得るために第二の発現を変更することができる方法はありますまず、ドット/テンダードットを使うだけです。

は、私はそれが可能であると信じ、そしてsome comments onlineを見てきましたが、決してどんな例が

+0

'tensordot'スワップをし、再形成するので、問題は(当時と)' dot'に減少します。いくつかの 'matmul'演算は、もっと大きな '外側'計算から対角をとることで実現できます。 – hpaulj

+0

はい、私は対角線を取っていることに気付きましたが、潜在的にはそれほど効率が悪いと考えていました –

答えて

2

私たちは整列1を維持し、出力でもそれを維持する必要がありません。したがって、tensordot/dotはここでは機能しません。 More info on tensordotはどうしてそれがどうしてそうでないのかについて何らかの説明をするかもしれません。しかし、ほとんどの場合(私の経験では)np.matmulよりわずかに速いと見なされるnp.einsumを使用することができます。

実装では、このようになります - また

np.einsum('ijk,ik->ij',rotations, vectors) 

は、所望の出力が薄暗い1つの末尾のシングルトンを持っているようです。だから、そのように、None/np.newaxisとそこに新しい軸を追加 -

np.einsum('ijk,ik->ij',rotations, vectors)[...,None] 
+0

"このライブラリを使用すると、並列乗算をサポートするmatmulはありません。私はeinsumを使うこともできません。他のアイデア? –

+0

@ChrisBamfordどのような図書館ですか?それはテンソルフローですか? – Divakar

+0

@ChrisBamford Nah、 'dot/tensordot'ではベクトル化された方法ではできません。だから、私はちょうどループスルーと言うでしょう。 – Divakar

関連する問題