강의 / 우리는 모두 같은 AI를 쓰고 있다 / 4강
시작 …
같은 모델을 두 번 학습하면 좌표는 달라지지만 각도는 남습니다. 모든 점을 앵커와의 유사도로 바꾸면 서로 다른 모델의 부품을 학습 없이 이어 붙일 수 있습니다.
3강이 표현이 닮아 간다는 관찰이었다면, 이번 편은 그 닮음을 실제로 써먹는 방법입니다.
문제부터 보겠습니다. 같은 모델을 같은 데이터로 두 번 학습시키면 잠재 공간이 서로 다르게 나옵니다. 초기값과 데이터 순서가 다르기 때문입니다. 그래서 한쪽 인코더와 다른 쪽 디코더를 이어 붙이면 동작하지 않습니다.
학습의 무작위성은 공간을 회전시키고 늘리지만 점들 사이의 관계는 대체로 유지합니다.
고양이, 강아지, 자동차 세 점을 생각해 보겠습니다. 두 번 학습시키면 세 점의 좌표는 완전히 달라집니다. 그런데 고양이와 강아지 사이의 각도, 고양이와 자동차 사이의 각도는 양쪽에서 비슷합니다.
좌표를 버리고 각도만 쓰면 두 공간을 같은 언어로 말하게 만들 수 있습니다.
방법은 이렇습니다.
앵커를 300개 쓰면 모든 점이 300차원 벡터가 됩니다. 원래 공간이 768차원이든 1024차원이든 상관없습니다.
핵심은 이 변환이 회전에 영향을 받지 않는다는 점입니다. 공간을 통째로 돌려도 각도는 그대로이므로 상대 표현도 그대로입니다.
import numpy as np
def to_relative(x: np.ndarray, anchors: np.ndarray) -> np.ndarray:
"""모든 점을 앵커와의 코사인 유사도로 바꿉니다."""
xn = x / np.linalg.norm(x, axis=1, keepdims=True)
an = anchors / np.linalg.norm(anchors, axis=1, keepdims=True)
return xn @ an.T
# 앵커 3개로 직접 해 보기
anchors = np.array([[1.0, 0.0], [0.0, 1.0], [1.0, 1.0]])
point = np.array([[2.0, 1.0]])
print(to_relative(point, anchors))
# [[0.894 0.447 0.949]]
# 공간을 45도 돌려도 결과는 같습니다.
t = np.pi / 4
R = np.array([[np.cos(t), -np.sin(t)], [np.sin(t), np.cos(t)]])
print(to_relative(point @ R.T, anchors @ R.T))
# [[0.894 0.447 0.949]]바꿔 끼우기 실험의 결과입니다.
| 바꾼 것 | 전 | 후 |
|---|---|---|
| 언어 (스페인어) | 43.67 | 82.78 |
| 구조 (DBpedia) | 6.96 | 80.47 |
| 이미지 인코더 (CIFAR-100) | 6.21 | 81.42 |
| 이미지 인코더 (ImageNet) | 0.07 | 44.72 |
ImageNet에서 0.07이라는 값은 사실상 무작위 추측입니다. 그것이 44.72까지 올라갑니다. 추가 학습은 없습니다.
Cora 데이터셋에서 모델 2,000개를 놓고 봤을 때 성능과 잠재 유사도의 피어슨 상관은 0.955입니다.
다음 편에서는 같은 아이디어를 더 밀어붙입니다. 앵커도 없고 짝지어진 데이터도 없을 때 어떻게 하는지 봅니다.
로그인하시면 댓글을 쓰실 수 있습니다.
아직 댓글이 없습니다. 첫 댓글을 남겨 주시면 됩니다.