web-dev-qa-db-ja.com

numpy dot()とinner()の違い

違いは何ですか

_import numpy as np
np.dot(a,b)
_

そして

_import numpy as np
np.inner(a,b)
_

私が試みたすべての例は同じ結果を返しました。 Wikipedia 両方に同じ記事がありますか?! 説明 of inner()では、その動作は高次元で異なると言いますが、異なる出力を生成することはできませんでした。どちらを使用すればよいですか?

53
Milla Well

numpy.dot

2次元配列の場合、これは行列の乗算に相当し、1次元配列の場合、ベクトルの内積(複素共役なし)に相当します。 N次元の場合、aのlast axissecond-to-lastのb:

numpy.inner

1次元配列のベクトルの通常の内積(複素共役なし)。高次元では、最後の軸の合計積。

(エンファシス鉱山。)

例として、2D配列を使用したこの例を考えてみましょう。

>>> a=np.array([[1,2],[3,4]])
>>> b=np.array([[11,12],[13,14]])
>>> np.dot(a,b)
array([[37, 40],
       [85, 92]])
>>> np.inner(a,b)
array([[35, 41],
       [81, 95]])

したがって、使用する必要があるのは、アプリケーションに正しい動作を提供するものです。


性能テスト

(1Dケースのみをテストしていることに注意してください。これは.dotおよび.inner同じ結果が得られます。)

>>> import timeit
>>> setup = 'import numpy as np; a=np.random.random(1000); b = np.random.random(1000)'

>>> [timeit.timeit('np.dot(a,b)',setup,number=1000000) for _ in range(3)]
[2.6920320987701416, 2.676928997039795, 2.633111000061035]

>>> [timeit.timeit('np.inner(a,b)',setup,number=1000000) for _ in range(3)]
[2.588860034942627, 2.5845699310302734, 2.6556360721588135]

かもね .innerは高速ですが、マシンは現時点ではかなりロードされているため、タイミングは一貫性がなく、必ずしも非常に正確ではありません。

55
huon

np.dotおよびnp.innerは1次元配列で同一であるため、おそらく違いに気付かないのはこのためです。 N次元配列の場合、それらは一般的なテンソル操作に対応します。

np.innerは、高次と低次のテンソル、特にテンソルとベクトルの「ベクトル積」と呼ばれることもあり、しばしば「テンソル収縮」につながります。行列とベクトルの乗算が含まれます。

np.dotは「テンソル製品」に対応し、Wikipediaページの下部に記載されているケースを含みます。通常、2つの同様のテンソルを乗算して新しいテンソルを生成するために使用されます。マトリックスとマトリックスの乗算が含まれます。

テンソルを使用していない場合は、これらのケースを心配する必要はなく、同じように動作します。

18
marshall.ward

1次元配列と2次元配列の場合、numpy.innerは2番目の行列を転置してから乗算します。だから:

_A = [[a1,b1],[c1,d1]]
B = [[a2,b2],[c2,d2]]
numpy.inner(A,B)
array([[a1*a2 + b1*b2, a1*c2 + b1*d2],
       [c1*a2 + d1*b2, c1*c2 + d1*d2])
_

私は次のような例を使用してこれを解決しました:

_A=[[1  ,10], [100,1000]]
B=[[1,2], [3,4]]
numpy.inner(A,B)
array([[  21,   43],
       [2100, 4300]])
_

これは、1つのディメンションnumpy.inner([a,b],[c,b]) = ac+bdおよびnumpy.inner([[a],[b]], [[c],[d]]) = [[ac,ad],[bc,bd]]の動作も説明しています。これは私の知識の範囲であり、より高い次元でそれが何をするのか分かりません。

8
Rob McKemey

innerは複雑な2D配列で適切に動作していません。乗算してみてください

およびその転置

array([[ 1.+1.j,  4.+4.j,  7.+7.j],
       [ 2.+2.j,  5.+5.j,  8.+8.j],
       [ 3.+3.j,  6.+6.j,  9.+9.j]])

あなたは得るでしょう

array([[ 0. +60.j,  0. +72.j,  0. +84.j],
       [ 0.+132.j,  0.+162.j,  0.+192.j],
       [ 0.+204.j,  0.+252.j,  0.+300.j]])

行から列へではなく、行から行への効果的な乗算

1
Himanshu

高次元の空間では、内積と内積の間に大きな違いがあります。以下は、2x2行列と3x2行列の例です。x = [[a1、b1]、[c1、d1]] y = [[a2、b2]。[c2、d2]、[e2、f2]

np.inner(x、y)

output = [[a1xa2 + b1xb2、a1xc2 + b1xd2、a1xe2 + b1f2]、[c1xa2 + d1xb2、c1xc2 + d1xd2、c1xe2 + d1xf2]]

ただし、ドット積の場合、2x2行列に3x2を掛けることができないため、出力には次のエラーが表示されます。

ValueError:形状(2,2)および(3,2)が整列していません:2(dim 1)!= 3(dim 0)

0
pylearner