programing

numpy dot()와 Python 3.5+ 행렬 곱셈의 차이 @

skycolor 2023. 6. 6. 08:08
반응형

numpy dot()와 Python 3.5+ 행렬 곱셈의 차이 @

저는 최근에 Python 3.5로 이동했고 새로운 행렬 곱셈 연산자(@)때때로 numpy dot 연산자와 다르게 동작한다는 것을 알게 되었습니다.예: 3D 어레이의 경우:

import numpy as np

a = np.random.rand(8,13,13)
b = np.random.rand(8,13,13)
c = a @ b  # Python 3.5+
d = np.dot(a, b)

@연산자가 도형 배열을 반환합니다.

c.shape
(8, 13, 13)

天皇가 동안에이사.np.dot()함수 반환:

d.shape
(8, 13, 8, 13)

어떻게 하면 움피 도트로 동일한 결과를 재현할 수 있습니까?다른 중요한 차이점이 있습니까?

@연자가배호출다니합열을 합니다.__matmul__ 메소드가 , 메소드dot이 방법은 API에도 함수로 존재합니다.

>>> a = np.random.rand(8,13,13)
>>> b = np.random.rand(8,13,13)
>>> np.matmul(a, b).shape
(8, 13, 13)

설명서에서 다음을 참조하십시오.

matmul와 .dot두 가지 중요한 방법으로

  • 스칼라에 의한 곱셈은 허용되지 않습니다.
  • 행렬 스택은 행렬이 요소인 것처럼 함께 브로드캐스트됩니다.

마지막 요점은 다음과 같은 것을 분명히 합니다.dot그리고.matmul메서드는 3D(또는 고차원) 배열을 통과할 때 다르게 동작합니다.설명서에서 추가로 인용한 내용:

위해서matmul:

두 인수 중 하나가 N-D, N > 2이면 마지막 두 인덱스에 있는 행렬의 스택으로 처리되고 그에 따라 브로드캐스트됩니다.

대상:

2-D 배열의 경우 행렬 곱셈과 같으며, 1-D 배열의 경우 벡터의 내부 곱(복잡한 활용 없이)과 같습니다.N차원의 경우 a의 마지막 축과 b의 두 번째에서 마지막 축에 걸친 합 곱입니다.

참고로, 참로고.@ 그것의 등가물인 고그의바그보같등가물은리것▁and.dot그리고.matmul모두 동일한 속도입니다. ( 프로젝트인 성능 그림으로 만든 그림)

여기에 이미지 설명 입력

그림을 재현하는 코드:

import perfplot
import numpy


def setup(n):
    A = numpy.random.rand(n, n)
    x = numpy.random.rand(n)
    return A, x


def at(A, x):
    return A @ x


def numpy_dot(A, x):
    return numpy.dot(A, x)


def numpy_matmul(A, x):
    return numpy.matmul(A, x)


perfplot.show(
    setup=setup,
    kernels=[at, numpy_dot, numpy_matmul],
    n_range=[2 ** k for k in range(15)],
)

@ajcr의 대답은 어떻게 설명합니다.dot그리고.matmul((으)로 @기호)가 다릅니다.간단한 예를 보면, '매트리스 스택' 또는 텐서에서 작동할 때 두 가지가 어떻게 다르게 작동하는지 명확하게 알 수 있습니다.

하기 하고 4x4 배열을 합니다.dot 및 제품및matmul3x4x2의 '매트릭스 스택' 또는 텐서를 사용하는 제품.

import numpy as np
fourbyfour = np.array([
                       [1,2,3,4],
                       [3,2,1,4],
                       [5,4,6,7],
                       [11,12,13,14]
                      ])


threebyfourbytwo = np.array([
                             [[2,3],[11,9],[32,21],[28,17]],
                             [[2,3],[1,9],[3,21],[28,7]],
                             [[2,3],[1,9],[3,21],[28,7]],
                            ])

print('4x4*3x4x2 dot:\n {}\n'.format(np.dot(fourbyfour,threebyfourbytwo)))
print('4x4*3x4x2 matmul:\n {}\n'.format(np.matmul(fourbyfour,threebyfourbytwo)))

각 작업의 제품은 아래와 같습니다.도트 제품이 어떤지 주목해 보세요.

...a의 마지막 축과 b의 두 번째에서 마지막 축에 걸친 곱의 합

그리고 매트릭스를 함께 방송함으로써 매트릭스 생성물이 어떻게 형성되는지.

4x4*3x4x2 dot:
 [[[232 152]
  [125 112]
  [125 112]]

 [[172 116]
  [123  76]
  [123  76]]

 [[442 296]
  [228 226]
  [228 226]]

 [[962 652]
  [465 512]
  [465 512]]]

4x4*3x4x2 matmul:
 [[[232 152]
  [172 116]
  [442 296]
  [962 652]]

 [[125 112]
  [123  76]
  [228 226]
  [465 512]]

 [[125 112]
  [123  76]
  [228 226]
  [465 512]]]

수학에서, 나는 numpy의 이 더 말이 된다고 생각합니다.

도트(a,b)_{i,j,k,a,b,c} =공식

a와 b가 벡터일 때 점 곱을 주고, a와 b가 행렬일 때 행렬 곱을 주기 때문입니다.


Numpy의 공식 연산은 점 결과의 일부로 구성되며, 다음과 같이 정의할 수 있습니다.

matul(a,b)_{i,j,k,c} =공식


따라서 matul(a,b)가 작은 모양의 배열을 반환하는 것을 볼 수 있습니다. 이 배열은 메모리 소비가 적고 응용 프로그램에서 더 의미가 있습니다.특히, 방송과 결합하면, 당신은 얻을 수 있습니다.

matul(a,b)_{i,j,k,l} =공식

예를들면.


위의 두 가지 정의에서 이러한 두 가지 작업을 사용하기 위한 요구 사항을 확인할 수 있습니다.a.shape=(s1,s2,s3,s4) 및 b.shape=(t1,t2,t3,t4)가정합니다.

  • 필요한 (a,b) 사용하려면
  1. t3=s4;
  • 함수(a,b)를 사용하려면 필요합니다.
  1. t3=s4
  2. t2=s2 또는 t2와 s2 중 하나는 1
  3. t1=s1 또는 t1 및 s1 중 하나는 1입니다.

다음 코드를 사용하여 자신을 설득합니다.

import numpy as np
for it in range(10000):
    a = np.random.rand(5,6,2,4)
    b = np.random.rand(6,4,3)
    c = np.matmul(a,b)
    d = np.dot(a,b)
    #print ('c shape: ', c.shape,'d shape:', d.shape)
    
    for i in range(5):
        for j in range(6):
            for k in range(2):
                for l in range(3):
                    if c[i,j,k,l] != d[i,j,k,j,l]:
                        print (it,i,j,k,l,c[i,j,k,l]==d[i,j,k,j,l])  # you will not see them              

다음은 인덱스가 어떻게 투영되는지 보여주는 비교입니다.

np.allclose(np.einsum('ijk,ijk->ijk', a,b), a*b)        # True 
np.allclose(np.einsum('ijk,ikl->ijl', a,b), a@b)        # True
np.allclose(np.einsum('ijk,lkm->ijlm',a,b), a.dot(b))   # True

MATMUL과 DOT에 대한 나의 경험

"ValueError:전달된 값의 모양은 (200, 1)이고, 인덱스는 MATMUL을 사용하려고 할 때 (200, 3)"을 의미합니다.빠른 해결 방법을 원했고 동일한 기능을 제공할 수 있는 DOT를 찾았습니다.저는 DOT를 사용하면 어떠한 오류도 발생하지 않습니다.나는 정답을 얻습니다.

MATMUL 포함

X.shape
>>>(200, 3)

type(X)

>>>pandas.core.frame.DataFrame

w

>>>array([0.37454012, 0.95071431, 0.73199394])

YY = np.matmul(X,w)

>>>  ValueError: Shape of passed values is (200, 1), indices imply (200, 3)"

DOT 포함

YY = np.dot(X,w)
# no error message
YY
>>>array([ 2.59206877,  1.06842193,  2.18533396,  2.11366346,  0.28505879, …

YY.shape

>>> (200, )

언급URL : https://stackoverflow.com/questions/34142485/difference-between-numpy-dot-and-python-3-5-matrix-multiplication

반응형