2016-12-14 36 views
1

私はeinsum numpy: C(24,79)とD(1,1,24,1)を使って乗算したい次元の異なる2つの行列を持っています。私は次元(1,1,79,1)で行列を求めたいと思います。異なる次元の行列を掛け算する

私は2つの方法でそれらを乗算することを試みた:

tmp = np.einsum('px, klpj ->klxj', C, D) 

tmp = np.einsum('xp, klpj ->klxj', C, D) 

と私は異なる結果を得ています。どうして?これらの行列を乗算する正しい方法は何ですか?本当にsum-reductionにはなりませんシングルトン寸法により

+2

最初のものが正しいです。私は2番目のものを再現できません。それはエラーを投げます(それはすべきです)。 – FTP

+0

投稿されたソリューションがあなたに役立つ/あなたを助けたかどうか不思議ですか? – Divakar

+0

正直なところ、私はまだ最初の答えが正しい理由を理解することにまだ苦労しています。行列Dが(1,1,79,1)次元を有する場合、それは同じであろうか? – Monica

答えて

0

、我々はそれを解決するために、さらに2つのアプローチを持っているnp.tensordotまたはnp.dotでマトリックス乗算を導入することができます -

np.tensordot(C,D,axes=([0],[2])).swapaxes(0,2) 

D.ravel().dot(C).reshape(1,1,C.shape[1],1) 

の結果を確認します -

In [26]: tmp = np.einsum('px, klpj ->klxj', C, D) 

In [27]: out = np.tensordot(C,D,axes=([0],[2])).swapaxes(0,2) 

In [28]: np.allclose(out, tmp) 
Out[28]: True 

In [29]: out = D.ravel().dot(C).reshape(1,1,C.shape[1],1) 

In [30]: np.allclose(out, tmp) 
Out[30]: True 

ランタイム試験 -

In [31]: %timeit np.einsum('px, klpj ->klxj', C, D) 
100000 loops, best of 3: 5.84 µs per loop 

In [32]: %timeit np.tensordot(C,D,axes=([0],[2])).swapaxes(0,2) 
100000 loops, best of 3: 18.5 µs per loop 

In [33]: %timeit D.ravel().dot(C).reshape(1,1,C.shape[1],1) 
100000 loops, best of 3: 3.29 µs per loop 

大きなデータセットでは、行列乗算で目に見えるメリットが得られます。

In [36]: C = np.random.rand(240,790) 
    ...: D = np.random.rand(1,1,240,1) 
    ...: 

In [37]: %timeit np.einsum('px, klpj ->klxj', C, D) 
    ...: %timeit np.tensordot(C,D,axes=([0],[2])).swapaxes(0,2) 
    ...: %timeit D.ravel().dot(C).reshape(1,1,C.shape[1],1) 
    ...: 
1000 loops, best of 3: 182 µs per loop 
10000 loops, best of 3: 84.9 µs per loop 
10000 loops, best of 3: 55.5 µs per loop 
関連する問題