15장 — 비평형 통계역학과 야르진스키 등식

경로 공간의 ELBO: ln Z는 아래로 치우친다

이 장 첫머리의 물음 가운데 하나가 아직 남아 있다. 가중치의 평균에 로그를 씌운 값은 왜 한쪽으로 치우쳐 나올까? ML에서는 모델을 견줄 때마다 ln Z나 로그우도를 어림하므로, 이 치우침이 어느 쪽인지 알아야 견줌이 공정해진다. 가장 단순한 경우부터 보자. 덫을 κ = 1에서 4로 한순간에 조이면 일의 평균은 1.5이고 ΔF는 ln 2 = 0.693이어서 소산된 일은 0.807이다. 사슬 하나의 로그 가중치 ln e^(−𝒲) = −𝒲를 평균하면 −1.5로, 참값 ln(Z₁/Z₀) = −0.693보다 0.807만큼 아래에 있다. 이 0.807은 무엇을 잰 값일까?

덫을 κ = 1에서 4로 한순간에 조일 때 사슬 하나의 로그 가중치 −𝒲의 분포(40만 번). 로그 가중치의 평균 −1.5는 참값 ln(Z₁/Z₀) = −0.693보다 0.807만큼 아래에 있다. 이 틈이 소산된 일이다.
덫을 κ = 1에서 4로 한순간에 조일 때 사슬 하나의 로그 가중치 −𝒲의 분포(40만 번). 로그 가중치의 평균 −1.5는 참값 ln(Z₁/Z₀) = −0.693보다 0.807만큼 아래에 있다. 이 틈이 소산된 일이다.

소산된 일은 KL 발산이다

크룩스 정리의 오른쪽 식은 경로 하나마다 앞으로 간 확률과 거꾸로 밟는 확률의 비를 준다. 이 비의 로그를 앞으로 간 경로들로 평균하면 다음 두 식을 얻는다.

β (⟨W⟩−ΔF)=DKL(PF ∥ PR)≥0,⟨ln⁡e−βW⟩=ln⁡Z1Z0−DKL(PF ∥ PR)\textcolor{#8c564b}{\beta}\,\big(\langle \textcolor{#ff7f0e}{\mathcal{W}} \rangle - \Delta \textcolor{#a000c8}{F}\big) = \textcolor{#9467bd}{D_{\mathrm{KL}}}(\textcolor{#e377c2}{\mathcal{P}_F} \,\|\, \textcolor{#e377c2}{\mathcal{P}_R}) \ge 0, \qquad \big\langle \ln e^{-\textcolor{#8c564b}{\beta}\textcolor{#ff7f0e}{\mathcal{W}}} \big\rangle = \ln \frac{\textcolor{#667733}{Z_1}}{\textcolor{#667733}{Z_0}} - \textcolor{#9467bd}{D_{\mathrm{KL}}}(\textcolor{#e377c2}{\mathcal{P}_F} \,\|\, \textcolor{#e377c2}{\mathcal{P}_R})
DKL(PF ∥ PR)앞으로 간 경로 분포와 거꾸로 밟는 경로 분포 사이의 KL 발산⟨ln⁡e−βW⟩로그 가중치의 평균 (가중치 평균의 로그가 아니다)\begin{array}{ll} \textcolor{#9467bd}{D_{\mathrm{KL}}}(\textcolor{#e377c2}{\mathcal{P}_F} \,\|\, \textcolor{#e377c2}{\mathcal{P}_R}) & \text{앞으로 간 경로 분포와 거꾸로 밟는 경로 분포 사이의 KL 발산} \\ \langle \ln e^{-\textcolor{#8c564b}{\beta}\textcolor{#ff7f0e}{\mathcal{W}}} \rangle & \text{로그 가중치의 평균 (가중치 평균의 로그가 아니다)} \end{array}

소산된 일의 평균은 앞으로 간 경로들이 거꾸로 틀어 본 경로들과 얼마나 다른지를 KL 발산(두 분포가 얼마나 다른지 0 이상의 수 하나로 재는 양. 두 분포의 밀도 비에 로그를 씌워 앞쪽 분포로 평균한 값으로, 두 분포가 같을 때만 0이다)으로 잰 것이다. 한없이 천천히 바꾸면 경로를 거꾸로 틀어도 구별할 수 없어 KL이 0이 되고, 서두를수록 거꾸로 튼 영상이 어색해진다. 덫을 한순간에 조일 때는 경로가 처음 위치 하나뿐이어서 이 KL은 두 정규분포 사이의 KL(N(0, 1)‖N(0, 1/4)) = ½(4 − 1 − ln 4) = 0.807이고, 실제로 1.5 − 0.693 = 0.807이다.

ELBO의 틈

두 번째 식은 ELBO(evidence lower bound, 곧 증거의 하한. 여기서는 ln Z보다 클 수 없는 값)의 모양 그대로다. ELBO는 근사 분포 q에 대해 ⟨ln(p̃/q)⟩_q = ln Z − D_KL(q‖p)이고, 여기서는 앞으로 간 경로 분포가 q 자리에, 거꾸로 밟는 경로 분포가 p 자리에 선다. 로그 가중치의 평균은 경로 공간의 ELBO이고, ELBO의 틈이 곧 소산된 일이다. 한 걸음도 움직이지 않는 AIS에서는 경로가 출발 위치 하나이므로, 이것은 q = p₀로 둔 보통의 ELBO와 같다. 그래서 사슬마다 ln e^(−β𝒲)를 평균하면 ln(Z₁/Z₀)의 하한을 얻고, 가중치를 평균한 뒤 로그를 씌운 ln⟨e^(−β𝒲)⟩도 기댓값으로는 ln(Z₁/Z₀)보다 작다. 로그가 위로 볼록하기 때문이다. AIS의 ln Z 추정값이 사슬이 적을 때 아래로 치우치는 까닭이 이것이고, 목표 분포에서 정확한 샘플을 얻을 수 있으면 거꾸로 가는 AIS로 위쪽에서도 끼울 수 있다.

코드로 확인하기

모든 쌍이 J/N으로 묶인 스핀 100개는 에너지가 위를 향한 스핀의 수 하나로 정해져서 ln Z를 정확히 셀 수 있다. βJ = 1.5에서는 메트로폴리스 사슬이 자화의 부호를 바꾸지 못하고 한쪽 봉우리에 갇힌다. 온도 사다리 βJ = 0 → 1.5를 따라 AIS를 돌려 ln Z(1.5) − ln Z(0)을 어림하고 정확한 값과 비교한다.

import numpy as np
from scipy.special import gammaln, logsumexp
rng = np.random.default_rng(0)

# 모든 쌍이 J/N으로 묶인 스핀 N개: 에너지는 스핀의 합 M = 2n − N 하나로 정해진다 (n = 위를 향한 수)
N, J = 100, 1.0
E = lambda M: -(J / (2 * N)) * (M**2 - N)
n_all = np.arange(N + 1)
log_count = gammaln(N + 1) - gammaln(n_all + 1) - gammaln(N - n_all + 1)
lnZ = lambda beta: logsumexp(log_count - beta * E(2 * n_all - N))   # n으로 묶어 정확히 센 ln Z

def ais(K, chains=1000, beta_max=1.5):
    betas = np.linspace(0, beta_max, K + 1)              # 온도 사다리: βJ = 0 → 1.5
    n = rng.binomial(N, 0.5, chains)                      # β = 0: 스핀마다 동전 던지기 (정확한 샘플)
    logw = np.zeros(chains)
    for k in range(1, K + 1):
        logw -= (betas[k] - betas[k - 1]) * E(2 * n - N)  # 온도를 바꾸는 순간의 일 × β
        for _ in range(N):                                # 메트로폴리스 한 번 훑기 (스핀 N개를 골라 뒤집기 시도)
            M = 2 * n - N
            up = rng.uniform(size=chains) < n / N         # 고른 스핀이 위를 향하는가
            M_new = np.where(up, M - 2, M + 2)
            ok = np.log(rng.uniform(size=chains)) < -betas[k] * (E(M_new) - E(M))
            n = np.where(ok, np.where(up, n - 1, n + 1), n)
    return n, logw

print(f"정확한 ln Z(1.5) − ln Z(0) = {lnZ(1.5) - lnZ(0):.3f}")
for K in (10, 100, 1000):
    n, logw = ais(K)
    est = logsumexp(logw) - np.log(len(logw))            # ln⟨e^(−βW)⟩
    w = np.exp(logw - logw.max()); ess = w.sum()**2 / (w**2).sum()
    print(f"사다리 {K:4d}칸: ln⟨e^(−W)⟩ = {est:6.3f}, ⟨ln e^(−W)⟩ = {logw.mean():6.3f}, "
          f"유효 표본 {ess:6.1f}/1000, 자화가 양수인 사슬 {np.mean(n > N / 2):.3f}")
# 정확한 ln Z(1.5) − ln Z(0) = 11.726
# 사다리   10칸: ln⟨e^(−W)⟩ = 15.336, ⟨ln e^(−W)⟩ =  3.408, 유효 표본    1.0/1000, 자화가 양수인 사슬 0.509
# 사다리  100칸: ln⟨e^(−W)⟩ = 12.053, ⟨ln e^(−W)⟩ = 10.151, 유효 표본   14.3/1000, 자화가 양수인 사슬 0.499
# 사다리 1000칸: ln⟨e^(−W)⟩ = 11.749, ⟨ln e^(−W)⟩ = 11.594, 유효 표본  734.6/1000, 자화가 양수인 사슬 0.501

사다리 1000칸에서는 ln⟨e^(−𝒲)⟩ = 11.749로 정확한 값 11.726에 가깝고, 로그 가중치의 평균 11.594는 그보다 조금 아래에 있는 하한이다. 사다리 100칸에서는 하한이 10.151로 멀어지고 유효 표본이 14개로 줄며, 10칸에서는 유효 표본이 1개뿐이어서 추정값이 사슬 하나의 운에 달린다. 어느 사다리에서든 자화가 양수인 사슬은 절반 근처여서, 사슬 무리가 한쪽 봉우리에 쏠리지 않는다.

ML에서: 제한 볼츠만 머신 로그우도의 치우침

샐러쿠트디노프와 머리(2008)는 AIS가 「Z의 불편 추정량을 준다」고 적었다. 이 장을 마친 독자는 「불편 추정량」에 단서를 붙여 읽는다. Z의 추정값은 치우치지 않지만 ln Z의 추정값은 사슬이 적거나 사다리가 짧으면 아래로 치우치고, 로그우도는 −(에너지) − ln Z이므로 ln Z를 작게 어림하면 모델이 실제보다 좋아 보인다. 부르다·그로스·샐러쿠트디노프(2015)가 목표 분포 쪽에서 거꾸로 담금질해 반대쪽으로 치우친 보수적인 추정값을 따로 만든 것이 이 때문이다.

ML에서: IWAE는 한 걸음도 움직이지 않는 AIS

VAE(variational autoencoder, 변분 오토인코더)의 ELBO는 근사 분포 q(h|x)에서 뽑은 잠재변수 하나로 ln p(x)의 하한을 만든다. 부르다·그로스·샐러쿠트디노프(2016)의 IWAE(importance weighted autoencoder, 중요도 가중 오토인코더)는 잠재변수를 K개 뽑아 중요도 가중치를 평균한 뒤 로그를 씌운다.

ELBOK=⟨ln⁡1K∑k=1Kpθ(x,hk)q(hk∣x)⟩hk∼q,ELBO=ELBO1≤ELBOK≤ln⁡pθ(x)\textcolor{#a000c8}{\mathrm{ELBO}}_K = \Big\langle \ln \frac{1}{\textcolor{#1f77b4}{K}} \sum_{k=1}^{\textcolor{#1f77b4}{K}} \frac{\textcolor{#bcbd22}{p_\theta}(\textcolor{#1b9e77}{x}, \textcolor{#1b9e77}{h}_k)}{\textcolor{#bcbd22}{q}(\textcolor{#1b9e77}{h}_k \mid \textcolor{#1b9e77}{x})} \Big\rangle_{\textcolor{#1b9e77}{h}_k \sim \textcolor{#bcbd22}{q}}, \qquad \textcolor{#a000c8}{\mathrm{ELBO}} = \textcolor{#a000c8}{\mathrm{ELBO}}_1 \le \textcolor{#a000c8}{\mathrm{ELBO}}_K \le \ln \textcolor{#bcbd22}{p_\theta}(\textcolor{#1b9e77}{x})
q(h∣x)인코더가 주는 근사 분포 (AIS의 출발 분포)x, hk데이터와, q 에서 뽑은 k번째 잠재변수pθ(x,h)디코더와 사전분포의 곱 (정규화 전 사후분포, 목표)pθ/q한순간에 바꿀 때의 가중치 e−WK뽑는 잠재변수 수 (사슬의 수)ELBOKIWAE의 하한 (K = 1이면 보통의 ELBO)\begin{array}{ll} \textcolor{#bcbd22}{q}(\textcolor{#1b9e77}{h} \mid \textcolor{#1b9e77}{x}) & \text{인코더가 주는 근사 분포 (AIS의 출발 분포)} \\ \textcolor{#1b9e77}{x},\ \textcolor{#1b9e77}{h}_k & \text{데이터와, } \textcolor{#bcbd22}{q} \text{ 에서 뽑은 k번째 잠재변수} \\ \textcolor{#bcbd22}{p_\theta}(\textcolor{#1b9e77}{x}, \textcolor{#1b9e77}{h}) & \text{디코더와 사전분포의 곱 (정규화 전 사후분포, 목표)} \\ \textcolor{#bcbd22}{p_\theta}/\textcolor{#bcbd22}{q} & \text{한순간에 바꿀 때의 가중치 } e^{-\textcolor{#ff7f0e}{\mathcal{W}}} \\ \textcolor{#1f77b4}{K} & \text{뽑는 잠재변수 수 (사슬의 수)} \\ \textcolor{#a000c8}{\mathrm{ELBO}}_K & \text{IWAE의 하한 (K = 1이면 보통의 ELBO)} \end{array}

이것은 q에서 사후분포로 한순간에 건너는, 한 걸음도 움직이지 않는 AIS를 사슬 K개로 돌려 ln⟨e^(−𝒲)⟩를 어림한 것이다. K = 1이면 로그 가중치의 평균, 곧 ELBO이고 그 틈은 한순간에 바꿀 때의 소산된 일 D_KL(q‖사후분포)다. K를 늘리면 틈이 줄지만 한순간에 건너는 한 소산된 일은 그대로여서, 차원이 높으면 K가 아주 커야 한다. 중간 분포를 두고 사슬을 움직여 소산된 일 자체를 줄이는 것이 AIS 쪽의 해법이다.

ML에서: 확산 모델 논문 제목의 「비평형 열역학」

확산 모델을 처음 제안한 졸-딕스타인과 동료들(2015)의 논문 제목은 「비평형 열역학을 이용한 깊은 비지도 학습」이다. 논문 요약은 이 방법이 「비평형 통계물리에서 착안해, 반복되는 전방 확산 과정으로 데이터 분포의 구조를 체계적이고 천천히 없애는」 것이라 적었다. 본문은 관련된 물리의 생각으로 「야르진스키 등식, 기계학습에서는 담금질 중요도 샘플링(AIS)으로 알려진 것」을 들고, 모델의 확률을 계산하는 대목에서 「담금질 중요도 샘플링과 야르진스키 등식에서 실마리를 얻어, 전방 경로와 역방향 경로의 상대 확률을 계산한다」고 썼다.

이 장을 마친 독자는 이 문장들을 크룩스 정리로 읽는다. 데이터 x₀의 확률은 역방향 경로의 확률을 전방 경로(앞으로 간 경로)의 확률로 나눈 비를 전방 경로들로 평균한 것이고, 학습 목표는 그 비의 로그 평균, 곧 경로 공간의 ELBO다. 그 틈은 전방 경로와 역방향 경로 사이의 KL, 곧 소산된 일이다. 확산 모델이 수백에서 수천 단계를 두고 「천천히」 구조를 없애는 것은 매개변수를 천천히 바꿀수록 소산된 일이 줄어든다는 이 장의 패턴을 그대로 따른 설계다.

문제 12. 복권 열 장의 평균

1000장 가운데 1장만 100만 원에 당첨되고 나머지는 꽝인 복권이 있다. (가) 한 장의 기대 당첨금은 얼마인가? (나) 10장을 사서 장당 평균 당첨금을 내면, 그 값이 기대 당첨금보다 작게 나올 확률은 얼마인가? 100장, 1000장이면?

김민준 M11
김민준

한 장에 100만 원 × 1/1000 = 1000원이요. 열 장을 사면 장당 평균도 대개 1000원 근처겠죠.

선생님 T14
선생님

열 장 가운데 당첨이 하나도 없을 확률은요?

이서연 S07
이서연

0.999의 10제곱이니까 0.990이에요. 열 번에 아홉 번 넘게 장당 평균이 0원이고, 드물게 1등이 섞이면 10만 원으로 뛰어요. 기댓값은 1000원이 맞는데 거의 늘 그보다 작게 나와요.

김민준 M08
김민준

100장이면 0.905, 1000장을 사야 0.368로 내려가네요. 기댓값을 끌어올리는 건 드문 1등 한 장이에요.

이서연 S09
이서연

평균은 치우치지 않는데 한 번 재서 나오는 값은 거의 늘 작다… 통계 수업에서 본, 오른쪽으로 꼬리가 긴 분포의 평균과 중앙값의 차이네요.

문제 13. 로그의 평균과 평균의 로그

용수철 덫을 κ = 1에서 4로 한순간에 조이는 실험을 n번 해서 −ln((1/n)Σe^(−𝒲))로 ΔF를 어림한다. 이 어림을 수천 번 되풀이해 평균을 내면 n = 1, 10, 100, 1000에서 각각 얼마인가? (풀어 본 뒤 아래 위젯 1의 「문제 13 불러오기」로 확인해 보자.)

직접 움직여 보기위젯 1: 몇 번씩 묶어 어림하기새 창에서 열기 ↗
김민준 M04
김민준

야르진스키 등식이 정확하다니까 n이 얼마든 평균은 0.693이겠죠. 돌려 볼게요. n = 1이면 1.495, n = 10이면 0.724, 100이면 0.697, 1000이면 0.692요. 어, n이 작으면 크게 틀리는데요?

이서연 S07
이서연

n = 1이면 −ln e^(−𝒲) = 𝒲니까 그냥 일의 평균 1.5를 잰 거야. 로그를 씌우고 평균을 낸 거랑 평균을 내고 로그를 씌운 게 다르잖아.

선생님 T14
선생님

등식이 정확한 건 e^(−𝒲)의 평균이에요. 그 평균은 몇 번을 하든 치우치지 않고 0.5를 향하지만, −ln은 아래로 볼록해서 −ln(평균)의 기댓값은 −ln 0.5보다 커요.

김민준 M08
김민준

아까 복권 문제랑 같네요. e^(−𝒲)가 큰 드문 경로가 1등이에요. 몇 번만 재서 평균을 내면 그 경로가 빠지니까 거의 늘 작게 나와요.

이서연 S09
이서연

그러면 ln Z를 어림하면 거의 늘 아래로 틀리는 거네. IWAE가 K를 늘리면 하한이 올라가는 것도 이거고.

선생님 T13
선생님

맞아요. 사슬을 늘리거나 소산된 일을 줄이면 치우침이 줄어요.

문제 14. 어떤 길로 옮겨 갈까

(가) 쉬운 분포 p₀에서 목표 p₁로 가는 중간 분포로, 에너지를 직선으로 섞은 p₀^(1−λ)p̃₁^λ 대신 확률을 직선으로 섞은 (1 − λ)p₀ + λp₁을 쓰면 안 되는가? (나) 모든 쌍이 J/N으로 묶인 스핀 100개에서 βJ = 1.5의 ln Z를 온도 사다리로 어림하라. 메트로폴리스 사슬 하나로는 무엇이 어려웠는가?

이서연 S11
이서연

확률을 섞는 쪽이 더 자연스러워 보이는데요. 두 분포 사이를 직선으로 가는 거니까요.

선생님 T02
선생님

p₁을 섞으려면 무엇이 필요하죠?

이서연 S08
이서연

아… 정규화된 p₁이요. 그러려면 Z₁을 알아야 하는데, 그걸 구하려고 하는 거잖아요. 에너지를 섞는 쪽은 정규화 전 밀도만 있으면 되고요. 로그를 직선으로 잇는 길이라서, 지수족으로 보면 자연 매개변수를 직선으로 옮기는 길이네요.

김민준 M11
김민준

스핀 100개는 메트로폴리스로 10만 번 훑어도 자화의 부호가 한 번도 안 바뀌었던 그 모형이죠. 온도 사다리를 βJ = 0에서 1.5까지 1000칸으로 놓았더니 ln Z(1.5) − ln Z(0)이 11.749, 정확한 값이 11.726이에요. 자화가 양수인 사슬은 0.501이고요.

이서연 S09
이서연

βJ가 작을 때는 봉우리가 하나라 부호를 자유롭게 바꾸다가, 사다리를 올라가며 양쪽 봉우리로 반씩 나뉜 거야. 게다가 한 번 돌리면 칸마다 ln Z(β)가 다 나오니까, 온도마다 따로 구한 자유에너지를 이 사다리 하나로 이어 붙여 견줄 수도 있겠네.

김민준 M06
김민준

그런데 10칸짜리 사다리로 돌렸더니 15.336이 나왔어요. 하한이라더니 참값보다 크잖아요?

선생님 T14
선생님

유효 표본은요?

김민준 M04
김민준

1.0이요… 사슬 하나가 가중치를 다 가져갔네요.

이서연 S07
이서연

치우침은 기댓값에 대한 말이잖아. 사슬 하나의 운에 달리면 이번처럼 위로도 튈 수 있어. 난수 시드를 바꿔 여덟 번 돌려 봤는데 9.4에서 11.8 사이로 퍼지고 대부분 참값보다 작아.

선생님 T14
선생님

그래서 AIS의 결과는 유효 표본과 로그 가중치의 평균을 함께 봐야 해요. 1000칸에서는 로그 가중치의 평균 11.594가 추정값 11.749 바로 아래에 있고, 두 값의 차이가 사다리가 충분히 촘촘한지 알려 줘요.