、我々はそれを解決するために、さらに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
最初のものが正しいです。私は2番目のものを再現できません。それはエラーを投げます(それはすべきです)。 – FTP
投稿されたソリューションがあなたに役立つ/あなたを助けたかどうか不思議ですか? – Divakar
正直なところ、私はまだ最初の答えが正しい理由を理解することにまだ苦労しています。行列Dが(1,1,79,1)次元を有する場合、それは同じであろうか? – Monica