검색
← 모듈 로드맵

GAN 실전: 모드 붕괴 · WGAN · 조건부 GAN · StyleGAN

강의 · 준전문가 · KAITABASE 정리

원제 · GAN in Practice (D2L 20.1 · WGAN · StyleGAN 참고)

비포화 손실 · 모드 붕괴 · 바서슈타인 거리 · WGAN-GP · 조건부 GAN · StyleGAN을 숫자로 익히는 수업

먼저 알아야 할 것

GAN 원 논문의 최소최대 게임KL · JS 발산시그모이드와 로짓경사 하강법과 Adam

다루는 내용

GAN을 실제로 학습할 때 생기는 문제와 대표 해법을 정리합니다. 최적 판별자와 포화 · 비포화 손실의 기울기를 손계산하고, 모드 붕괴의 원인과 처방을 설명합니다. 겹치지 않는 분포에서 JS 발산이 멈추는 문제를 바서슈타인 거리로 풀어낸 WGAN · WGAN-GP의 식과 기본 설정, 조건부 GAN과 StyleGAN 구조를 다룹니다.

해설

GAN 실전: 모드 붕괴 · WGAN · 조건부 GAN · StyleGAN

GAN은 원 논문의 아이디어는 단순하지만, 실제로 학습시키면 "판별자가 너무 세져서 생성자가 멈춤", "한두 종류만 계속 만들어 냄(모드 붕괴)" 같은 문제가 바로 나옵니다. 이 수업은 그 문제들이 왜 생기는지 숫자로 보이고, 이를 고친 대표 해법 — 비포화 손실, WGAN과 기울기 벌점, 조건부 GAN, StyleGAN — 을 정리합니다.

항목내용
참고 출처D2L 20.1 Generative Adversarial Networks, Arjovsky 외(2017) WGAN, Gulrajani 외(2017) WGAN-GP, Mirza · Osindero(2014) 조건부 GAN, Karras 외(2018) StyleGAN, Salimans 외(2016)
트랙 · 수준생성 모델 · 중급
이 수업이 다루는 범위최소최대 목표 복습, 최적 판별자 손계산, 포화 · 비포화 손실의 기울기, 모드 붕괴, JS 발산의 한계와 바서슈타인 거리, 가중치 자르기 · 기울기 벌점, 조건부 GAN, StyleGAN 구조, 학습 요령

들어가기 전에

한눈에 보기

  • 최적 판별자 D∗(x)=pdata(x)pdata(x)+pg(x)D^*(x)=\dfrac{p_{\text{data}}(x)}{p_{\text{data}}(x)+p_g(x)} 를 숫자로 계산합니다.
  • 원래 생성자 손실이 왜 초반에 기울기가 거의 0이 되는지, 로짓 기울기 −0.01-0.01 대 −0.99-0.99 로 확인합니다.
  • 모드 붕괴가 무엇이고 왜 생기는지 압니다.
  • 두 분포가 겹치지 않으면 JS 발산은 늘 log⁡2\log 2 로 멈추지만 바서슈타인 거리는 거리를 알려 준다는 점을 손계산합니다.
  • WGAN · WGAN-GP의 핵심 설정(c=0.01c=0.01, λ=10\lambda=10, ncritic=5n_{\text{critic}}=5)과 조건부 GAN · StyleGAN의 구조를 압니다.

1. 복습: 최적 판별자와 게임의 값

직관(해설용 비유). 위조지폐범(생성자 GG)과 경찰(판별자 DD)의 게임입니다. 경찰은 진짜에 1, 가짜에 0을 내도록, 위조범은 경찰을 속이도록 배웁니다.

min⁡Gmax⁡D  Ex∼pdata[log⁡D(x)]+Ez∼p(z)[log⁡(1−D(G(z)))]\min_G\max_D\; \mathbb E_{x\sim p_{\text{data}}}[\log D(x)] + \mathbb E_{z\sim p(z)}[\log(1-D(G(z)))]

생성자를 고정하면 판별자의 최적해는 점마다 다음과 같습니다.

D∗(x)=pdata(x)pdata(x)+pg(x)D^*(x)=\frac{p_{\text{data}}(x)}{p_{\text{data}}(x)+p_g(x)}
기호뜻
pdata(x)p_{\text{data}}(x)진짜 데이터의 밀도
pg(x)p_g(x)생성자가 만든 표본의 밀도
D(x)D(x)"진짜일 확률" 판정(0~1)

숫자로 해 보기(해설용). 어떤 점에서 pdata=0.6p_{\text{data}}=0.6, pg=0.2p_g=0.2 이면 D∗=0.6/0.8=0.75D^*=0.6/0.8=0.75 입니다. 반대로 pdata=0.1p_{\text{data}}=0.1, pg=0.4p_g=0.4 이면 D∗=0.2D^*=0.2 입니다. 두 분포가 같으면 어디서나 D∗=0.5D^*=0.5 이고, 이때 게임의 값은 −log⁡4≈−1.386-\log4\approx-1.386 입니다. 원 논문은 이 값이 −log⁡4+2 JSD(pdata∥pg)-\log4+2\,\mathrm{JSD}(p_{\text{data}}\|p_g) 꼴임을 보였습니다. 즉 최적 판별자 아래에서 생성자는 JS 발산을 줄이고 있는 셈 입니다.

2. 포화 손실과 비포화 손실

문제. 학습 초반에는 생성자가 형편없어서 판별자가 가짜를 쉽게 알아봅니다(D(G(z))≈0D(G(z))\approx0). 이때 원래 손실 log⁡(1−D(G(z)))\log(1-D(G(z))) 는 평평해져 기울기가 거의 없습니다(포화, saturation).

숫자로 해 보기(해설용). 판별자 출력을 로짓 aa 와 시그모이드 D=σ(a)D=\sigma(a) 로 씁니다. D(G(z))=0.01D(G(z))=0.01 인 가짜 하나를 봅니다.

  • 원래 손실 log⁡(1−σ(a))\log(1-\sigma(a)) 의 aa 에 대한 기울기: −σ(a)=−0.01-\sigma(a)=-0.01
  • 비포화 손실 −log⁡σ(a)-\log\sigma(a) 의 기울기: −(1−σ(a))=−0.99-(1-\sigma(a))=-0.99

같은 상황에서 기울기 크기가 99배 차이 납니다. 그래서 원 논문부터 실전에서는 생성자가 log⁡D(G(z))\log D(G(z)) 를 최대화 하도록 바꿉니다. D2L 20.1절도 같은 이유로, 코드에서는 가짜 표본에 "진짜(1)" 라벨을 붙여 생성자를 학습합니다.

왜 이렇게 하나. 두 손실은 최적점(고정점)이 같지만, 비포화 손실은 생성자가 가장 못할 때 가장 강한 신호를 받습니다.

3. 모드 붕괴: 한 가지만 잘 만드는 생성자

직관(해설용 비유). 위조범이 1만 원권 하나만 완벽하게 만들 줄 안다면, 경찰이 1만 원권을 의심하기 시작할 때까지 그것만 찍어 냅니다. 경찰이 의심하면 5천 원권으로 옮겨 가고, 다시 그것만 찍습니다.

모드 붕괴(mode collapse) 는 데이터에 여러 "봉우리(모드)"가 있는데, 생성자가 그중 일부만 만들어 내는 현상입니다. 예를 들어 Unrolled GAN 논문(Metz 외, 2016)은 반지름 2인 원 위에 가우시안 8개를 놓은 2차원 장난감 문제에서, 보통 GAN의 생성자가 매 순간 한 봉우리에만 질량을 몰아 두고 학습이 진행되며 봉우리를 돌아가며 옮겨 다닌다고 보고했습니다.

왜 생기나. 게임은 생성자와 판별자가 한 걸음씩 번갈아 움직입니다. 판별자가 고정된 순간, 생성자에게 가장 좋은 전략은 "판별자가 가장 진짜라고 믿는 한 점"으로 모든 표본을 보내는 것입니다. 이 점이 다양성을 잃게 만듭니다.

대표 처방(Salimans 외, 2016).

  • 미니배치 판별(minibatch discrimination): 판별자가 한 배치 안 표본들이 서로 얼마나 비슷한지도 보게 해, 다 똑같은 배치를 가짜로 잡아내게 합니다.
  • 특징 맞추기(feature matching): 판별자의 최종 판정 대신 중간 층 특징의 평균을 진짜와 맞추게 합니다.
  • 한쪽 라벨 평활화(one-sided label smoothing): 진짜 라벨만 1보다 조금 작은 값으로 낮춰 판별자의 과신을 줄입니다.

4. JS 발산의 한계와 바서슈타인 거리

문제. 고차원 이미지 분포는 공간의 아주 얇은 영역에만 몰려 있어서, 학습 초반의 진짜 · 가짜 분포는 거의 겹치지 않습니다. 겹치지 않는 두 분포의 JS 발산은 얼마나 떨어져 있든 항상 log⁡2\log2 입니다. 값이 변하지 않으니 기울기도 없습니다.

바서슈타인 거리(Wasserstein-1, 흙 옮기기 거리). 한 분포의 "흙 더미"를 다른 분포 모양으로 옮길 때 드는 최소 작업량(흙의 양 × 옮긴 거리)입니다.

숫자로 해 보기(해설용).

  • 진짜: 점 0과 1에 흙 0.5씩. 가짜: 점 2와 3에 0.5씩. 0→2, 1→3 으로 각각 거리 2씩 옮기면 W=0.5×2+0.5×2=2W=0.5\times2+0.5\times2=2 입니다. JS 발산은 ln⁡2≈0.693\ln2\approx0.693 입니다.
  • 가짜를 0.5와 1.5로 옮기면 W=0.5W=0.5 로 줄어듭니다. 그런데 여전히 진짜와 겹치는 점이 없어서 JS는 그대로 0.6930.693 입니다.

WGAN 논문(Arjovsky 외, 2017)의 예도 같습니다. 원점을 지나는 수직선 위의 균등분포와 그것을 θ\theta 만큼 옮긴 분포 사이에서 W=∣θ∣W=|\theta| 지만, JS는 θ≠0\theta\ne0 이면 늘 log⁡2\log2, KL은 무한대입니다. WW 만이 "얼마나 가까워졌는지"를 매끄럽게 알려 줍니다.

WGAN의 목표. 칸토로비치-루빈시테인 쌍대성으로 WW 를 다음처럼 씁니다.

W(pdata,pg)=sup⁡∥f∥L≤1  Ex∼pdata[f(x)]−Ex∼pg[f(x)]W(p_{\text{data}},p_g)=\sup_{\|f\|_L\le1}\;\mathbb E_{x\sim p_{\text{data}}}[f(x)]-\mathbb E_{x\sim p_g}[f(x)]
기호뜻
ff비평자(critic). 확률이 아니라 아무 실수나 내는 점수 함수
∥f∥L≤1\Vert f\Vert_L\le11-립시츠: 입력이 1 움직일 때 출력이 1보다 많이 변하지 않음
sup⁡\sup조건을 만족하는 ff 중 가장 큰 값

판별자는 이제 "진짜 확률"이 아니라 진짜에는 높은 점수, 가짜에는 낮은 점수를 주는 비평자 가 됩니다. 문제는 1-립시츠 조건을 신경망에 어떻게 지키게 하느냐입니다.

  • WGAN(가중치 자르기): 매 갱신 뒤 비평자 가중치를 [−0.01, 0.01][-0.01,\ 0.01] 로 자릅니다. 논문 알고리즘은 생성자 1번당 비평자 5번, RMSProp 학습률 5×10−55\times10^{-5} 을 쓰고, 모멘텀 기반 Adam은 비평자 학습이 불안정했다고 보고합니다.
  • WGAN-GP(기울기 벌점): Gulrajani 외(2017)는 자르기 대신, 진짜와 가짜를 잇는 직선 위에서 무작위로 뽑은 점 x^\hat x 에서 비평자 기울기의 크기가 1이 되도록 벌점을 줍니다.
L=Ex~∼pg[D(x~)]−Ex∼pdata[D(x)]+λ Ex^[(∥∇x^D(x^)∥2−1)2]L = \mathbb E_{\tilde x\sim p_g}[D(\tilde x)] - \mathbb E_{x\sim p_{\text{data}}}[D(x)] + \lambda\,\mathbb E_{\hat x}\big[(\|\nabla_{\hat x}D(\hat x)\|_2-1)^2\big]

기본값은 λ=10\lambda=10, ncritic=5n_{\text{critic}}=5, Adam(학습률 10−410^{-4}, β1=0\beta_1=0, β2=0.9\beta_2=0.9) 입니다. 벌점이 표본마다 따로 계산되므로 비평자에서는 배치 정규화를 빼고, 대신 층 정규화를 권합니다.

숫자로 해 보기(해설용). 비평자가 선형 함수 D(x)=3x1+4x2D(x)=3x_1+4x_2 라면 기울기 (3,4)(3,4) 의 크기는 5입니다. 벌점은 10×(5−1)2=16010\times(5-1)^2=160 으로 매우 커서, 학습은 기울기 크기를 1 쪽으로 강하게 끌어내립니다.

mermaid
flowchart LR
  Z[잡음 z] --> G[생성자 G]
  C[조건 c<br/>선택] --> G
  G --> F[가짜 x̃]
  R[진짜 x] --> MIX[직선 위 무작위 점 x̂]
  F --> MIX
  R --> D[비평자 D]
  F --> D
  C --> D
  MIX --> GP[기울기 벌점<br/>λ · 기울기 크기−1 제곱]
  D --> LD[비평자 손실]
  GP --> LD
  D --> LG[생성자 손실<br/>−D x̃]

5. 조건부 GAN: 원하는 것을 만들게 하기

Mirza · Osindero(2014)는 생성자와 판별자 둘 다에 추가 정보 yy (예: 숫자 클래스 라벨)를 넣었습니다. 생성자는 G(z,y)G(z,y), 판별자는 D(x,y)D(x,y) 가 됩니다. 논문은 MNIST에서 클래스 라벨을 조건으로 원하는 숫자를 생성하는 것을 보였습니다.

왜 판별자에도 넣나. 판별자가 조건을 모르면 "7을 요청했는데 3을 그린 그림"도 진짜처럼 보이면 통과시킵니다. 판별자가 (x,y)(x,y) 짝이 맞는지까지 보아야 생성자가 조건을 지킵니다. 이 구조는 이미지 변환(스케치 → 사진) 같은 후속 연구의 바탕이 되었습니다.

6. StyleGAN: 잠재 벡터를 "스타일"로 나누어 넣기

Karras 외(2018)의 StyleGAN은 생성자 구조를 바꿨습니다.

  1. 매핑 신경망: 512차원 잡음 zz 를 완전 연결 층 8개에 통과시켜 512차원 중간 잠재 ww 로 바꿉니다.
  2. AdaIN으로 스타일 주입: 합성 신경망의 각 층에서 특징 지도를 정규화한 뒤, ww 에서 만든 크기 · 이동 값으로 다시 조절합니다: AdaIN(xi,y)=ys,ixi−μ(xi)σ(xi)+yb,i\mathrm{AdaIN}(x_i,y)=y_{s,i}\dfrac{x_i-\mu(x_i)}{\sigma(x_i)}+y_{b,i}.
  3. 잡음 입력: 층마다 픽셀별 가우시안 잡음을 더해 머리카락 결 같은 무작위 세부를 맡깁니다.
  4. 스타일 섞기: 학습 중 일부 이미지는 잠재 코드 두 개를 써서, 중간 지점부터 다른 코드로 바꿉니다.
  5. 잘라내기 요령(truncation): w′=wˉ+ψ(w−wˉ)w'=\bar w+\psi(w-\bar w), ψ<1\psi<1 로 평균 쪽으로 당겨 품질을 올리고 다양성을 줄입니다. 논문은 이를 그림 예시에만 쓰고 FID 계산에는 쓰지 않았습니다.

논문은 1024×1024 해상도의 얼굴 사진 7만 장으로 이루어진 FFHQ 데이터셋도 함께 공개했습니다. 낮은 해상도 층의 스타일은 얼굴 방향 · 형태 같은 큰 특징을, 높은 해상도 층은 색 · 미세한 질감을 바꾸는 식으로 역할이 나뉩니다.

7. 학습 요령 정리

증상의심할 것처방
생성자 손실이 줄지 않고 판별자 정확도 100%포화 · 판별자 과강비포화 손실, WGAN-GP, 판별자 학습률 조정
표본이 몇 종류뿐모드 붕괴미니배치 판별, WGAN-GP, 데이터 증강
손실이 진동하며 품질 들쭉날쭉불안정한 게임판별자 · 생성자 학습률을 따로 두기(TTUR, Heusel 외 2017)
비평자 손실이 폭주립시츠 조건 깨짐기울기 벌점 계수 · 정규화 방식 확인

손실 값 자체는 GAN 품질을 잘 알려 주지 않습니다. 품질은 FID 같은 지표와 표본 눈검사로 함께 봐야 합니다(→ 생성 모델 평가).

연습 문제

  1. pdata=0.3, pg=0.3p_{\text{data}}=0.3,\ p_g=0.3 인 점에서 D∗D^* 는?
    • 풀이: 0.3/0.6=0.50.3/0.6=0.5 입니다. 두 밀도가 같으면 판별자는 반반입니다.
  2. D(G(z))=0.1D(G(z))=0.1 일 때 포화 · 비포화 손실의 로짓 기울기는?
    • 풀이: −σ(a)=−0.1-\sigma(a)=-0.1, −(1−σ(a))=−0.9-(1-\sigma(a))=-0.9 입니다.
  3. 진짜가 점 0에 질량 1, 가짜가 점 5에 질량 1일 때 바서슈타인 거리와 JS 발산은?
    • 풀이: W=5W=5, JS =ln⁡2≈0.693=\ln2\approx0.693 입니다. 가짜를 점 1로 옮기면 W=1W=1 로 줄지만 JS는 그대로입니다.
  4. 비평자 기울기 크기가 0.5인 점의 벌점(λ=10\lambda=10)은?
    • 풀이: 10×(0.5−1)2=2.510\times(0.5-1)^2=2.5 입니다. 기울기가 1보다 작아도 벌점을 받습니다(양쪽 벌점).

스스로 점검

  1. 비포화 손실로 바꿔도 되는 이유는?
    • 답: 고정점(생성자가 데이터 분포를 따라 하는 지점)이 같으면서, 판별자가 가짜를 쉽게 알아보는 초반에 훨씬 큰 기울기를 주기 때문입니다.
  2. WGAN이 JS 대신 바서슈타인 거리를 쓴 이유는?
    • 답: 겹치지 않는 분포에서 JS는 상수 log⁡2\log2 라 기울기가 없지만, 바서슈타인 거리는 두 분포가 얼마나 떨어져 있는지에 비례해 변해 학습 신호를 주기 때문입니다.
  3. 조건부 GAN에서 판별자에도 조건을 넣는 이유는?
    • 답: 판별자가 조건과 이미지가 맞는지 검사해야 생성자가 조건을 무시하지 못하기 때문입니다.

용어 정리

용어쉬운 뜻
최적 판별자생성자를 고정했을 때 가장 잘 구분하는 판별자, pdata/(pdata+pg)p_{\text{data}}/(p_{\text{data}}+p_g)
포화함수가 평평해져 기울기가 거의 0이 되는 상태
비포화 손실생성자가 log⁡D(G(z))\log D(G(z)) 를 최대화하도록 바꾼 손실
모드 붕괴생성자가 데이터의 일부 유형만 반복해 만드는 현상
JS 발산두 분포와 그 평균 분포 사이 KL 두 개의 평균
바서슈타인 거리한 분포를 다른 분포로 옮기는 최소 작업량
비평자WGAN의 판별자. 확률 대신 실수 점수를 냄
립시츠 조건입력 변화보다 출력 변화가 일정 배수 이상 커지지 않는 성질
기울기 벌점비평자 기울기 크기를 1로 유지하게 하는 벌점 항
AdaIN정규화한 특징을 스타일 값으로 다시 크기 · 이동시키는 연산

더 깊이 보려면

다음에 볼 것

라이선스

본문은 KAITABASE 자체 해설입니다. 참고 자료 D2L은 CC BY-SA 4.0으로 공개되어 있으며, 각 논문은 요약 · 인용만 했습니다. 확률 · 기울기 · 흙 옮기기 숫자는 이 수업을 위해 만든 해설용 예입니다.

출처

AI 원리부터 이해하기 · 생성 모델 모듈

생성 모델 모듈 학습

이 글은 생성 모델 모듈의 학습 자료입니다. 전체 10개 자료 중 4번째입니다.

AI 기초 과정은 현재 진도 저장을 지원하지 않습니다.

출처·원문

원문 보기

요약만

본문 자체 작성 · 참고 자료 D2L(CC BY-SA 4.0) · 각 논문