U-Net: 여러 해상도로 잡음을 읽는다

자주 하는 실수와 요약

자주 하는 실수

실수 나온 문제 바로잡는 법
축척을 줄이는 횟수를 너비의 비로 셈 1 한 번 줄일 때마다 너비가 두 배다. 2j로 센다
해상도를 낮춘 단계의 층도 원래 칸으로 2칸씩만 넓힌다고 셈 2, 3 한 칸이 원래 2j칸을 맡는 단계의 k칸 커널은 (k − 1) × 2j칸을 넓힌다
줄이는 층은 닿는 폭을 넓히지 않는다고 봄 2 두 칸 평균도 커널이 2칸인 층이다. 그 단계의 칸 너비만큼 넓힌다
줄인 그림을 잘 키우면 가는 결이 돌아온다고 봄 4 서로 다른 원래 그림이 같은 줄인 그림이 된다. 지운 결은 건너뛰기 연결로 건네야 한다
쓸 수 있는 가운데 부분이 아니라 입력 전체 폭으로 타일 수를 셈 5 답을 내는 가운데 폭(388)으로 나누고, 입력은 가장자리만큼 겹친다
건너뛰기 연결의 이어 붙이기와 더하기가 같다고 봄 6 이어 붙이면 두 출처에 다른 가중치를 줄 수 있다. 더하기는 그 가운데 두 가중치를 같게 묶은 경우다
빠른 바늘 하나로 시각을 다 적을 수 있다고 봄 7 빠른 바늘은 한 바퀴 돌면 겹친다. 빠르기가 다른 바늘을 함께 써야 한다
사인 인코딩이 「비슷한 잡음 수준」을 알고 있다고 봄 8 사인 인코딩의 닮음은 두 걸음의 차이에만 기댄다. 수준 사이의 뜻은 학습이 정한다
시간을 주지 않으면 잡음 예측 신경망이 전혀 일하지 못한다고 봄 9 그림 자체가 잡음 크기를 꽤 알려 준다. 남는 비율을 그림에서 가르기 어려운 짙은 잡음에서 차이가 커지고, 시간을 받은 신경망은 받은 값에 크게 기댄다
층을 더 쌓으면 적어도 학습 오차는 줄어든다고 봄 10, 11 표현력은 늘어도 최적화가 어려워진다. 입력을 그대로 넘기는 잔차 블록이 그 길을 연다
잔차 블록을 0으로 시작하면 그냥 쌓은 층처럼 학습이 막힌다고 봄 11 잔차 블록은 0에서 시작해도 출력이 입력과 같고 기울기 1이 그대로 닿는다
시간 MLP 만 시간을 받는 매개변수로 셈 12 블록마다 시간 벡터를 채널 수로 바꾸는 층까지 센다

요약

3 × 3 합성곱을 그대로 쌓으면 출력 한 칸이 기대는 폭이 층 수의 제곱근으로만 넓어진다. 해상도를 낮춰 한 칸이 원래 2j칸을 맡게 하면, 같은 커널이 (k − 1) × 2j칸씩 넓혀 몇 단계 만에 그림 전체에 닿는다. 묶은 칸에서는 잡음도 평균으로 줄어 짙은 잡음 속의 굵은 윤곽을 찾기 쉽다. 그러나 줄인 그림을 다시 키우기만 해서는 지운 가는 결이 돌아오지 않는다. 내려가는 길의 단계마다 특징을 올라오는 길의 같은 해상도 자리로 건네 이어 붙이는 건너뛰기 연결을 두면, 낮은 해상도는 굵은 틀을, 건너온 특징은 가는 결을 맡는다. 이것이 U-Net 이다. 그림을 대역마다 나눠 적던 라플라시안 피라미드처럼, U-Net 은 해상도의 대역마다 나눠 읽고 아래에서부터 보태며 되살린다. 짙은 잡음에서 살아남는 굵은 대역은 낮은 해상도가, 가는 결은 건너뛰기 연결이 맡는다. 잡음 수준 t는 빠르기가 다른 사인·코사인 값으로 편 사인 인코딩을 MLP 에 통과시킨 시간 임베딩으로 만들어, 블록마다 채널 수로 바꿔 모든 칸에 더한다. 블록은 입력을 그대로 넘기고 고친 만큼만 더하는 잔차 블록으로 짜서, 50층이 넘게 쌓아도 학습이 막히지 않게 한다. Stable Diffusion 1.x 의 잡음 예측 신경망은 이 부품들로 짠 8억 6,000만 개짜리 U-Net 이고, 맨 아래를 뺀 세 단계와 가운데에 멀리 떨어진 칸끼리 읽는 어텐션 블록이 끼어 있다.

flowchart LR
  A["합성곱을 그대로 쌓기<br/>기대는 폭 ∝ √L"] --> B["해상도 낮추기<br/>한 칸 = 원래 2^j칸, 걸음이 두 배씩"]
  B --> C["줄였다 키우기만 하면<br/>가는 결이 사라진다"]
  C --> D["건너뛰기 연결<br/>같은 해상도의 특징을 이어 붙인다 = U-Net"]
  T["잡음 수준 t"] --> E["사인 인코딩 → MLP<br/>시간 임베딩"]
  E --> F["블록마다 채널에 더한다"]
  D --> G["잔차 블록으로 깊이 쌓기<br/>SD 1.x: 8억 6,000만 개"]
  F --> G
  G --> H["단계마다 끼운 어텐션 블록<br/>멀리 떨어진 칸끼리 직접 읽기"]

막힌 곳

이제 잡음 예측 신경망 εθ(xt, t)를 실제로 지을 수 있다. 해상도를 낮추며 굵은 대역으로 그림 전체를 보고, 건너뛰기 연결로 가는 대역을 되살리고, 시간 벡터로 잡음 수준마다 다르게 일한다.

그런데 아직 그림을 한 장도 뽑지 않았다. 이 신경망은 잡음 섞인 그림 하나를 받아 섞인 잡음을 어림할 뿐이다. 수리공은 고친 그림 쪽으로 조금씩 옮기기를 되풀이해 새 그림을 만들었지만, 그 걸음이 왜 데이터 분포의 그림에 닿는지, 걸음마다 얼마나 옮겨야 하는지는 따지지 않았다. 망가뜨리는 쪽은 식 한 줄이었고, 그림들의 분포는 열 방정식을 따라 가는 무늬부터 지워지며 퍼졌다. 되돌리는 쪽도 그 열 방정식을 거꾸로 돌리기만 하면 될까? 거꾸로 돌리면 가장 먼저 지워진 가는 무늬를 다시 키워야 할 텐데, 그 일이 순순히 될까?