정규분포끼리는 더하고 곱해도 평균과 분산 두 숫자만 고치면 되기 때문에, 계산을 쉽게 하려고 모든 불확실성을 정규분포 하나로 적는 프로그램이 많다. 그런 프로그램에 버스 대기 시간을 넣는다고 하자. 배차 간격이 10분이고 정류장에 아무 때나 도착한다면, 기다리는 시간은 0분에서 10분 사이 어디든 고르게 나온다. 이 분포를 정규분포 하나로 대신 적어야 한다면 어떤 정규분포를 골라야 할까? 정규분포는 종 모양이고 음수 쪽으로도 꼬리를 뻗으니, 어떻게 골라도 원래의 고른 모양은 되지 않는다.
실제 데이터의 분포는 이보다 훨씬 복잡하다. 이미지, 자연어의 토큰, 단백질 구조의 분포는 지수족의 깔끔한 꼴을 따르지 않는다. 지수족은 정규분포·베르누이처럼 log p = θ·t(x) − F(θ) 꼴로 쓰이는 분포의 모임이다. 그 안에서는 자연 파라미터 θ와 기댓값 파라미터 η = E[t(x)]가 좌표가 되고, e-측지선은 θ 좌표의 직선, m-측지선은 η 좌표의 직선이 된다. 디퓨전 모델이 만들어 내는 이미지 분포도, 파라미터가 수억 개인 신경망이 표현하는 분포도 이 꼴이 아니다. 그러면 지수족 위에 쌓아 올린 도구는 쓸모없는가?
아니다. 복잡한 분포를 직접 다루는 대신 다루기 쉬운 모델 안에서 「가장 가까운 점」을 찾도록 전략을 바꾸면 된다. 현실의 분포 p를 모델 위의 분포 q로 옮기는 것인데, 모델이라는 곡면 위에 가장 가까운 점을 찍는 이 일을 사영이라 부른다. 가까움은 KL 발산(Kullback–Leibler divergence, 한 분포를 다른 분포로 대신할 때 치르는 손해)으로 잰다.
KL은 두 인자의 순서를 바꾸면(KL(p‖q)와 KL(q‖p)) 값이 달라서, 「가장 가까운 점」도 어느 방향으로 재느냐에 따라 달라진다. 이 비대칭은 발산이라는 척도의 성질이고, 계량이 비대칭이라는 뜻은 없다. q가 p에 아주 가까워지면 두 방향의 KL이 모두 같은 피셔 이차식으로 줄어든다는 것이 그 근거다. 현실 p를 첫 인자로 둔 KL(p‖q)를 줄이면 q는 p가 있는 곳을 빠짐없이 덮으려 넓게 앉고(m-사영), 모델 q를 첫 인자로 둔 KL(q‖p)를 줄이면 q는 p가 거의 0인 곳을 피해 좁게 앉는다(e-사영). 이 절에서는 KL(p‖q)를 줄이는 m-사영만 쓴다.
왜 평균과 분산만 맞추면 될까? KL(p‖q) = −H(p) − Ep[log q]에서 앞의 엔트로피는 q와 상관이 없다. 정규분포 q에 대해 뒤의 항은 ½ log(2πσ²) + Ep[(x − μ)²]/(2σ²)이고, 뒤의 항은 μ가 p의 평균, σ²가 p의 분산일 때 가장 작다. 정규분포족에서 m-사영은 평균과 분산을 맞추는 일이다.
버스의 경우 평균은 5분, 분산은 10²/12 ≈ 8.33이므로 q* = N(5, 8.33)이다. 이 정규분포는 기다리는 시간이 음수일 확률에 4.2%를 건다.
0분에서 10분 사이에 고르게 퍼진 대기 시간 분포와, 평균·분산을 맞춘 정규분포 N(5, 8.33). 정규분포는 음수 대기 시간에 4.2%를 건다
파이썬
import numpy as np
from math import erf, sqrt, log, pi
# 현실 p: 0~10분 사이 고른 대기 시간. 모델: 정규분포 N(μ, σ²)
x = np.linspace(0, 10, 200001) # p 가 0 이 아닌 곳에서 고르게 뽑은 점들
def kl_p_q(mu, s): # KL(p‖q) = -H(p) - E_p[log q], H(p) = log 10
return -log(10) + np.mean(0.5 * np.log(2 * pi * s**2) + (x - mu)**2 / (2 * s**2))
grid = [(kl_p_q(m, s), m, s) for m in np.arange(4, 6.001, 0.05) for s in np.arange(2.5, 3.301, 0.01)]
kl, mu, s = min(grid)
print(f"격자에서 찾은 q*: 평균 {mu:.2f} 표준편차 {s:.2f} KL {kl:.4f}")
print(f"p 의 평균 {x.mean():.2f} 표준편차 {x.std():.2f}")
print(f"q* 가 음수 대기 시간에 거는 확률 {0.5 * (1 + erf(-mu / (s * sqrt(2)))):.3f}")
# 격자에서 찾은 q*: 평균 5.00 표준편차 2.89 KL 0.1765
# p 의 평균 5.00 표준편차 2.89
# q* 가 음수 대기 시간에 거는 확률 0.042
평균과 표준편차를 이리저리 바꿔 가며 KL을 직접 재어도, 가장 작은 곳은 p의 평균과 표준편차를 그대로 맞춘 자리다.
이 절의 결론
「현실이 모델 밖에 있으면 모델 안에서 KL로 가장 가까운 점을 찾고, 이 일을 사영이라 한다. KL(p‖q)로 재면(m-사영) 정규분포족에서는 평균과 분산을 맞추는 것이 답이다.」
문제 13. 평균 65점, 표준편차 25.5점
어느 반의 시험에서 절반은 40점 근처(표준편차 5점), 절반은 90점 근처(표준편차 5점)를 받았는데, 성적표에는 「평균 65점, 표준편차 25.5점」만 적혀 나왔다. (가) 평균과 표준편차가 정말 이 값인지 확인하라. (나) 성적표만 본 학부모가 점수 분포를 정규분포 N(65, 25.5²)으로 그렸다면, 55점에서 75점 사이 학생이 몇 %라고 여기겠는가? 실제로는 몇 %인가?
40점 근처와 90점 근처로 나뉜 점수 분포, 성적표의 두 숫자, 물음의 구간 55~75점
함께 풀기
김민준
평균은 (40 + 90)/2 = 65. 표준편차는 40점 근처 학생들도 90점 근처 학생들도 5점이니까 5점이요. 성적표가 틀렸네요.
선생님
40점 받은 학생과 90점 받은 학생은 평균에서 얼마나 떨어져 있어요?
김민준
25점씩이요. 아, 점수대 안의 표준편차만 셌네요. 분산은 점수대 안의 분산 5² = 25에 두 점수대 사이의 분산 25² = 625를 더해서 650, 표준편차 25.5예요. 성적표가 맞아요.
이서연
(나)는 N(65, 25.5²)에서 65 ± 10 안이니까 30.5%. 실제로는 55점에서 75점 사이에 거의 아무도 없어. 계산하면 0.1%쯤이야.
선생님
성적표의 두 숫자는 틀린 게 없어요. 그럼 학부모는 어디서 틀렸어요?
이서연
숫자가 아니라 모양이요. 평균과 표준편차를 맞춘 정규분포를 원래 분포로 믿은 거예요. 버스 대기 시간처럼, 평균과 분산이 같아도 모양은 전혀 다를 수 있어요.
김민준
조별 과제 평균 점수가 같은 두 조라도, 한 조는 넷이 고르게 하고 다른 조는 둘이 다 하고 둘은 안 했을 수 있는 거랑 같네요.
문제 14. 두 정규분포를 섞으면 정규분포인가 (킬러)
평균이 −2와 2이고 분산이 1인 두 정규분포 p0 = N(−2, 1), p1 = N(2, 1)이 있다. (가) 반반 혼합 ½p0 + ½p1의 평균과 분산을 구하라. (나) 정규분포족의 기댓값 파라미터 η = (E[x], E[x²]) 좌표에서 두 점의 중간점을 구하라. 어떤 정규분포인가? (다) (가)의 혼합과 (나)의 정규분포는 같은 분포인가? x = 0과 x = 2에서 밀도를 비교하고, KL(혼합‖(나)의 정규분포)를 구하라. (라) 자연 파라미터 θ 좌표의 중간점(e-측지선의 중간점)은 무엇인가?
두 정규분포 N(−2, 1), N(2, 1)과 밀도를 비교할 두 자리 x = 0, x = 2
함께 풀기
김민준
(가)는 평균 0, 분산은 1 + 4 = 5요. 확인하려고 N(−2, 1)에서 5만 개, N(2, 1)에서 5만 개 뽑아서 합치고 정규분포를 적합(fit)했어요. 평균 −0.001, 표준편차 2.235. √5가 2.236이니까 딱 맞아요. 그러니까 혼합은 N(0, 5)예요.
e-측지선의 중간점은 분산 1, 혼합을 m-사영한 점은 분산 5. 같은 두 끝점인데 중간의 분산이 다섯 배 차이네요.
선생님
오늘 두 사람 다 한 번씩, 정규분포족 위로 사영한 점을 원래 혼합분포로 착각했어요. 민준 학생은 적합한 결과를 원래 분포로 봤고, 서연 학생은 큰 공간의 정리를 작은 족 안으로 그대로 가져왔어요. 가져갈 것은 하나예요. e-측지선(확률을 곱해 잇는 길)은 지수족 안에 머물지만, m-측지선(확률을 섞어 잇는 길)은 지수족 밖으로 나간다. 그래서 지수족 안에서 혼합의 결과를 보려면 사영이 필요하다.
이서연
선형대수에서 부분공간 밖의 벡터와 그 정사영을 구분하라고 배웠는데, 여기서는 그 부분공간이 「정규분포족」이었네요.
문제 15. 갈림길에서 평균을 내는 운전 모델
사람이 운전한 기록을 흉내 내도록 학습하는 모델을 두고, 계산을 위해 지어낸 장면 하나를 보자. 도로 한가운데에 장애물이 있는 갈림길에서, 운전자의 절반은 핸들을 왼쪽으로 30°, 절반은 오른쪽으로 30° 꺾었다(각각 표준편차 5°). (가) 모델이 핸들 각도 하나를 내놓고 평균제곱오차(MSE)로 학습한다면, MSE를 가장 작게 하는 출력은 몇 도인가? (나) 각도 하나 대신 정규분포 N(μ, σ²)을 내놓고 로그우도를 키우도록 학습하면 μ와 σ는 얼마가 되는가? 이 정규분포가 ±10° 안에 거는 확률과, 실제 운전자 가운데 ±10° 안으로 꺾은 비율을 비교하라. (다) 무엇을 바꿔야 하는가?
장애물 앞에서 운전자 절반은 왼쪽으로, 절반은 오른쪽으로 30° 꺾은 갈림길과, 꺾은 각도의 분포
함께 풀기
김민준
모델이 똑똑하면 왼쪽이든 오른쪽이든 하나를 고르겠죠. −30°나 +30°요.
선생님
−30°로 냈을 때 MSE를 계산해 볼래요?
김민준
왼쪽 운전자와는 오차가 거의 없는데 오른쪽 운전자와는 60°씩 틀려요. 0°로 내면 모두와 30°씩 틀리니까 0°의 MSE가 더 작아요. MSE를 줄이면 평균인 0°가 나와요. 장애물로 곧장 가는 각도인데요.
이서연
(나)는 버스 대기 시간 예와 같아. 로그우도를 키우는 건 KL(p‖q)를 줄이는 거고.
선생님
정규분포족 안에서 그 KL을 줄이면 무엇이 맞춰지죠?
이서연
평균과 분산이요. 그러니까 μ = 0, σ² = 30² + 5², σ ≈ 30.4. 문제 13(성적표)과 같은 구조예요.
이서연
이 정규분포는 ±10° 안에 25.8%를 걸어. 실제 운전자는 0.003%밖에 ±10° 안으로 꺾지 않았고.
선생님
그럼 모델이 학습을 잘못한 거예요?
이서연
아니요. 모델은 자기 족 안에서 가장 가까운 점을 제대로 찾았어요. 정규분포 하나라는 족에 봉우리 둘이 없을 뿐이에요. 고치려면 족을 넓혀야 해요. 정규분포 둘을 섞은 꼴을 내놓게 하면 왼쪽과 오른쪽 두 봉우리를 다 담을 수 있어요.
선생님
그래요. MSE로 학습한다는 건 분산을 고정한 정규분포족으로 사영한다는 뜻이에요. 그 족에 무엇이 들어 있느냐가 답을 정해요.
김민준
조별 과제에서 의견이 둘로 갈렸을 때 둘을 반씩 섞어 낸 보고서가 어느 쪽도 설득하지 못했던 게 생각나네요.