물리 모델과 학습 문제
먼저 읽을 장 9.6 ODE 수치해법1.3 문제를 수학적으로 정의하기
과학 머신러닝(scientific machine learning)은 "신경망에 물리를 넣는다"는 말로 자주 요약된다. 그런데 이 말은 너무 넓다. 물리 지식은 학습 데이터로도, 손실 함수의 한 항으로도, 모델 구조로도, 기존 시뮬레이터와 학습 모델을 잇는 방식으로도 들어갈 수 있고, 각 방식이 보장하는 것과 실패하는 방식이 다르다. 그 전에 더 기본적인 질문이 있다. 물리 모델의 어떤 양이 학습 문제의 입력이고, 어떤 양이 출력이며, 무엇을 추정하고 무엇을 고정하는가.
이 장은 24부 전체의 공통 언어를 만든다. 물리 모델을 구성 요소로 나누고, 그 변수들을 1.3장의 학습 문제 변수(입력·출력·상태·파라미터)에 대응시키고, forward·inverse·대리모델·발견의 네 가지 문제로 분류한다. 이어서 무차원화, 물리적 제약을 모델에 넣는 네 가지 경로와 보존량 검사, 그리고 예측 오차를 데이터·모델·수치 오차로 나누는 방법을 다룬다. 24.2장 이후의 PINN, neural ODE, neural operator는 모두 이 장의 분류 위에서 "어떤 문제를, 어떤 경로로 푸는가"로 읽을 수 있다.
학습 목표
- 물리 모델의 변수를 학습 문제의 변수에 대응시킨다
- 오차의 출처를 분해한다
- 물리 지식을 학습에 넣는 경로를 분류하고, 보존량으로 학습된 모델을 검사한다
물리 모델의 구성
왜 나누는가. "진자 모델"이라고 하면 보통 운동 방정식 하나를 떠올린다. 그러나 실제로 계산에 쓰이는 모델은 여러 부품의 조립이고, 학습으로 바꾸거나 보완하는 대상은 대개 그중 한 부품이다. 어떤 부품을 믿고 어떤 부품을 의심하는지 정하지 않으면, 학습이 무엇을 대신하는지도 말할 수 없다.
정의. 물리 모델은 다음 세 부품으로 나눌 수 있다.
- 지배 방정식(governing equation). 보존 법칙에서 나오는 방정식이다. 질량·운동량·에너지·전하의 수지(balance)를 쓴 것으로, 대개 가장 믿을 만한 부품이다. 예: 뉴턴의 운동 법칙 , 열의 보존 .
- 구성 관계(constitutive relation). 지배 방정식에 들어가는 플럭스나 힘을 상태와 잇는 관계다. Fourier 법칙 , 마찰 법칙, 반응 속도식, 상태 방정식이 여기에 속한다. 재료와 조건마다 다르고, 경험식인 경우가 많아 지배 방정식보다 덜 확실하다.
- 경계·초기 조건(boundary and initial conditions). 계가 바깥과 어떻게 상호작용하는지, 어떤 상태에서 출발하는지를 정한다. 같은 방정식도 조건이 바뀌면 다른 문제가 된다.
진자로 보면 의 골격은 뉴턴 법칙(지배 방정식), 마찰력 은 구성 관계, , 은 초기 조건이다. 실제 진자의 마찰이 속도에 비례하는지, 공기 저항처럼 속도의 제곱에 비례하는지는 실험으로 정할 문제다. 과학 머신러닝의 많은 연구가 바로 이 자리, 즉 불확실한 구성 관계를 데이터로 배우고 확실한 지배 방정식은 그대로 두는 설계를 다룬다(24.3장의 universal differential equation, 24.5장의 하이브리드 모델).
변수의 역할
대응 규칙. 1.3장은 학습 문제의 변수를 입력 , 출력 , 제어입력 , 파라미터 , 상태 로 나눴다. 물리 모델의 양도 같은 역할로 나눌 수 있다. 다만 진자 각도와 기호가 겹치지 않도록, 이 장에서는 물리 파라미터를 로 쓴다.
| 물리 모델의 양 | 학습 문제에서의 역할 | 진자 예 |
|---|---|---|
| 상태 | 시간에 따라 변하며 미래를 결정 () | 각 , 각속도 |
| 파라미터 | 계에 고정된 성질 () | 길이 , 중력 가속도 , 감쇠 계수 |
| 입력(강제항) | 바깥에서 주어지는 시간 함수 () | 받침점을 흔드는 외력 |
| 관측 | 상태의 함수로 측정되는 양 () | 카메라로 잰 각도, 잡음 포함 |
이 표에서 "학습되는 신경망 가중치"는 아직 없다. 신경망은 이 중 어떤 대응을 근사하는 함수로 들어간다. 예를 들어 (1) 상태에서 다음 상태로 가는 사상 전체, (2) 마찰력 같은 구성 관계 하나, (3) 파라미터와 초기 조건에서 관측으로 가는 사상 전체를 근사할 수 있다. 같은 진자라도 (1)은 데이터 기반 동역학 학습, (2)는 하이브리드 모델, (3)은 대리모델이 된다.
역할은 문제가 정한다. 길이 은 진자를 시뮬레이션할 때는 주어진 파라미터지만, 측정된 궤적으로 을 추정하는 문제에서는 구해야 할 미지수(출력)다. 1.3장에서 본 것처럼 역할은 변수 자체가 아니라 질문이 정한다. 문제 정의서에는 변수마다 역할, 단위, 측정 방법(직접 측정인지 다른 모델로 추정한 값인지)을 적는다.
문제의 종류
네 가지 문제. 물리 모델과 학습이 만나는 문제는 무엇을 알고 무엇을 구하는지에 따라 네 가지로 나뉜다.
| 종류 | 알고 있는 것 | 구하는 것 | 진자 예 | 다루는 곳 |
|---|---|---|---|---|
| forward | 방정식, 파라미터, 초기·경계 조건 | 상태의 궤적 | 로 계산 | 9.6장, 24.2장 |
| inverse | 방정식, 관측 | 파라미터(또는 초기 조건·강제항) | 측정한 로 추정 | 24.3장, 24.7장 |
| 대리모델(surrogate) | 시뮬레이터 실행 결과 다수 | 시뮬레이터를 흉내 내는 빠른 근사 | 를 신경망으로 | 24.4장, 24.5장 |
| 발견(discovery) | 관측 | 방정식의 형태 자체 | 마찰이 에 비례하는지 에 비례하는지 | 24.3장, 25부 |
forward 문제는 고전 수치해석(9부)이 이미 잘 푸는 문제다. 신경망으로 forward 문제를 푸는 방법(24.2장의 PINN)은 그 자체로는 고전 solver보다 빠르거나 정확하다는 보장이 없으므로, 왜 그 방법을 쓰는지를 따로 설명해야 한다. inverse 문제는 같은 관측을 설명하는 파라미터가 여럿일 수 있어(식별 불가능성, 24.6장) 해의 존재·유일성·안정성부터 따져야 한다. 대리모델은 학습 비용을 많은 반복 호출(설계 탐색, 불확실성 전파)로 회수하는 문제이므로, 학습에 쓴 시뮬레이션 수와 대리모델을 쓰는 호출 수를 함께 보고해야 공정하다.
대리모델과 forward 문제의 차이. 둘 다 "입력 → 해"를 계산하지만, forward 문제는 하나의 조건에 대해 방정식을 푼다. 대리모델은 조건의 분포에 걸친 사상을 배우므로, 학습 분포 밖의 조건에서는 보장이 없다. 대리모델을 평가할 때는 학습에 쓰지 않은 조건에서 시뮬레이터와 비교해야 하고, 그 비교의 기준이 되는 시뮬레이터 자체의 이산화 오차(9.7장)도 함께 적어야 한다.
단위와 무차원화
왜 필요한가. 물리량에는 단위가 있고 크기가 수십 자릿수에 걸친다. 온도 300 K, 농도 mol/L, 시간 s가 한 모델에 함께 들어오면, 숫자의 크기는 물리적 중요도가 아니라 단위 선택을 반영한다. 신경망과 경사하강은 단위를 모르고 숫자만 본다.
무차원화. 각 변수를 그 문제의 특성 척도로 나누어 단위 없는 변수로 바꾸는 것을 무차원화(nondimensionalization)라 한다. 진자 방정식 에서 시간 척도 를 잡고 로 바꾸면
가 된다. 원래 세 파라미터 가 무차원 수 하나 로 줄었다. 와 초기 조건이 같은 진자는 지구에 있든 달에 있든 같은 무차원 궤적을 그린다. 이 사실을 계산으로 확인한다. 셀은 이 장의 뒤 셀들이 쓰는 진자 함수도 정의한다.
import numpy as np
from scipy.integrate import solve_ivp
def pendulum(t_s, y, g_mps2, length_m, c_per_s): # y = (θ [rad], ω [rad/s])
theta, omega = y
return [omega, -(g_mps2 / length_m) * np.sin(theta) - c_per_s * omega]
cases = {"지구, L = 1 m ": (9.81, 1.0), "달, L = 0.25 m": (1.62, 0.25)}
tau = np.linspace(0, 20, 6) # 무차원 시각 τ = t / T0
for name, (g_mps2, length_m) in cases.items():
T0_s = np.sqrt(length_m / g_mps2) # 고유 시간 척도 [s]
sol = solve_ivp(pendulum, (0, 20 * T0_s), [1.0, 0.0], t_eval=tau * T0_s,
args=(g_mps2, length_m, 0.1 / T0_s), rtol=1e-10, atol=1e-12)
print(f"{name} T0 = {T0_s:.3f} s θ(τ) =", np.round(sol.y[0], 4))지구, L = 1 m T0 = 0.319 s θ(τ) = [ 1. -0.6782 0.1733 0.2604 -0.424 0.3094] 달, L = 0.25 m T0 = 0.393 s θ(τ) = [ 1. -0.6782 0.1733 0.2604 -0.424 0.3094]
두 진자의 시간 척도는 0.319 s와 0.393 s로 다르지만, 무차원 시각 에서 본 궤적은 소수점 넷째 자리까지 같다. 이것이 무차원화가 학습에 주는 첫 번째 이점이다. 모델이 배워야 할 것이 의 4차원 함수에서 의 2차원 함수로 준다. 무차원 수의 개수는 Buckingham 정리가 정한다. 차원이 있는 변수가 개이고 그 안에 독립인 기본 단위가 개 있으면, 관계는 무차원 수 개 사이의 관계로 쓸 수 있다.
두 번째 이점은 최적화다. 크기가 매우 다른 입력을 그대로 넣으면 손실의 Hessian이 극단적으로 ill-conditioned가 되어(10부), 경사하강이 작은 축의 방향으로 거의 움직이지 못한다. 온도(수백 K)와 농도( mol/L)로 반응 속도를 선형 회귀하는 문제를 원 단위와 표준화한 입력으로 각각 5000 step 경사하강한다.
rng = np.random.default_rng(0)
n = 200
temp_k = rng.uniform(280, 360, n) # 온도 [K]
conc_mol_l = rng.uniform(1e-4, 2e-3, n) # 농도 [mol/L]
rate = 0.02 * (temp_k - 300) + 800 * conc_mol_l + rng.normal(0, 0.05, n)
def gradient_descent(X, y, steps=5000): # X: (N, D), y: (N,)
H = X.T @ X / len(y) # 제곱 손실의 Hessian, (D, D)
lr = 1.0 / np.linalg.eigvalsh(H).max() # 발산하지 않는 가장 큰 학습률 근처
w = np.zeros(X.shape[1])
for _ in range(steps):
w -= lr * X.T @ (X @ w - y) / len(y)
return w, np.linalg.cond(H)
def standardize(v):
return (v - v.mean()) / v.std()
for name, X, scale in [("원 단위", np.column_stack([np.ones(n), temp_k, conc_mol_l]), 1.0),
("표준화 ", np.column_stack([np.ones(n), standardize(temp_k), standardize(conc_mol_l)]),
conc_mol_l.std())]:
w, cond = gradient_descent(X, rate)
exact = np.linalg.lstsq(X, rate, rcond=None)[0]
print(f"{name} cond(H) = {cond:.1e} 농도 계수(원 단위): " # 표준화한 계수는 원 단위로 되돌려 비교
f"경사하강 {w[2] / scale:6.1f} 최소제곱 해 {exact[2] / scale:6.1f}")원 단위 cond(H) = 3.5e+11 농도 계수(원 단위): 경사하강 0.0 최소제곱 해 805.7 표준화 cond(H) = 1.1e+00 농도 계수(원 단위): 경사하강 805.7 최소제곱 해 805.7
원 단위에서 Hessian의 조건수는 이다. 학습률은 가장 큰 고유값(온도 축)에 맞춰야 발산하지 않는데, 그 학습률로는 농도 축 방향의 오차가 사실상 줄지 않는다. 5000 step 뒤 농도 계수는 0.0으로, 데이터에 분명히 있는 농도 효과(최소제곱 해 805.7)를 전혀 배우지 못했다. 손실 곡선만 보면 온도 효과를 배우며 손실이 줄었으므로 학습이 잘된 것처럼 보인다는 점이 위험하다. 표준화하면 조건수가 1.1로 떨어지고 같은 step 수로 정확한 해에 도달한다.
연구에서의 의미. 표준화(평균을 빼고 표준편차로 나누기)는 데이터 기반 무차원화이고, 물리적 무차원화는 문제의 척도를 써서 같은 일을 한다. 물리적 척도를 쓰면 학습 데이터의 범위가 바뀌어도 변환이 그대로이고, 무차원 수(Reynolds 수, Damköhler 수, )가 모델 입력으로 바로 드러나 외삽의 방향을 해석하기 쉽다. 단위가 다른 출력 여러 개를 한 손실로 학습할 때도 같은 문제가 생긴다. 온도 오차(K)와 농도 오차(mol/L)를 그냥 더하면 숫자가 큰 쪽만 학습된다. 24.2장의 PINN에서 방정식 잔차와 경계 조건 손실의 크기가 맞지 않는 문제도 같은 뿌리다.
물리적 제약
어떤 제약이 있는가. 물리 지식 중 학습 모델에 넣을 수 있는 것은 방정식만이 아니다.
- 보존 법칙. 질량·에너지·운동량·전하의 총량이 (닫힌 계에서) 변하지 않는다.
- 대칭성. 좌표계를 회전·이동해도 법칙이 같다. 원자의 순서를 바꿔도 에너지가 같다(7.10장, 24.8장).
- 양수성. 농도, 밀도, 질량, 절대온도는 음수가 될 수 없다.
- 단조성과 부등식. 열은 뜨거운 곳에서 차가운 곳으로 흐르고, 고립계의 엔트로피는 줄지 않으며, 배터리 용량은 (가역 효과를 빼면) 사이클에 따라 늘지 않는다.
물리 지식을 넣는 네 가지 경로. 이런 지식을 학습 모델에 넣는 방법은 크게 네 가지로 나눌 수 있다. 이 분류는 Karniadakis 외(2021)의 리뷰가 쓴 관측 편향(observational bias)·학습 편향(learning bias)·귀납 편향(inductive bias)의 세 갈래에 하이브리드 결합을 더한 것이다.
| 경로 | 방법 | 보장 수준 | 예 | 다루는 곳 |
|---|---|---|---|---|
| 데이터 | 물리를 반영한 데이터를 더한다 | 데이터가 덮는 범위에서만 권장 | 시뮬레이션 데이터, 대칭 변환한 증강 데이터 | 15.6장, 7.10장 |
| 손실 | 방정식 잔차·제약 위반을 벌점으로 더한다 | 권장(soft). 학습점에서 근사적으로 | PINN의 잔차 항, 에너지 보존 벌점 | 24.2장 |
| 구조 | 모델의 형태가 제약을 자동으로 만족하게 한다 | 보장(hard). 모든 입력에서 정확히 | 등변 층, 양수 출력(, softplus), 보존형 이산화, Hamiltonian 구조 | 7.10장, 24.8장 |
| 하이브리드 | 확실한 물리 모델을 두고 불확실한 부품만 학습한다 | 확실한 부품이 지키는 제약은 보장 | 알려진 지배 방정식 + 학습된 구성 관계 | 24.3장, 24.5장 |
데이터와 손실 경로는 구현이 쉽지만 제약을 권장할 뿐이다. 학습 데이터나 collocation 점에서 멀어지면 제약이 깨질 수 있다. 구조와 하이브리드 경로는 제약을 보장하지만, 설계가 어렵고 제약이 틀렸을 때(대칭이 실제로는 깨진 문제, 24.8장) 모델이 데이터를 따라갈 수 없게 만든다. 어느 경로를 고를지는 그 제약을 얼마나 확신하는지가 정한다.
보존량 검사. 제약을 넣었든 넣지 않았든, 학습된 동역학 모델은 보존량으로 검사할 수 있다. 짧은 구간의 예측 오차는 작아도, 긴 rollout에서 에너지나 질량이 체계적으로 새는 모델은 물리적으로 쓸모가 없다. 마찰 없는 진자()의 궤적 20개(잡음 표준편차 )로 두 모델을 학습하고, 10000 step rollout에서 에너지 의 상대 변화를 잰다.
- 구조 없음. 다음 상태를 현재 상태의 3차 이하 다항식으로 직접 회귀한다. 무엇이든 표현할 수 있지만 에너지 보존을 모른다.
- 구조 있음. 운동 방정식이 꼴, 즉 힘이 위치에만 의존한다는 구조를 가정하고 만 홀수 차 다항식으로 회귀한다. 그리고 에너지를 보존하는 성질(symplectic)을 가진 Störmer–Verlet 방법 으로 적분한다.
dt = 0.1 # 무차원 진자 θ'' = -sin θ, 표본 간격
trajs = []
for theta0 in rng.uniform(-1.5, 1.5, 20):
s = solve_ivp(lambda t, y: [y[1], -np.sin(y[0])], (0, 10), [theta0, 0.0],
t_eval=np.arange(0, 10.001, dt), rtol=1e-10, atol=1e-12).y.T # (101, 2)
trajs.append(s + rng.normal(0, 1e-3, s.shape)) # 측정 잡음
def feats(s): # 3차 이하 다항식 특징, (..., 6)
th, om = s[..., 0], s[..., 1]
return np.stack([th, om, th**3, th**2 * om, th * om**2, om**3], -1)
X = np.vstack([s[:-1] for s in trajs]) # (2000, 2) 현재 상태
Y = np.vstack([s[1:] for s in trajs]) # (2000, 2) 다음 상태
W = np.linalg.lstsq(feats(X), Y - X, rcond=None)[0] # 구조 없음: 상태 변화를 직접 회귀
th3 = np.vstack([s[:, 0] for s in trajs]) # (20, 101)
acc = (th3[:, 2:] - 2 * th3[:, 1:-1] + th3[:, :-2]) / dt**2
a = np.linalg.lstsq(np.stack([th3[:, 1:-1].ravel() ** p for p in (1, 3, 5)], -1),
acc.ravel(), rcond=None)[0] # 구조 있음: 힘 g(θ)만 회귀
print("학습된 힘의 계수 (θ, θ³, θ⁵):", np.round(a, 3), " -sin θ의 Taylor 계수: [-1, 0.167, -0.008]")
energy = lambda th, om: 0.5 * om**2 - np.cos(th)
E0, steps = energy(1.0, 0.0), 10000
s, E_free = np.array([1.0, 0.0]), []
for _ in range(steps):
s = s + feats(s) @ W
E_free.append(energy(*s))
th = [1.0, 1.0 + 0.5 * dt**2 * a.sum()] # Störmer–Verlet로 학습된 힘을 적분
for _ in range(steps):
th.append(2 * th[-1] - th[-2] + dt**2 * (a @ [th[-1], th[-1]**3, th[-1]**5]))
th = np.array(th)
E_struct = energy(th[1:-1], (th[2:] - th[:-2]) / (2 * dt))
for k in [100, 1000, 10000]:
print(f"{k:5d} step까지 최대 |ΔE|/|E0| 구조 없음 {np.abs(np.array(E_free[:k]) - E0).max() / abs(E0):.4f}"
f" 구조 있음 {np.abs(E_struct[:k] - E0).max() / abs(E0):.4f}")학습된 힘의 계수 (θ, θ³, θ⁵): [-1.002 0.176 -0.012] -sin θ의 Taylor 계수: [-1, 0.167, -0.008] 100 step까지 최대 |ΔE|/|E0| 구조 없음 0.0010 구조 있음 0.0035 1000 step까지 최대 |ΔE|/|E0| 구조 없음 0.0063 구조 있음 0.0035 10000 step까지 최대 |ΔE|/|E0| 구조 없음 0.0608 구조 있음 0.0035
학습된 힘의 계수는 의 Taylor 계수와 정확히 같지 않다. 잡음과 유한한 데이터 때문이다. 그런데도 구조를 넣은 모델의 에너지 오차는 100 step에서 10000 step까지 0.0035에 머문다. 이 모델은 1차원에서 언제나 퍼텐셜 를 가진 보존력이고, Verlet 적분은 그 퍼텐셜의 에너지를 장기간 거의 보존하기 때문이다. 오차는 학습된 퍼텐셜이 참 퍼텐셜과 다른 만큼으로 유계다. 구조 없는 모델은 처음 100 step에서 오히려 더 정확하지만(0.0010), 오차가 step 수에 비례해 자라 10000 step에서 6%가 된다. 이것이 짧은 구간의 예측 오차만으로 동역학 모델을 평가하면 안 되는 이유이고, 보존량 검사는 그 차이를 값싸게 드러낸다.
오차의 분해
왜 나누는가. 학습된 모델이든 시뮬레이터든, 예측이 측정과 다를 때 원인은 여러 겹이다. 원인을 나누지 않으면 엉뚱한 곳을 고친다. 모델 오차가 지배적인데 데이터를 더 모으거나, 수치 오차가 지배적인데 신경망을 키우는 식이다.
정의. 예측 와 실제 값 의 차이를 세 가지로 나눈다.
은 참 파라미터를 넣은 모델 방정식의 정확한 해, 는 데이터로 추정한 파라미터 를 넣은 정확한 해, 는 그것을 solver로 근사한 값이다.
- 모델 오차(model error, model-form error). 방정식이 현실을 다르게 묘사해서 생기는 오차다. 선형화, 빠뜨린 물리 과정, 틀린 구성 관계가 원인이다. 데이터를 더 모아도 줄지 않는다.
- 데이터 오차. 측정 잡음과 유한한 데이터 때문에 파라미터나 초기 조건을 잘못 추정해서 생긴다. 무작위 잡음이 원인이면 데이터를 더 모을수록 줄어든다(대개 ). 측정 장비의 체계적 편향이 원인이면 줄지 않는다.
- 수치 오차. 이산화, solver tolerance, 부동소수점에서 생긴다(9부). 격자와 step을 줄이면 줄어든다.
감쇠 진자( m/s², m, s⁻¹, rad)의 s 각도를 기준으로 세 오차를 하나씩 만들어 크기를 비교한다.
g_mps2, length_m, c_per_s, T_s = 9.81, 1.0, 0.2, 10.0
y0 = [1.0, 0.0] # 초기 각 1 rad (약 57°)
def theta_at_T(rhs, length):
return solve_ivp(rhs, (0, T_s), y0, args=(g_mps2, length, c_per_s), rtol=1e-11, atol=1e-12).y[0, -1]
ref = theta_at_T(pendulum, length_m) # 기준: 참 모델, 참 파라미터, 엄격한 tolerance
y, h = np.array(y0), 0.01 # 수치 오차: explicit Euler, h = 0.01 s
for k in range(round(T_s / h)):
y = y + h * np.array(pendulum(k * h, y, g_mps2, length_m, c_per_s))
linear = lambda t, y, g, L, c: [y[1], -(g / L) * y[0] - c * y[1]] # 모델 오차: sin θ ≈ θ
period_s = 2 * np.pi * np.sqrt(length_m / g_mps2) + rng.normal(0, 0.01, 10) # 데이터 오차: 주기 측정 10회
length_hat = g_mps2 * (period_s.mean() / (2 * np.pi)) ** 2
print(f"기준 θ(10 s) = {ref:+.4f} rad")
print(f"수치 오차 (Euler h=0.01 s) {abs(y[0] - ref):.4f} rad")
print(f"모델 오차 (선형화) {abs(theta_at_T(linear, length_m) - ref):.4f} rad")
print(f"데이터 오차 (L 추정 {length_hat:.4f} m) {abs(theta_at_T(pendulum, length_hat) - ref):.4f} rad")기준 θ(10 s) = +0.2024 rad 수치 오차 (Euler h=0.01 s) 0.0432 rad 모델 오차 (선형화) 0.1619 rad 데이터 오차 (L 추정 1.0026 m) 0.0122 rad
초기 각이 1 rad인 진자에서는 선형화로 생기는 모델 오차(0.16 rad)가 가장 크고, explicit Euler 수치 오차(0.04 rad), 주기 측정 10회로 길이를 0.26% 틀리게 추정한 데이터 오차(0.012 rad) 순이다. 이 경우 주기를 더 정밀하게 재는 것은 거의 도움이 되지 않는다. 같은 계산을 초기 각 0.1 rad로 반복하면(집필 시점 실행) 선형화 오차는 rad로 세 오차 중 가장 작아지고, Euler 수치 오차(0.023 rad)가 가장 커진다. 오차의 순위는 모델의 성질이 아니라 문제 설정의 성질이다.
시뮬레이터–실험 불일치. 시뮬레이터로 만든 데이터로 학습하고 실험 데이터에 적용하면, 위 세 오차가 모두 섞인 차이(sim-to-real gap)를 만난다. 시뮬레이터의 모델 오차는 학습 데이터에 체계적으로 들어가 있으므로, 학습 모델이 시뮬레이터를 완벽히 흉내 낼수록 그 오차도 완벽히 물려받는다. 그래서 대리모델의 정확도는 "시뮬레이터 대비 오차"와 "실험 대비 오차"를 구분해 보고하고, 후자가 전자보다 작아질 수 없다는 점을 염두에 둔다. 9.7장의 격자 수렴 연구는 이 분해에서 수치 오차 항의 크기를 재는 도구다.
실습
물리 모델 하나를 골라 각 변수를 AI 모델의 입력·출력·파라미터에 대응시키고 오차 출처를 분석한다. 진자를 쓰거나, 자기 분야의 모델(반응기, 열전달, 배터리 등가회로, 개체군 모형)을 쓴다. 다음을 한 쪽 분량의 문제 정의서로 쓴다.
- 모델의 부품. 지배 방정식, 구성 관계, 경계·초기 조건을 나누어 쓰고, 각 부품을 얼마나 신뢰하는지와 그 근거를 적는다.
- 변수 대응표. 모든 양을 상태·파라미터·입력·관측으로 나누고 단위와 측정 방법을 적는다.
- 문제 종류. forward·inverse·대리모델·발견 중 하나로 정의하고, 학습 모델이 근사하는 사상을 "무엇 → 무엇"으로 한 줄로 쓴다.
- 무차원화. 특성 척도를 정하고 무차원 수를 유도한다. 학습 모델의 입력은 무차원 수로 쓴다.
- 제약과 경로. 지켜야 할 물리적 제약을 나열하고, 각각을 데이터·손실·구조·하이브리드 중 어느 경로로 넣을지 근거와 함께 정한다. 넣지 않는 제약은 학습 후 검사 항목으로 적는다.
- 오차 예산. 위 셀 4처럼 모델·데이터·수치 오차를 하나씩 만들어 크기를 비교하고, 가장 큰 항을 줄이는 계획을 쓴다.
셀 3의 코드를 바꾸어 다음을 확인한다. (1) 잡음 표준편차를 와 으로 바꾸면 두 모델의 에너지 오차가 어떻게 변하는가. (2) 구조 있는 모델을 Verlet 대신 explicit Euler로 적분하면 유계성이 유지되는가. 이 질문은 구조가 모델의 형태와 적분 방법 둘 다에 있다는 점을 보여 준다.
이어서 연습문제를 푼다. 반응 네트워크의 화학량론 행렬에서 보존량을 찾고, 궤적이 그것을 지키는지 검사한다.
실패 사례
- 무차원화 없이 크기가 다른 물리량을 함께 학습하는 것. 입력의 크기 차이는 경사하강을 멈추게 하고(셀 2), 출력의 크기 차이는 손실을 숫자가 큰 물리량이 독점하게 한다. 손실이 줄었다는 사실만으로는 모든 변수의 효과를 배웠는지 알 수 없다. 변수별 오차를 따로 본다.
- 문제 종류를 정하지 않고 "물리 기반 모델"을 만드는 것. forward 문제를 신경망으로 풀었다면 고전 solver와의 비용 비교가, 대리모델이라면 학습 분포 밖 조건에서의 검증이, inverse 문제라면 식별 가능성 분석이 필요하다. 종류가 정해지지 않으면 어떤 검증이 필요한지도 정해지지 않는다.
- 짧은 구간의 예측 오차로만 동역학 모델을 평가하는 것. 셀 3의 구조 없는 모델은 100 step에서 더 정확했지만 장기적으로 에너지가 샜다. 보존량, 양수성 같은 물리 검사를 긴 rollout에서 함께 보고한다.
- 오차를 분해하지 않고 모델을 키우는 것. 수치 오차가 지배적인 데이터로 학습하면 신경망을 아무리 키워도 그 바닥 아래로 내려가지 않는다. 시뮬레이터로 만든 label의 오차를 모르면 모델이 그 오차보다 좋아졌다는 주장도 할 수 없다.
통과 기준
- 물리 기반 학습 문제 하나를 forward·inverse·대리모델·발견 중 하나로 정의하고, 모든 변수의 역할·단위·측정 방법을 표로 적은 문제 정의서를 쓴다.
- 문제의 특성 척도로 무차원화하고, 무차원 수의 개수를 Buckingham 정리로 확인한다.
- 문제의 물리적 제약마다 넣을 경로(데이터·손실·구조·하이브리드)와 그 근거를 적고, 넣지 않은 제약은 학습 후 검사 항목으로 둔다.
- 학습된 동역학 모델 하나에 대해 보존량 또는 양수성 검사를 긴 rollout에서 수행하고, 연습문제
conserved-quantities의 테스트를 통과한다. - 예측 오차를 모델·데이터·수치 오차로 나누어 각각의 크기를 계산으로 비교하고, 가장 큰 항을 근거로 다음 작업을 정한다.
참고 문헌
- Karniadakis, G. E., Kevrekidis, I. G., Lu, L., Perdikaris, P., Wang, S., Yang, L. (2021). Physics-informed machine learning. Nature Reviews Physics, 3, 422–440. doi:10.1038/s42254-021-00314-5 — 물리 지식을 학습에 넣는 경로(관측·학습·귀납 편향)의 분류와 개관
- Greydanus, S., Dzamba, M., Yosinski, J. (2019). Hamiltonian neural networks. Advances in Neural Information Processing Systems 32. — 에너지 보존을 모델 구조(Hamiltonian)로 넣는 방법