Normalizing Flows
정규화 흐름은 가역 레이어를 통해 단순한 노이즈를 복잡한 데이터로 매핑하므로, 하나의 모델로 샘플링과 정확한 우도 계산을 모두 수행할 수 있습니다. 작동 방식을 살펴봅니다.
정규화 흐름은 단순한 기본 분포(대개 표준 가우시안 분포)를 일련의 가역적이고 미분 가능한 함수를 거쳐 복잡한 데이터 분포로 변환하는 생성형 AI 모델입니다. 모든 계층을 역방향으로 실행할 수 있고 부피에 미치는 영향을 정확히 계산할 수 있으므로, 정규화 흐름 하나로 대부분의 생성 모델이 함께 수행할 수 없는 두 가지 작업을 처리합니다. 즉, 노이즈를 계층에 순방향으로 통과시켜 새 샘플을 생성하고, 관측 데이터 포인트를 기본 분포까지 역방향으로 통과시켜 정확한 우도를 계산합니다. Esteban Tabak과 동료들은 2010년과 2013년에 밀도 추정을 위한 흐름을 정식화했으며, DeepMind의 Danilo Rezende와 Shakir Mohamed는 ICML 2015에서 정규화 흐름을 이용한 변분 추론을 발표해 이 명칭을 딥러닝에 도입했습니다. "정규화"는 데이터 분포를 정규분포, 즉 가우시안 분포로 변환한다는 뜻이며 배치 정규화와는 관련이 없습니다.
변수 변환 공식#
가역 함수 f가 데이터 포인트 x를 잠재 포인트 z = f(x)로 매핑하면, 데이터의 로그 우도는 log p(x) = log p_z(f(x)) + log |det J|입니다. 여기서 J는 f의 야코비안 행렬이며 행렬식은 f가 x 주변의 부피를 얼마나 늘리거나 줄이는지 측정합니다. D개 변수로 이루어진 일반 함수의 행렬식을 계산하려면 대략 D³ 연산이 필요하므로, 수십만 차원의 이미지에는 너무 느립니다. 따라서 흐름 계층은 대각 성분의 곱이 행렬식이 되는 삼각 야코비안을 갖도록 설계됩니다. 이러한 계층을 여러 개 쌓으면 변환이 합성되고 로그 행렬식의 합이 계산되며, 학습 데이터의 로그 우도를 직접 최대화하도록 학습합니다.
RealNVP의 아핀 결합 계층은 대표적인 설계입니다. 입력의 절반은 변경 없이 통과해 작은 신경망에 입력되고, 이 신경망은 나머지 절반의 스케일과 시프트를 설정합니다. 다음은 PyTorch 계층의 예입니다:
import torch
from torch import nn
torch.manual_seed(0)
# Affine coupling layer (RealNVP): x1 passes through unchanged and sets the scale and shift for x2
net = nn.Sequential(nn.Linear(2, 32), nn.Tanh(), nn.Linear(32, 4))
def coupling(x):
"""Map data x to z and return log|det J|, which is just the sum of the log-scales."""
x1, x2 = x.chunk(2, dim=-1)
log_s, t = net(x1).chunk(2, dim=-1)
return torch.cat([x1, x2 * log_s.exp() + t], dim=-1), log_s.sum(dim=-1)
x = torch.randn(4)
z, log_det = coupling(x)
jacobian = torch.autograd.functional.jacobian(lambda v: coupling(v)[0], x)
print(f"log|det J|: {log_det:.4f} from the formula, {torch.logdet(jacobian):.4f} from the full 4x4 Jacobian")
# Inverse: z1 equals x1, so the same scale and shift can be recomputed and undone
z1, z2 = z.chunk(2)
log_s, t = net(z1).chunk(2)
x_rec = torch.cat([z1, (z2 - t) * (-log_s).exp()])
print(f"Largest reconstruction error: {(x_rec - x).abs().max():.1e}")간단한 공식과 전체 야코비안은 모두 로그 행렬식 0.1489를 산출하며, 역변환 결과는 float32 반올림 오차인 1.2e-07 이내로 입력값을 복원합니다. 계층 내부의 신경망은 역변환할 필요가 없으므로 임의로 복잡하게 구성할 수 있습니다.
흐름 아키텍처#
- 결합 흐름: Laurent Dinh과 동료들이 개발한 NICE(2014)와 RealNVP(2016)는 변환되는 절반을 번갈아 바꾸며, OpenAI의 Glow(2018)는 학습 가능한 가역 1 x 1 컨볼루션을 추가해 사실적인 256 x 256 얼굴을 생성했습니다. 샘플링과 밀도 평가는 모두 빠릅니다.
- 자기회귀 흐름: 각 차원을 그보다 앞선 차원에 조건화해 변환합니다. 마스크 자기회귀 흐름은 한 번의 순전파로 밀도를 평가하지만 한 번에 한 차원씩 샘플링하며, 역자기회귀 흐름은 그 반대로 작동합니다. Apple의 TarFlow(2024)는 이미지 패치에 자기회귀 Transformer 블록을 쌓았으며, 샘플 품질이 확산 모델에 필적한 최초의 독립형 흐름 모델이었습니다.
- 연속 흐름: 변환을 상미분방정식의 해로 정의해 계층 설계 제약을 없앱니다. FFJORD(2018)는 확률적 트레이스 추정기로 로그 밀도 변화를 추적합니다.
응용 분야#
- 이상 탐지: DifferNet(2021), CFLOW-AD, FastFlow는 결함이 없는 제품 이미지에 대해 사전 학습된 컨볼루션 신경망의 특징에 흐름을 적합시키고, 우도가 낮은 이미지를 결함으로 표시합니다. FastFlow는 2021년 MVTec AD 산업 검사 벤치마크에서 이상 탐지 AUC 99.4%를 보고했습니다.
- 음성 합성: NVIDIA의 WaveGlow(2018)는 멜 스펙트로그램에서 단일 병렬 순전파로 음성을 생성했습니다.
- 과학적 샘플링: Frank Noé와 동료들의 Boltzmann 생성기(2019)는 분자와 단백질의 평형 상태를 샘플링하고, 정확한 우도를 사용해 샘플을 실제 물리적 분포에 맞게 재가중합니다.
이 탐지기들이 픽셀 대신 특징을 모델링하는 데는 이유가 있습니다. Eric Nalisnick과 동료들은 2019년에 CIFAR-10 사진으로 학습한 Glow 모델이 한 번도 본 적 없는 SVHN 주택 번호 이미지에 더 높은 우도를 부여한다는 사실을 보였습니다. 이후 이 실패는 흐름 모델이 이미지 내용보다 국소 픽셀 상관관계를 더 많이 모델링하기 때문인 것으로 밝혀졌습니다. 결함 탐지에서 흐름의 입력은 사전 학습된 어떤 백본에서 가져온 임베딩으로도 구성할 수 있습니다. Ultralytics YOLO26의 embed 메서드는 이미지마다 평균 풀링된 특징 벡터 하나를 반환하며, 기본적으로 탐지 헤드 바로 앞 계층의 특징을 사용합니다.










