web-dev-qa-db-ja.com

3番目の軸に沿った内積

tensordotを使用してテンソル内積をnumpyで取得しようとしていますが、計算を実行するために配列をどのように再形成する必要があるのか​​わかりません。 (一般的に、私はまだテンソルの数学に不慣れです。)

私が持っています

_arr = np.array([[[1, 1, 1],
                [0, 0, 0],
                [2, 2, 2]],

               [[0, 0, 0],
                [4, 4, 4],
                [0, 0, 0]]])

w = [1, 1, 1]
_

そして、_axis=2_に沿って内積を取りたいので、行列ができます

_array([[3, 0, 6],
       [0, 12, 0]])
_

これに適したnumpy構文は何ですか? np.tensordot(arr, [1, 1, 1], axes=2)ValueErrorを発生させるようです。

14
hlin117

削減は、arrの場合はaxis=2に、wの場合はaxis=0に沿って行われます。したがって、 np.tensordot の場合、解は-になります。

np.tensordot(arr,w,axes=([2],[0]))

または、 np.einsum -を使用することもできます。

np.einsum('ijk,k->ij',arr,w)

np.matmul も機能します

np.matmul(arr, w)

ランタイムテスト-

In [52]: arr = np.random.Rand(200,300,300)

In [53]: w = np.random.Rand(300)

In [54]: %timeit np.tensordot(arr,w,axes=([2],[0]))
100 loops, best of 3: 8.75 ms per loop

In [55]: %timeit np.einsum('ijk,k->ij',arr,w)
100 loops, best of 3: 9.78 ms per loop

In [56]: %timeit np.matmul(arr, w)
100 loops, best of 3: 9.72 ms per loop

hlin117は、Macbook Pro OS X El Capitan、numpyバージョン1.10.4でテストされています。

15
Divakar

.dotの使用は、私にとっては問題なく機能します。

>>> import numpy as np
>>> arr = np.array([[[1, 1, 1],
                     [0, 0, 0],
                     [2, 2, 2]],

                    [[0, 0, 0],
                     [4, 4, 4],
                     [0, 0, 0]]])
>>> arr.dot([1, 1, 1])
array([[ 3,  0,  6],
       [ 0, 12,  0]])

興味深いことに、他のすべての提案よりも遅いですが

2
Eric