Numpyのtensordot()関数は、2つのテンソル(3次元配列)からテンソル積を求める関数です。
2つのテンソルa とb を渡して、第三引数に (aの次元軸, bの次元軸)をタプルで渡すと、a とb の指定の次元軸の要素の積の和を求めます。第三引数に1つの整数N だけを渡した場合は、a の最後からN個目の次元軸とb の最初からN個目の次元軸の要素の積の和を求めます。
実際にサンプルコードを見ながら確認していきましょう。
1. numpy.tensordot()の使い方
まずは、numpy.outer()の書式を確認しましょう。
書き方:
np.tensordot(a, b, axes=2)
パラメーター:
引数 | 型 | 解説 |
---|---|---|
a | array_like | テンソル積を求めるためのテンソル |
b | array_like | 同上 |
axes | int or array_like of shape(2,) |
・整数N を渡した場合は、a の最後からN番目の次元軸と、b の最初からN番目の次元軸の要素を合計します。お互いの次元軸の要素数は一致している必要があります。 ・shape(2,)の配列やリストで合計を求める次元軸を指定します。最初の要素はa の次元軸、2番目の要素はb の次元軸として適用されます。指定の次元軸の要素数が揃っている必要があります。 |
戻り値:
配列 テンソル積を要素とする配列を戻します。 |
一緒に確認したい関数:
- dot
- einsum
Notes
最初はaxesの設定に戸惑うかもしれません。しかし、一般的な使用例は以下の3通りなので、まずはこれらを知っておけば十分です。
- axes=0: テンソル積 a⊗b
- axes=1: テンソル内積 a・b
- axes=2: テンソルの二重縮約 a:b (※デフォルト)
axes に整数(integer_like)Nを渡した場合、式は a の axis=-N とb のaxis=0 で始まり、a のaxis=-1 とb のaxis=N で終わります。
複数の次元軸を設定する場合で、それらが aの最初の軸またはbの最後の軸でない場合、引数 axesは、同じ要素数の2つのシーケンスになっている必要があります。
出力結果のshapeは、(最初のテンソルの非縮約軸, 2つ目のテンソルの非縮約軸)という並びになります。
2. サンプルコード
それではサンプルコードを確認しましょう。
まずはテンソル(3次元配列)のa とb を作成します。
import numpy as np
a = np.arange(60).reshape(3,4,5)
b = np.arange(24).reshape(4,3,2)
最も一般的なテンソル積は次のものでしょう。
# テンソル積を取得
c = np.tensordot(a,b, axes=([1,0],[0,1]))
c
戻り値の配列のshapeは、それぞれのテンソルの非縮約軸を組み合わせたものになります。
# shapeはa とb の非縮約軸を組み合わせたもの
# この場合はa,bともに最後の軸が非縮約軸
c.shape
なお、これは次のように書くのと同じですが、numpy.tensordot()関数を使った方がコードも処理も軽いです。
# 以下のコードを計算しているのと同じ
d = np.zeros((5, 2))
for i in range(5):
for j in range(2):
for k in range(3):
for l in range(4):
d[i,j] += a[k,l,i] * b[l,k,j]
d
テンソルa, bのそれぞれの次元軸要素の計算関係は、次のようなコードで見てみると分かりやすいでしょう。
import numpy as np
a = np.arange(1, 9).reshape(2, 2, 2)
A = np.array([['a', 'b', 'c', 'd']], dtype=object).reshape(2, 2)
np.tensordot(a, A) # デフォルトはaxes=2
np.tensordot(a, A, 1) # axes=1
np.tensordot(a, A, 0) # axes=0
np.tensordot(a, A, (0, 1)) # axes=(0, 1)
np.tensordot(a, A, (2, 1)) # axes=(2, 1)
np.tensordot(a, A, ((0, 1), (0, 1))) # axes=((0, 1), (0, 1))
np.tensordot(a, A, ((2, 1), (1, 0)))
3. まとめ
以上がnumpy.tensordot()の使い方です。
コメント