3

ドキュメントによると:

N 次元の場合、 は の最後の軸と の最後から 2 番目のdot軸の積の合計です。ab

dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])

aの最後の軸と最後から 2 番目の軸の合計積を計算したいのですbが、残りの軸は同じ形状であるため、残りの軸のデカルト積を形成しません。例を挙げて説明しましょう:

a = np.random.normal(size=(11, 12, 13))
b = np.random.normal(size=(11, 12, 13, 13))
c = np.dot(a, b)
c.shape # = (11, 12, 11, 12, 13)

しかし、私は形をしたいと思います(11, 12, 13)。ブロードキャストを使用して目的の効果を達成できます

c = np.sum(a[..., None] * b, axis=-2)
c.shape # = (11, 12, 13)

np.sumしかし、私の配列は比較的大きいので、 ではサポートされていないように見えますがでサポートされている、並列化された BLAS 実装の機能を使用したいと考えていますnp.dot。これを達成する方法についてのアイデアはありますか?

4

2 に答える 2

3

あなたが使用することができますnp.einsum-

c = np.einsum('ijk,ijkl->ijl',a,b)
于 2016-05-05T09:20:52.393 に答える
2

次のものも使用できますnp.matmul

c = np.matmul(a[..., None, :], b)[..., 0, :]

これは、Python 3.5 以降の new@演算子と同等です。

c = (a[..., None, :] @ b)[..., 0, :]

パフォーマンスに大きな違いはありません-例の配列に対して何かnp.einsumがわずかに高速であると思われる場合:

In [1]: %%timeit a = np.random.randn(11, 12, 13); b = np.random.randn(11, 12, 13, 13)
   ....: np.einsum('...i,...ij->...j', a, b)
   ....: 
The slowest run took 5.24 times longer than the fastest. This could mean that an
intermediate result is being cached.
10000 loops, best of 3: 26.7 µs per loop

In [2]: %%timeit a = np.random.randn(11, 12, 13); b = np.random.randn(11, 12, 13, 13)
np.matmul(a[..., None, :], b)[..., 0, :]
   ....: 
10000 loops, best of 3: 28 µs per loop
于 2016-05-05T15:36:53.590 に答える