1-2. DDPM: 확산 모델의 출발점
노이즈를 조금씩 1000번 섞는다. 그리고 그 한 걸음씩을 되돌리는 법을 배운다. 2020년에 나온 DDPM이 이 방법으로 이미지 생성의 판을 바꿨다. 지금 쓰는 모델은 전부 여기서 갈라져 나왔다.
한 번에 되돌릴 수 없는 이유
순수 노이즈에서 그림으로 한 번에 가는 함수를 배우면 될 것 같다. 잘 안 된다.
0-6 실습의 마지막을 떠올리자. 노이즈가 많이 섞인 그림에서는 원본이 무엇인지 알 수 없다. 가능한 답이 수없이 많다. 모델은 그 답들의 평균을 내놓는다. 평균은 흐릿한 덩어리다.
그래서 일을 잘게 쪼갠다. "노이즈가 아주 조금 더 섞인 그림"에서 "조금 덜 섞인 그림"으로 가는 한 걸음은 쉽다. 가능한 답의 범위가 좁기 때문이다.
순방향: 조금씩 섞는다
t번째 걸음에서 하는 일은 이렇다.
x_t = √(1 − β_t) · x_(t−1) + √β_t · ε
β_t: 이번 걸음에 섞는 노이즈의 양. 아주 작은 값이다(0.0001에서 0.02).- 앞 단계의 그림을 살짝 줄이고, 새 노이즈를 살짝 더한다.
이것을 1000번(T = 1000) 한다. 끝에 가면 순수 노이즈가 된다.
건너뛰기
학습할 때마다 1000번을 다 밟을 수는 없다. 0-1의 성질 2가 여기서 쓰인다. 가우시안 노이즈를 여러 번 더한 것은 큰 가우시안 노이즈를 한 번 더한 것과 같다. 그래서 원본에서 t번째 단계로 한 번에 갈 수 있다.
x_t = √ᾱ_t · x₀ + √(1 − ᾱ_t) · ε
ᾱ_t(알파 바)는 (1 − β)를 처음부터 t까지 전부 곱한 값이다. 원본이 얼마나 남았는지를 나타낸다. 1에서 시작해 0으로 내려간다.
0-1의 식과 나란히 놓아 보자.
| 원본의 계수 | 노이즈의 계수 | 규칙 | |
|---|---|---|---|
| 0-1의 식 | 1 − t | t | 두 계수의 합이 1 |
| DDPM | √ᾱ_t | √(1 − ᾱ_t) | 두 계수의 제곱의 합이 1 |
구조는 같다. "원본을 줄이고 노이즈를 늘린다." 계수를 정하는 규칙만 다르다. DDPM의 규칙은 섞인 결과의 분산이 항상 1로 유지되게 한다.
역방향: 한 걸음씩 되돌린다
x_t를 보고 x_(t−1)을 뽑고 싶다. 0-2에서 본 "조건의 방향 뒤집기"다. 직접 계산할 수는 없다.
여기서 걸음을 작게 잡은 덕을 본다. 한 걸음이 충분히 작으면, 되돌아가는 분포도 가우시안에 가깝다. 가우시안은 평균과 퍼짐만 알면 된다. 퍼짐은 미리 정해 두고, 평균만 신경망이 맞히게 한다.
그리고 0-2의 마지막 절이 그대로 쓰인다. 퍼짐이 같은 두 가우시안의 KL은 평균의 제곱 오차다. 복잡한 확률 식이 제곱 오차 하나로 줄어든다.
무엇을 맞히게 하나
평균을 직접 맞히게 할 수도 있다. 그런데 식을 정리하면, 평균을 맞히는 것은 "섞인 노이즈 ε을 맞히는 것"과 같은 일이 된다. ε을 알면 평균이 계산되기 때문이다. 그리고 ε을 맞히게 하는 쪽이 학습이 잘 된다.
손실 = ‖ ε − ε_θ(x_t, t) ‖²
ε_θ가 신경망이다. 섞인 그림과 t를 받아 노이즈를 내놓는다. 0-6에서 만든 디노이저가 바로 이것이다.
학습 절차
반복:
그림 x₀ 을 하나 뽑는다
t 를 1~1000 에서 무작위로 고른다
ε 을 N(0, 1) 에서 뽑는다
x_t = √ᾱ_t · x₀ + √(1 − ᾱ_t) · ε
신경망이 x_t, t 를 보고 ε 을 예측한다
예측과 진짜 ε 의 제곱 오차를 줄인다
0-6의 코드와 한 줄만 다르다. 섞는 식의 계수다.
생성 절차
x 를 N(0, 1) 에서 뽑는다 (순수 노이즈)
t = 1000 부터 1 까지:
신경망이 x 에 섞인 노이즈를 예측한다
그 노이즈를 한 걸음만큼 걷어 낸다
(마지막 걸음이 아니면) 새 노이즈를 조금 더한다
x 가 생성된 그림이다
한 걸음의 식은 이렇다.
x_(t−1) = (1/√α_t) · ( x_t − (β_t / √(1 − ᾱ_t)) · ε_θ(x_t, t) ) + σ_t · z
α_t = 1 − β_t이고 z는 새로 뽑은 노이즈다. 외울 필요는 없다. "예측한 노이즈를 조금 빼고, 새 노이즈를 조금 더한다"로 읽으면 된다.
걷어 내면서 왜 다시 더할까. 되돌아가는 분포에서 평균이 아니라 표본을 뽑아야 하기 때문이다. 평균만 따라가면 0-6에서 본 것처럼 뭉개진다.
DDPM의 약점
느리다. 그림 한 장에 신경망을 1000번 불러야 한다. 이 문제를 푸는 것이 다음 수업의 샘플러이고, 1-7의 증류다.
맞히는 대상의 종류
ε 말고 다른 것을 맞히게 해도 된다. 셋은 서로 변환된다. 하나를 알면 나머지가 계산된다.
| 이름 | 맞히는 것 | 쓰는 곳 |
|---|---|---|
| ε 예측 | 섞인 노이즈 | SD 1.5, SDXL |
| x₀ 예측 | 원본 그 자체 | 일부 모델 |
| v 예측 | 노이즈와 원본을 섞은 값 | SD 2.x, 일부 SDXL 파생 모델 |
모델을 내려받을 때 "v-pred"라고 적혀 있으면 세 번째다. 도구에서 예측 방식을 맞춰 주지 않으면 그림이 깨진다.
노이즈 스케줄
β_t를 걸음마다 어떻게 정할지를 노이즈 스케줄이라고 한다. 처음 DDPM은 일정하게 늘렸다(선형). 그러면 뒤쪽 걸음들이 이미 노이즈뿐인 그림에 노이즈를 더하느라 낭비된다. 그래서 천천히 섞는 코사인 스케줄 등이 나왔다.
스케줄은 모델을 학습할 때 정해진다. 생성할 때 고르는 "스케줄러"는 이것과 다른 것이다. 다음 수업에서 구분한다.
확인 문제
ᾱ_t = 0.25일 때 원본의 계수와 노이즈의 계수는 각각 얼마인가?- DDPM이 한 번에 되돌리지 않고 1000걸음으로 나누는 이유는?
- 생성할 때 노이즈를 걷어 내면서 새 노이즈를 다시 더하는 이유는?
풀이
- 원본 0.5, 노이즈 약 0.87이다. √0.25 = 0.5, √0.75 ≈ 0.866이다. 제곱해서 더하면 1이다.
- 한 번에 되돌리면 가능한 답이 너무 많아 평균(흐릿한 덩어리)이 나온다. 걸음이 작으면 되돌아가는 분포가 가우시안에 가까워서 평균만 맞히면 된다.
- 되돌아가는 분포의 평균이 아니라 표본을 뽑아야 하기 때문이다.