카테고리 없음

[수식 이해] diffusion 기본개념 수식정리, Score-Based Generative Modeling through Stochastic Differential Equations, SDE-diffusion

도도걸만단 2025. 3. 19. 05:32
반응형

 

Score-Based Generative Modeling through Stochastic Differential Equations

 

 

diffusion model 

Diffusion model은 “정보를 점점 noise로 덮었다가, 그걸 다시 복원하면서 이미지(또는 데이터)를 생성하는 모델”

forward 과정: 깨끗한 이미지를 noise로 점점 망가뜨림

reverse 과정: noise를 조금씩 제거해서 원래 이미지를 복원함 → 여기서 이미지를 새로 생성할 수도 있음!

 

 

🧠 핵심 개념: Score-based Diffusion

score function: “지금 이 데이터가 어디로 가야 더 깨끗해질까?”를 알려주는 방향 정보

그 방향 정보를 따라가면 → 노이즈 제거 → 이미지 생성!


 

 

🔹 수식 (1)

 

dx = f(t)xdt + g(t)dw

 

• forward diffusion 과정을 수학적으로 표현.

x: 현재 시점의 latent 상태 (노이즈가 섞여 있음)

f(t): 시간에 따라 변하는 데이터의 drift (데이터가 어디로 흐를지)

g(t): 얼마나 노이즈를 섞을지

dw: 랜덤한 noise (Brownian motion, 즉 랜덤으로 움직임)

 

점점 더 이미지를 노이즈로 바꿔가는 과정.

즉, 깨끗한 이미지 → 점점 노이즈 이미지로 바뀜.

 

🔍 w: Wiener process (브라운 운동)

• w는 수학적으로 Brownian motion 또는 Wiener process를 뜻함.

시간에 따라 완전 랜덤 하게 움직이는 함수.

• dw는 그 미분형태로, 아주 짧은 시간에 일어나는 무작위 변화량.

 

Q1. 수식 (1)에서 왜 좌변이 dx인가?

“왜 현재 시점의 latent 상태를 미분해야 하지? dx가 중요한 이유는?”

 

수식 (1)은 일반적인 **확률 미분 방정식 (SDE: Stochastic Differential Equation)**의 형식. 이 식에서 dx는 “**time t**이 아주 조금 변했을 때, latent 상태 x가 얼마나 변하는가”를 의미함.

 

 dx: 작은 시간 변화 dt 동안, x가 얼마나 변화하는지

 즉, 이건 “변화량의 모델링”. deterministic (규칙적) + stochastic (랜덤) 변화의 합으로 모델링하는 것.

 

🎯 왜 중요하냐면?

 diffusion model은 시간에 따라 데이터가 어떻게 노이즈로 바뀌는가를 모델링함.

 그 변화 과정을 제대로 추적하려면 미분 기반 표현이 필요함.

 특히, SDE에서는 “데이터가 어떻게 랜덤하게 움직이는지”를 기술할 수 있는 유일한 도구가 바로 이런 미분 표현임.


🔹 수식 (2)

dx = \left[f(t)x - \frac{1}{2}g^2(x)\nabla_x \log(q_t(x))\right]dt

 

 

reverse diffusion, 즉 노이즈를 제거하면서 원래 이미지로 돌아가는 과정

\nabla_x \log(q_t(x)): 현재 데이터 분포의 score function임.

→ 지금 x가 어디로 가야 진짜 이미지 분포에 가까워지는지를 알려줌.

이건 데이터가 어디로 가야 “덜 노이즈스럽게” 될지를 알려주는 방향 vector

 

결론: 이 식은 노이즈 제거 방향으로 천천히 이동하는 수학적 표현.

 

Q2. w, dw는 뭐고 왜 t로 바뀌었지?

왜 수식 (2)에서는 dw가 사라지고 dt만 남았을까?

 

 수식 (1)은 forward diffusion, 즉 데이터에 노이즈를 추가하는 과정

 수식 (2)는 reverse diffusion, 즉 노이즈를 제거하는 과정인데

 이 reverse 과정은 확률적이 아니라 평균적인 경로(ODE)로 기술됨!

그래서,

 수식 (2)는 확률적 SDE를 평균적인 역방향 경로로 바꾼 deterministic ODE

 여기서는 노이즈가 아닌 score function 방향으로만 이동하므로 dw가 사라짐.

 

수식 (2)는 기본적으로 SDE의 역과정(Schrödinger bridge 해석)을 deterministic하게 기술한 것임.

Q3. dt는 왜 t에 대해 미분하는 거지? 모든 게 t 기준?

그렇다. diffusion model은 시간 t를 축으로 두고 전개됨.

 시간 t = 0이면 깨끗한 이미지

 시간 t = 1이면 완전한 노이즈

 diffusion은 이 시간 흐름에 따라 이미지를 노이즈화하거나 반대로 노이즈를 제거함

 

따라서 모든 변화량은 시간 기준의 미분량으로 표현 :

dx = \text{데이터가 시간 } t \text{동안 어떻게 움직이는가}

Q5. 수식 (1) → 수식 (2)에서 왜 g(t) -\frac{1}{2}g^2(x)로 바뀌어?

Ito calculus (확률 미적분) 를 기반으로 한 변화.

 수식 (1)은 SDE, 수식 (2)는 역방향 ODE

 이때 SDE에서 ODE로 바꾸는 과정에서, score function 항이 gradient와 결합되면서 -\frac{1}{2}g^2(x)\nabla_x \log q_t(x) 형태가 나옴.

이건 확률 해석학적으로 증명된 결과이고, noise 항이 역방향 score에 어떤 영향을 주는지를 수학적으로 반영.

 


🔹 수식 (3)

\mathcal{L} = \gamma(t)\|S_\theta(x, t) - \nabla_x \log(q_t(x))\|^2_2

 

• score function을 학습하는 loss 함수

S_\theta(x, t): 모델이 학습해서 만든 score function (예: U-Net이 출력하는 결과)

오른쪽의 true score와 얼마나 가까운지를 계산해서 학습함.

 

쉽게 말해, “진짜 방향”이랑 “내가 예측한 방향”의 차이를 줄이려고 학습

 

Q4. 수식 (3)의 \gamma(t)는 왜 곱하지?

 \mathcal{L} loss function, 학습 시 사용하는 손실 함수

 

 여기서 \nabla_x \log q_t(x): 진짜 score (데이터 분포의 gradient)

 S_\theta(x, t): 학습된 모델의 출력 (예: U-Net의 출력)

 \gamma(t): 시간에 따라 각 샘플의 loss 중요도를 조절하는 가중치 함수

 

 왜 필요하냐면?

 초기에 노이즈가 많을수록, score 추정이 더 불확실하고 중요한 역할을 함.

 그래서 시간 t에 따라 loss를 다르게 줄 필요가 있음 → 이걸 조절하는 게 \gamma(t)


🔹 수식 (4)

dx = \left[f(t)x - \frac{1}{2}g^2(x)S_\theta(x, t)\right]dt

 

👉 위의 수식 (2)에서 모델이 학습한 score function S_\theta을 집어넣은 버전

 

이 수식으로 노이즈 제거 과정을 진행하면서 깨끗한 이미지를 복원함.


🔹 수식 (5)

dx = \left[f(t)x - \frac{1}{2}g^2(x)\frac{\mu_t - x}{\sigma^2(t)}\right]dt

 

좀 더 실제 구현에 가까운 식

\mu_t: 현재 노이즈 이미지 x에서 denoising한 결과 (깨끗한 이미지 추정)

\sigma(t): 현재 시점의 noise 수준

 

“지금 noisy image x와 깨끗한 예측값 \mu_t” 사이의 차이를 보고, 그 방향으로 얼마나 이동할지를 계산한 것.

Q6. 수식 (4) → (5)에서 왜 \sigma(t)^2로 나눠? 가우시안이랑 관련 ?

배경:

 대부분의 diffusion model은 Gaussian noise를 사용함.

 이 때 score function은 다음과 같은 형태로 근사:

 

\(\nabla_x \log q_t(x) \approx \frac{\mu_t - x}{\sigma^2(t)}\)

 

→ 이건 denoising score matching에서의 closed-form score임. 즉, 정답 이미지 \mu_t와 현재 noisy 샘플 x의 차이로 score를 계산하는 방식.

 

그래서 수식 (5)는 학습된 score를 직접 쓰는 대신, Gaussian 가정 하에서 계산된 score를 사용하는 형태로 바뀜.

 

 


🔹 수식 (6)

dx = \frac{x - \mu_t}{\sigma(t)} d\sigma(t)

 

👉  특수한 경우: variance exploding (VE) diffusion.

식 (5)의 특별한 조건에서 단순화된 것임

x에서 \mu_t 방향으로 noise를 줄이면서 이동함.

 

이건 실제 구현에서 자주 쓰이는 형태로, 노이즈 제거 경로를 따라 이동하는 단순한 표현

 


1. sigma란?

정확한 의미:

sigma는 noise scale, 즉 diffusion process에서 각 시간 단계(timestep)에 해당하는 노이즈의 세기입니다.

• diffusion 모델은 이미지를 점점 noise로 바꾸는 forward process

• 노이즈에서 이미지를 복원하는 reverse process (denoising) 를 반복합니다.

• 이때 각 단계마다 얼마나 noisy한 샘플을 처리해야 하는지 정해주는 값이 바로 sigma.

 

Stable Diffusion에서의 역할:

• sigma는 denoising loop에서 사용되며, noise level이 높은 초기 단계부터, 점점 noise가 줄어드는 후반 단계까지 스케줄링되어 있습니다.

• scheduler.set_timesteps()를 통해 noise level (sigma) 리스트가 설정됩니다.

• 즉, sigma_list는 timestep에 대응되는 노이즈 강도의 리스트라고 보면 됩니다.

 

예시:

sigma_list = np.load('sigmas/sigmas_25.npy')

• 이건 inference 단계에서 사용할 noise schedule로,

• 25개의 timestep에 해당하는 noise level을 의미합니다.

(예: timestep 0에는 sigma=5.0, timestep 1에는 sigma=4.3 … 이런 식)


2. num_frames은 뭐고 왜 맞춰야 해?

num_frames의 의미:

• 생성할 비디오의 프레임 수입니다.

• 예를 들어 num_frames = 10이면 10장의 이미지 (시점별 view) 를 생성합니다.

• 이건 곧 하나의 카메라 트랙을 따라간 결과물이죠.


왜 num_frames과 sigma_list는 연관이 있는가?

lambda_ts (lambda schedule)는 (sigma 개수) × (num_frames 개수) 만큼의 weight를 계산합니다:

lambda_t_list_optimized = lambda_t_list_optimized.reshape([len(sigmas), num_frames])

즉, search_hypers() 함수에서:

• 각 sigma에 대해,

• 각 프레임별로 lambda_t라는 가중치를 계산합니다.

그래서 len(sigmas) * num_frames 개수만큼의 값이 필요합니다.

👉 하나라도 길이가 안 맞으면 reshape 에러 발생!


💡 요약 정리

항목 의미 예시

sigma timestep에 해당하는 noise level (scheduler에서 사용) [5.0, 4.3, …, 0.1] (25개)
num_frames 생성할 영상의 프레임 수 10이면 영상은 10장짜리
둘의 연관 lambda_ts 계산 시 sigma × num_frames만큼 weight 생성 [25, 10]이면 250개 필요

 

lambda_ts(sigma 개수 × num_frames)만큼 필요한가?
모델이
“각 timestep(sigma)에 대해 모든 frame에 다르게 반응하도록” 설계되어 있기 때문이에요.

 

기본 아이디어

 

이 구조는 2D 테이블 형태의 weight 스케줄을 만든다고 생각하시면 돼요.

          Frame 0   Frame 1   ...  Frame N
sigma_0   λ₀₀      λ₀₁      ...   λ₀N
sigma_1   λ₁₀      λ₁₁      ...   λ₁N
...       ...      ...      ...   ...
sigma_S   λS₀      λS₁      ...   λSN

sigma_s: s번째 timestep (noise level)

frame_f: f번째 프레임

lambda_t[s][f]: s번째 timestep에서 f번째 프레임에 적용할 가중치

 


왜 이렇게 해야 하느냐?

 

1. lambda_t는 denoising 반복(loop) 안에서 사용돼요.

denoising은 timestep마다 진행되므로 sigma 개수 만큼 반복됨

매 반복에서, 전체 프레임에 대한 gradient/condition 계산이 들어감

→ 따라서 각 timestep에 대해 모든 프레임의 가중치가 있어야 함

 

2. 시간(timestep)과 공간(frame)이 모두 중요한 문제

diffusion이 noise 제거를 timestep 단위로 하듯이,

프레임 별로도 temporal variation이 있으므로 frame-wise control도 필요

이걸 동시에 조절하려면 (sigma × frame)만큼의 가중치가 필요해요

 

 수식적으로 보면?

lambda_t_list_optimized = lambda_t_list_optimized.reshape([len(sigmas), num_frames])

이건 결국 이런 걸 만드는 거예요:

lambda_t_list_optimized[s][f]

→ s번째 sigma, f번째 frame에 사용할 가중치 λₛf

 

직관적으로 표현하자면:

sigma는 시간축

→ “지금 얼마나 noisy한 상태인가?”

frame은 공간축 (viewpoint)

→ “지금 몇 번째 프레임 (시점)인가?”

lambda_ts는 이 시간×공간을 커버하는 가중치 테이블

→ noise 강도와 프레임 위치에 따라 다른 보정값을 주는 거죠

 


결론: 왜 곱하냐?

 

각 timestep마다 모든 프레임을 커버해야 하니까

→ 전체 weight 수 = timestep 수 (sigma 개수) × 프레임 수 (num_frames)

 


💡 핵심 용어 정리

 

1. timestep

Diffusion process에서 “denoising을 몇 번에 걸쳐 할 것인가”를 결정하는 시간축 개념이야.

예: num_inference_steps=25이면, 25개의 timestep을 통해 점점 noise를 제거해 나가며 이미지를 복원해.

각 timestep마다 latent는 조금씩 denoise 됨.

 

2. sigma

각 timestep마다 사용되는 noise 수준 (standard deviation) 을 나타내.

일반적으로 timestep이 클수록 noise는 크고 (큰 sigma), 작을수록 noise는 적어 (작은 sigma).

diffusion 모델에서는 시간 t에 대응되는 sigma 값을 사전에 정한 schedule에 따라 사용해.

 

3. num_frames

생성할 비디오 프레임 수. 예: num_frames=25이면 25장의 이미지를 생성하게 돼.

각 프레임은 같은 시간축에서 함께 denoising을 당하지만, 위치나 latent 상태는 다를 수 있음.

 


🧠 구조적으로 어떻게 연관돼 있는가?

 

✅ 매 timestep마다 일어나는 일:

1. latent tensor는 num_frames개의 프레임에 대해 존재함 (shape: [B, num_frames, C, H, W]).

2. 하나의 timestep에서 전체 프레임(batch of frames) 에 대해 denoising을 수행해.

3. 이 denoising 과정에서, 프레임마다 조금씩 다른 guidance를 줄 수 있도록 하기 위해 frame별 lambda (weight) 를 적용해.

 


📌 그래서 lambda_ts는 왜 (sigma 개수 × num_frames) 짜리인가?

1. sigma 개수 = inference timestep 수 = num_inference_steps

2. 각 timestep에서 프레임마다 개별로 weight를 주려면, 프레임 수만큼 lambda가 필요해.

3. 따라서 전체 denoising process 동안 총 num_inference_steps × num_frames 개의 weight가 필요하게 돼.

 

즉, 각 timestep t에 대해 25개의 프레임이 있으면, 그 timestep에서 25개의 lambda를 적용해서 프레임별로 가중치를 다르게 줄 수 있음.

 


❓ 질문: sigma가 25개면, timestep 하나당 25번 denoise하냐?

 

➡️ 아니야!

sigma가 25개라는 건, 총 25개의 timestep이 있고, 각 timestep마다 하나의 sigma가 쓰인다는 뜻이야.

각 timestep은 한 번의 denoise만 수행해.

대신 그 denoising은 num_frames 개 프레임에 동시에 적용되는 거지.

 


🧭 비유로 설명하자면…

25개의 노이즈 레벨(sigma) = 25개의 정해진 날씨 변화.

하루하루(= timestep) 날씨가 달라짐.

근데 매 날, 25명의 사람이(= 프레임) 다 같이 외출해야 함.

그래서 날마다, 사람마다 옷차림(lambda_ts)을 다르게 챙겨야 하는 거야.

 


 

반응형