고급 Einsum 연산
이제 기본적인 einsum 연산에 익숙해졌으므로 몇 가지 더 고급 응용 프로그램을 살펴보겠습니다. 이러한 연산은 einsum 함수의 진정한 힘과 유연성을 보여줍니다.
대각선 추출
행렬의 대각선 요소를 추출하는 것은 선형 대수에서 일반적인 연산입니다. 행렬 A 의 경우 대각선 요소는 다음과 같은 벡터 d 를 형성합니다.
d_i = A_{ii}
einsum을 사용하여 대각선을 추출하는 방법은 다음과 같습니다.
## Create a random square matrix
A = np.random.rand(4, 4)
print("Matrix A:")
print(A)
## Extract diagonal using einsum
diagonal = np.einsum('ii->i', A)
print("\nDiagonal elements using einsum:")
print(diagonal)
## Verify with NumPy's diagonal function
numpy_diagonal = np.diagonal(A)
print("\nDiagonal elements using np.diagonal():")
print(numpy_diagonal)
표기법 'ii->i'는 다음을 의미합니다.
ii는 A 의 대각선 요소에 대한 반복 인덱스를 나타냅니다.
i는 이러한 요소를 1D 배열로 추출한다는 의미입니다.
행렬 트레이스 (Trace)
행렬의 트레이스는 대각선 요소의 합입니다. 행렬 A 의 경우 트레이스는 다음과 같습니다.
\text{trace}(A) = \sum_i A_{ii}
einsum을 사용하여 트레이스를 계산하는 방법은 다음과 같습니다.
## Using the same matrix A from above
trace = np.einsum('ii->', A)
print("Trace of matrix A using einsum:", trace)
## Verify with NumPy's trace function
numpy_trace = np.trace(A)
print("Trace of matrix A using np.trace():", numpy_trace)
표기법 'ii->'는 다음을 의미합니다.
ii는 대각선 요소에 대한 반복 인덱스를 나타냅니다.
- 빈 출력 인덱스는 모든 대각선 요소를 합산하여 스칼라를 얻는다는 의미입니다.
배치 행렬 곱셈
einsum은 고차원 배열에서 연산을 수행할 때 진가를 발휘합니다. 예를 들어, 배치 행렬 곱셈은 두 배치에서 행렬 쌍을 곱하는 것을 포함합니다.
모양이 (n, m, p) 인 행렬 배치 A 와 모양이 (n, p, q) 인 행렬 배치 B 가 있는 경우 배치 행렬 곱셈은 모양이 (n, m, q) 인 결과 C 를 제공합니다.
C_{ijk} = \sum_l A_{ijl} \times B_{ilk}
einsum을 사용하여 배치 행렬 곱셈을 수행하는 방법은 다음과 같습니다.
## Create batches of matrices
n, m, p, q = 5, 3, 4, 2 ## Batch size and matrix dimensions
A = np.random.rand(n, m, p) ## Batch of 5 matrices, each 3x4
B = np.random.rand(n, p, q) ## Batch of 5 matrices, each 4x2
print("Shape of batch A:", A.shape)
print("Shape of batch B:", B.shape)
## Batch matrix multiplication using einsum
C = np.einsum('nmp,npq->nmq', A, B)
print("\nShape of result batch C:", C.shape) ## Should be (5, 3, 2)
## Let's check the first matrix multiplication in the batch
print("\nFirst result matrix from batch using einsum:")
print(C[0])
## Verify with NumPy's matmul function
numpy_batch_matmul = np.matmul(A, B)
print("\nFirst result matrix from batch using np.matmul:")
print(numpy_batch_matmul[0])
표기법 'nmp,npq->nmq'는 다음을 의미합니다.
nmp는 배치 A 의 인덱스를 나타냅니다 (n 은 배치, m 은 행, p 는 열).
npq는 배치 B 의 인덱스를 나타냅니다 (n 은 배치, p 는 행, q 는 열).
nmq는 출력 배치 C 의 인덱스를 나타냅니다 (n 은 배치, m 은 행, q 는 열).
- 반복되는 인덱스
p는 합산됩니다 (행렬 곱셈).
왜 Einsum 을 사용하는가?
NumPy 가 이미 이러한 연산을 위한 특수 함수를 제공하는데 왜 einsum을 사용해야 하는지 궁금할 수 있습니다. 다음과 같은 몇 가지 장점이 있습니다.
- 통합 인터페이스 (Unified Interface):
einsum은 많은 배열 연산을 위한 단일 함수를 제공합니다.
- 유연성 (Flexibility): 여러 단계가 필요한 연산을 표현할 수 있습니다.
- 가독성 (Readability): 표기법을 이해하면 코드가 더 간결해집니다.
- 성능 (Performance): 많은 경우
einsum 연산은 최적화되고 효율적입니다.
복잡한 텐서 연산의 경우 einsum은 종종 가장 명확하고 직접적인 구현을 제공합니다.