안녕하세요! 오늘은 딥러닝 구현의 가장 큰 걸림돌 중 하나인 '텐서 곱셈'을 정복해보겠습니다.
선형대수학을 깊게 몰라도 괜찮습니다. "모양(Shape) 맞추기 게임"이라고 생각하면 훨씬 쉬워집니다.
1. 1D 텐서(벡터) 끼리의 곱 (내적)
"환자 한 명의 종합 점수 계산하기"
두 벡터의 곱은 내적(Dot Product)이라고 하며, 결과는 숫자 하나(스칼라)가 나옵니다.
- 상황: 환자 A의 검사 수치 벡터와, 각 검사 항목의 중요도(가중치) 벡터를 곱해서 '위험도 점수' 하나를 뽑고 싶을 때.
- 공식: $(a_1 \times b_1) + (a_2 \times b_2) + \dots$
- 조건: 두 벡터의 길이가 같아야 합니다.
import torch
# 환자 A의 검사 수치 [혈압, 당뇨수치, 콜레스테롤]
features = torch.tensor([120.0, 95.0, 200.0])
# 각 항목의 가중치
weights = torch.tensor([0.5, 2.0, 1.0])
# 내적 계산 -> 결과는 스칼라(점수)
score = torch.matmul(features, weights)
print(score) # tensor(450.) -> 120*0.5 + 95*2 + 200*1
2. 2D 텐서(행렬) 끼리의 곱
"환자 그룹의 진단 결과 한 번에 계산하기"
가장 많이 쓰는 연산입니다. 앞 행렬의 열 개수와 뒤 행렬의 행 개수가 같아야 합니다.
- 공식: $(N \times M) \times (M \times P) = (N \times P)$
- 가운데 $M$이 사라지고 양 끝 $N, P$가 남습니다.
# 환자 3명의 데이터 (3명 x 2개 특징) -> (3, 2)
patients = torch.rand(3, 2)
# 진단 모델 가중치 (2개 특징 x 5개 질병 확률) -> (2, 5)
model_weights = torch.rand(2, 5)
# 행렬 곱 -> (3, 5)
# 결과: 환자 3명에 대한 5가지 질병 확률
diagnosis = torch.matmul(patients, model_weights)
print(diagnosis.shape) # torch.Size([3, 5])
3. 벡터와 행렬의 곱 (Broadcasting의 마법)
파이토치는 똑똑해서 차원이 안 맞아도 알아서 맞춰줍니다(Broadcasting). 하지만 헷갈리기 쉬우니 주의해야 합니다.
① 벡터(1D) $\times$ 행렬(2D)
- 벡터가 앞에 오면: 벡터를 행 벡터($1 \times N$)로 취급하여 계산 후 다시 벡터로 돌려줍니다.
- (N,) $\times$ (N, M) $\to$ (M,)
② 행렬(2D) $\times$ 벡터(1D)
- 벡터가 뒤에 오면: 벡터를 열 벡터($M \times 1$)로 취급합니다.
- (N, M) $\times$ (M,) $\to$ (N,)
팁: 헷갈리면 그냥 벡터를 unsqueeze로 2차원 행렬로 만들어서 계산하는 게 정신건강에 좋습니다.
4. 고차원 텐서 곱셈 (Batched Matmul)
"여러 장의 MRI 이미지를 한 번에 처리하기"
3차원 이상의 텐서는 '여러 개의 행렬 묶음(Batch)'으로 생각하면 됩니다.
앞부분 차원(Batch Size)은 그대로 두고, 마지막 두 차원(행렬 부분)끼리만 곱셈을 수행합니다.
- 규칙: (B, N, M) $\times$ (B, M, K) = (B, N, K)
- 여기서 B(배치 크기)는 같아야 합니다.
# 배치 크기(B)=10, 환자 수(N)=3, 특징(M)=4
batch_data = torch.rand(10, 3, 4)
# 배치 크기(B)=10, 특징(M)=4, 결과(K)=5
batch_weights = torch.rand(10, 4, 5)
# 마지막 두 차원끼리만 곱셈 수행
# (3, 4) x (4, 5) -> (3, 5)
# 앞의 10은 그대로 유지
result = torch.matmul(batch_data, batch_weights)
print(result.shape) # torch.Size([10, 3, 5])
5. mm, bmm, matmul 비교 정리
파이토치에는 곱셈 함수가 여러 개 있습니다. 상황에 맞게 골라 쓰세요.
| 메서드 | 설명 | 지원 차원 | Broadcasting | 비고 |
| torch.matmul | 만능형, 대부분 활용 | 모든 차원 | 지원 | 가장 유연하지만 실수 할 수 있음 |
| torch.mm | 행렬 전용 | 오직 2D | 지원 안함 | 확실한 행렬 곱셈을 원할때 사용 |
| torch.bmm | 배치 행렬 전용 | 오직 3D | 지원 안함 | (B, N, M) 형태 텐서 곱셈에 엄격하게 사용 |
요약: 이것만 기억하세요!
- 차원 확인: 곱셈 전 .shape 확인은 필수!
- 안쪽 차원 일치: $(A, \mathbf{B}) \times (\mathbf{B}, C) \to (A, C)$ 공식 암기.
- 고차원 처리: 앞부분(배치)은 무시하고, 맨 뒤 2개 차원만 보고 계산하면 됩니다.
이제 복잡한 텐서 연산도 두렵지 않으시죠? 이 기초가 탄탄해야 나중에 Transformer 같은 복잡한 모델도 쉽게 이해할 수 있습니다. 화이팅!
'Study Note > Deep Learning' 카테고리의 다른 글
| 비선형 문제를 푸는 열쇠(Activation Function)와 학습의 핵심(Back Propagation) (0) | 2026.01.06 |
|---|---|
| [딥러닝 이론 1] 뇌를 흉내 낸 기계, 퍼셉트론에서 DNN까지 (0) | 2026.01.06 |
| 딥러닝을 위한 '텐서'와 '행렬'의 정체 (1) | 2026.01.02 |
| 딥러닝을 위한 필수 라이브러리, 의료 데이터로 정복하기 (0) | 2026.01.02 |
| [PyTorch] 의료 데이터를 위한 텐서(Tensor) 완전 정복 (1) | 2025.12.31 |