모든 데서 만날 그 연산
같은 길이 벡터 둘 골라. 내적 = element-wise 곱 후 합. . 스칼라 하나 출력. 끝. 공식 전체. 근데 모든 현대 신경망은 대충 "이거 수십억 번 하고 추론이라 부른다."
왜 이렇게 중심? 내적이 비밀스럽게 유사성 을 측정하기 때문. 구체적: , = 둘 사이 각도. 같은 방향 → 큰 양수. 반대 방향 → 큰 음수. 수직 (공유 방향 X) → 0. "이 둘이 얼마나 정렬돼있는가" 의 수치 답.
같은 연산의 세 렌즈
| 렌즈 | 의 의미 |
|---|---|
| 기하적 | 한 벡터의 다른 벡터 위로의 투영 길이, 길이 가중 |
| 통계적 | 두 feature 리스트의 비정규화 상관관계 |
| AI / ML | 한 임베딩이 다른 임베딩과 얼마나 "동의" 하는지 — attention, retrieval, classification 에서 사용 |
어디서 만날까
- Attention 점수: query 벡터를 각 key 벡터와 내적 → 어느 토큰에 집중할지.
- 코사인 유사도: 내적 / norm 곱 → "이 두 임베딩 얼마나 비슷?" Semantic search, 추천 시스템, 클러스터링에서 사용.
- Logits → softmax: 신경망 마지막 레이어 = 마지막 hidden state 와 클래스 임베딩 행렬의 내적 stack.
- Backprop chain: 모든 weight 갱신이 gradient 와 내적 포함.
import numpy as np
np.random.seed(42)
128차원 임의 벡터 두 개
a = np.random.randn(128) b = np.random.randn(128)
코사인 유사도 함수
def cosine_similarity(v1, v2): return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
첫 번째 비교
sim_ab = cosine_similarity(a, b) print(f"a와 b의 코사인 유사도: {sim_ab:.6f}")
a를 100배한 세 번째 벡터
c = a * 100
c와 b의 유사도
sim_cb = cosine_similarity(c, b) print(f"c와 b의 코사인 유사도: {sim_cb:.6f}")
두 결과 비교
print(f"두 유사도가 같은가? {np.isclose(sim_ab, sim_cb)}")
크기는 어떻게 변했나
print(f"\n||a|| = {np.linalg.norm(a):.4f}") print(f"||c|| = {np.linalg.norm(c):.4f}") print(f"c의 크기는 a의 {np.linalg.norm(c) / np.linalg.norm(a):.0f}배")
a와 b의 코사인 유사도: 0.029607 c와 b의 코사인 유사도: 0.029607 두 유사도가 같은가? True
크기만 변했지(스칼라) 방향(벡터)는 변하지 않았기 때문에 코사인 유사도는 같음, 두 백터에 어떤 값을 곱해도 동일하다