GAN — 생성자와 판별자 (GANs — Generator vs Discriminator)

Goodfellow가 2014년에 보여준 묘수는 밀도(density)를 아예 건너뛰는 것이었습니다. 두 개의 신경망(network)을 둡니다. 한쪽은 가짜(fake)를 만들고, 다른 한쪽은 그것을 잡아냅니다. 가짜가 진짜(real)와 구분되지 않을 때까지 둘은 끊임없이 싸웁니다. 잘 작동할 것 같지 않은 방식이고, 실제로도 자주 실패합니다. 그러나 잘 작동할 때의 결과물은 좁은 도메인(narrow domain)에서 지금까지 문헌에 보고된 어떤 표본보다도 선명합니다.

유형: Build 언어: Python 선수 지식: Phase 3 · 02 (Backprop), Phase 3 · 08 (Optimizers), Phase 8 · 02 (Autoencoder와 VAE) 예상 시간: 약 75분

문제

변분 오토인코더(VAE)는 흐릿한(blurry) 표본을 만들기 쉽습니다. MSE 디코더(decoder) 손실이 여러 그럴듯한 숫자(plausible digit)의 평균(mean) 이미지에 대해 베이즈 최적(Bayes-optimal)이기 때문이며, 여러 그럴듯한 숫자들의 평균은 결국 흐릿한 숫자일 수밖에 없습니다. 우리가 원하는 것은 특정 정답 이미지와의 픽셀 단위 근접도(pixel-wise proximity)가 아니라 그럴듯함(plausibility) 자체에 보상을 주는 손실 함수입니다. 그런데 그럴듯함에는 닫힌 형태(closed form)의 수식이 존재하지 않으므로, 직접 학습으로 얻어내야 합니다.

Goodfellow의 아이디어는 다음과 같습니다. 진짜 이미지와 가짜 이미지를 구분하는 분류기(classifier) D(x)를 학습하고, 생성자(generator) G(z)는 그 D를 속이도록 학습합니다. G가 받는 손실 신호(loss signal)는 "현재 D가 무엇을 진짜처럼 본다고 판단하는가"라는 기준 그 자체입니다. 이 신호는 G가 개선될수록 함께 바뀌므로 G는 움직이는 표적을 쫓는 셈입니다. 두 신경망이 모두 수렴하면 Glog p(x)를 한 번도 직접 적지 않고도 데이터 분포(data distribution)를 학습한 것이 됩니다.

이것이 적대적 학습(Adversarial Training)입니다. 수식으로는 미니맥스 게임(Minimax Game)으로 표현됩니다.

min_G max_D  E_real[log D(x)] + E_fake[log(1 - D(G(z)))]

2026년 기준으로 GAN은 더 이상 최첨단(SOTA) 범용 생성기는 아닙니다. 그 자리는 확산 모델(Diffusion)과 흐름 매칭(Flow Matching)이 가져갔습니다. 그러나 StyleGAN 2/3은 배포된 얼굴 생성 모델 가운데 여전히 가장 선명한 축에 속하고, GAN의 판별자(discriminator)는 확산 학습에서 지각 손실(Perceptual Loss)로 사용되며, SDXL-Turbo, SD3-Turbo, LCM 같은 빠른 1-스텝 증류(distillation)에도 적대적 학습이 핵심으로 쓰입니다.

사전 테스트

2문제 · 이 강의를 시작하기 전에 얼마나 알고 있는지 확인해보세요

1.원래 GAN 공식에서 생성자(generator)가 미니맥스 손실 log(1 - D(G(z))) 대신 비포화 손실(non-saturating loss) -log D(G(z))를 사용하는 이유는 무엇인가요?

2.완벽하게 학습된 GAN의 균형점(equilibrium) 조건은 무엇인가요?

0/2 답변 완료

개념

adversarial training: two networks, one loss z ~ N(0, I) G(z) generator x̂ (fake) x (real) D(x) discriminator real? 0-1 BCE loss real -> 1, fake -> 0 minimax: min_G max_D E_real[log D(x)] + E_fake[log(1 - D(G(z)))] use non-saturating G loss -log D(G(z)) to avoid vanishing gradients failure: D wins D(fake) → 0, gradient to G vanishes fix: cut D lr, add input noise, WGAN failure: G collapses G outputs one mode, D can't penalize fix: minibatch disc, spectral norm, PacGAN

생성자(Generator) G(z). 노이즈 벡터(noise vector) z ~ N(0, I)를 표본 로 변환합니다. 완전 연결층(dense layer)이나 전치 합성곱(transposed convolution)으로 구성한 디코더 형태의 신경망입니다.

판별자(Discriminator) D(x). 표본을 스칼라 확률 또는 점수로 사상합니다. 진짜는 1에 가깝게, 가짜는 0에 가깝게 출력합니다.

손실(Loss). 두 가지 갱신을 번갈아 수행합니다.

  • D 학습: loss_D = -[ log D(x) + log(1 - D(G(z))) ]. 진짜=1, 가짜=0으로 두는 이진 교차 엔트로피(Binary Cross-Entropy; BCE)입니다.
  • G 학습: loss_G = -log D(G(z)). Goodfellow가 채택한 비포화 형태(non-saturating form)입니다. 원래의 log(1 - D(G(z)))D가 확신할 때 포화되어 기울기(gradient)를 사실상 0으로 만듭니다.

학습 루프(Training loop). D 한 스텝, G 한 스텝씩 번갈아 학습하고, 이를 반복합니다.

왜 작동하는가. G가 실제 데이터 분포 p_data와 완전히 같아지면 D는 무작위 추측보다 잘할 수 없게 되어 모든 곳에서 0.5를 출력합니다. 이 시점에서 G는 더 이상 기울기를 받지 않습니다. 이것이 균형점(equilibrium)입니다.

왜 깨지는가. 모드 붕괴(mode collapse), 기울기 소실(vanishing gradient), 학습 불안정(training instability) 때문입니다. GD가 잘 잡아내지 못하는 모드(mode) 하나만 발견하고 그것만 계속 찍어내거나, D가 너무 빨리 학습되어 log D가 포화되거나, 학습률(learning rate)과 배치 크기(batch size) 같은 세부 설정이 학습을 흔들기 시작합니다.

GAN을 작동시키게 만든 변형들

연도혁신해결한 문제
2015DCGAN합성곱/전치 합성곱(Conv/deconv), 배치 정규화(Batch Norm), LeakyReLU를 사용한 최초의 안정적 구조.
2017WGAN, WGAN-GPBCE를 바서슈타인 거리(Wasserstein distance)와 기울기 패널티(Gradient Penalty)로 대체하여 기울기 소실을 완화.
2017스펙트럼 정규화(Spectral Normalization)판별자의 립시츠(Lipschitz) 상한을 강제. 2026년 판별자에도 여전히 표준.
2018Progressive GAN저해상도부터 학습하고 층을 점진적으로 추가. 첫 메가픽셀 결과.
2019StyleGAN / StyleGAN2매핑 신경망(Mapping Network)과 적응적 인스턴스 정규화(Adaptive Instance Norm; AdaIN). 고정 도메인 사실주의(photorealism)의 대표.
2021StyleGAN3에일리어스 없음(alias-free), 변환 등변성(translation-equivariant). 2026년에도 얼굴 생성의 표준.
2022StyleGAN-XL조건부(conditional), 클래스 인식, 더 큰 규모.
2024R3GAN더 강한 정규화로 1024² 해상도에서 트릭 없이 동작.

직접 만들기

code/main.py는 두 가우시안(Gaussian)이 섞인 1차원 데이터에서 작은 규모의 GAN을 학습합니다. 생성자와 판별자는 각각 은닉층이 한 개인 다층 퍼셉트론(MLP)입니다. 순전파(forward), 역전파(backward), 미니맥스 학습 루프를 직접 손으로 구현합니다. 목표는 모드 붕괴와 기울기 소실이라는 두 가지 대표적 실패 모드(failure mode)를 실제로 눈으로 확인하는 것입니다.

Step 1: 비포화 손실

원래의 Goodfellow 손실인 log(1 - D(G(z)))DG의 가짜를 가짜라고 높은 확신으로 분류하는 순간 0에 가까워집니다. 그 지점에서 G의 기울기는 사실상 0이고, G는 더 이상 개선되지 못합니다. 비포화 형태(non-saturating form)인 -log D(G(z))는 정반대 점근선을 가집니다. D가 확신할수록 값이 커지므로 G에게 강한 신호를 전달합니다.

def g_loss(d_fake):
    # log D(G(z))를 최대화하는 것은 -log D(G(z))를 최소화하는 것과 같다.
    return -sum(math.log(max(p, 1e-8)) for p in d_fake) / len(d_fake)

Step 2: 생성자 한 스텝마다 판별자 한 스텝

for step in range(steps):
    # D를 학습한다.
    real_batch = sample_real(batch_size)
    fake_batch = [G(z) for z in sample_noise(batch_size)]
    update_D(real_batch, fake_batch)

    # G를 학습한다.
    fake_batch = [G(z) for z in sample_noise(batch_size)]  # 새로 만든 가짜
    update_G(fake_batch)

G를 학습할 때는 새로 뽑은 가짜를 사용해야 합니다. 그렇지 않으면 기울기가 낡은(stale) 값이 됩니다.

Step 3: 모드 붕괴 관찰

if step % 200 == 0:
    samples = [G(z) for z in sample_noise(500)]
    mode_a = sum(1 for s in samples if s < 0)
    mode_b = 500 - mode_a
    if min(mode_a, mode_b) < 50:
        print("  [!] 모드 붕괴: 한쪽 모드가 거의 생성되지 않음")

대표적인 증상은 실제 데이터의 두 모드 중 한쪽이 더 이상 생성되지 않는 현상입니다. 판별자가 그 모드를 가짜로 본 적이 없기 때문에 더 이상 교정 신호를 보내지 못합니다.

함정과 주의점 (Pitfalls)

  • 판별자가 너무 강함. D의 학습률을 2~5배 낮추거나 입력에 인스턴스/층 단위 잡음(instance/layer noise)을 추가합니다. D의 정확도가 95%를 넘으면 G는 사실상 죽은 상태입니다.
  • 생성자가 한 모드만 외움. D의 입력에 잡음을 추가하거나, 미니배치 판별자(minibatch-discriminator) 층을 도입하거나, WGAN-GP로 전환합니다.
  • 배치 정규화의 통계 누출(statistics leakage). 진짜 배치와 가짜 배치가 같은 배치 정규화(BN) 층을 통과하면 통계가 섞입니다. 인스턴스 정규화(Instance Norm)나 스펙트럼 정규화(Spectral Norm)로 바꿉니다.
  • 인셉션 점수 조작(Inception-score gaming). FID와 IS는 표본 수가 적을 때 잡음이 큽니다. 평가 시에는 1만 개 이상의 표본을 사용합니다.
  • 조건부 작업에서 단일 표본 추출(one-shot sampling)만으로는 부족. 실제로 쓸 만한 결과를 얻으려면 CFG 스케일, 절단(truncation) 기법, 재표본 추출(re-sampling) 같은 추가 보정이 여전히 필요합니다.

사용해보기

2026년의 GAN 활용 스택입니다.

상황추천
사실적 인간 얼굴, 고정 포즈StyleGAN3 (가장 선명하고 작음)
애니메이션 / 양식화된 얼굴StyleGAN-XL 또는 Stable Diffusion LoRA
이미지-이미지 변환(Image-to-image translation)Pix2Pix / CycleGAN (Phase 8 · 04) 또는 ControlNet (Phase 8 · 08)
빠른 1-스텝 텍스트-이미지 변환확산 모델의 적대적 증류(SDXL-Turbo, SD3-Turbo)
확산 학습기 내부의 지각 손실이미지 패치를 입력으로 받는 작은 GAN 판별자
멀티모달, 개방형 생성GAN을 쓰지 않습니다. 확산이나 흐름 매칭을 사용합니다.

GAN은 선명하지만 좁습니다. 도메인이 일반 사진, 자유 텍스트 프롬프트, 동영상처럼 넓어지는 순간 확산으로 전환하는 것이 합리적입니다. 적대적 학습이라는 트릭은 단독 생성기로서가 아니라 지각 손실과 증류 같은 구성 요소로 살아남았습니다.

산출물 만들기

outputs/skill-gan-debugger.md를 저장합니다. 이 skill은 실패한 GAN 학습(손실 곡선, 표본 격자, 데이터셋 크기)을 입력으로 받아 가능성 높은 원인을 순위로 정리하고, 한 줄 수정안과 재실행 절차(rerun protocol)를 출력합니다.

연습문제

  1. 쉬움. 기본 설정 그대로 code/main.py를 실행합니다. 그런 다음 D_LR = 5 * G_LR로 바꾸어 다시 실행합니다. G의 손실이 상수 값으로 무너지는 데까지 걸리는 속도를 관찰합니다.
  2. 중간. Goodfellow의 BCE 손실을 WGAN 손실로 교체합니다. 즉 loss_D = E[D(fake)] - E[D(real)], loss_G = -E[D(fake)]로 바꾸고, D의 가중치를 [-0.01, 0.01] 구간으로 클리핑(clip)합니다. 학습이 더 안정적인지 확인하고 실제 시간(wall-clock) 기준 수렴 속도를 비교합니다.
  3. 어려움. 1차원 예제를 2차원 데이터로 확장합니다. 원 둘레에 배치된 8개의 가우시안 혼합으로 구성하고, 1k·5k·10k 스텝에서 생성자가 8개 모드 가운데 몇 개를 잡아내는지 추적합니다. 미니배치 판별(minibatch discrimination)을 구현하고 다시 측정해 비교합니다.

핵심 용어

용어흔한 설명실제 의미
생성자(Generator)"G"노이즈에서 표본으로 사상하는 신경망, G: z → x̂이다.
판별자(Discriminator)"D"진짜와 가짜를 구분하는 분류기, D: x → [0, 1]이다.
미니맥스(Minimax)"그 게임"공동 목적 함수에 대한 min_G max_D이다.
비포화 손실(Non-saturating loss)"그 수정"G에 대해 log(1 - D(G(z))) 대신 -log D(G(z))를 사용한다.
모드 붕괴(Mode collapse)"G가 하나만 외움"데이터가 다양해도 생성자가 소수의 결과만 반복해서 만든다.
WGAN"바서슈타인"BCE를 어스 무버 거리(Earth-Mover distance)와 기울기 패널티로 교체하여 매끄러운 기울기를 얻는다.
스펙트럼 정규화(Spectral Norm)"립시츠 트릭"판별자의 가중치 노름을 제약해 기울기를 제한하고 학습을 안정화한다.
StyleGAN"잘 되는 그 모델"매핑 신경망과 AdaIN을 사용하는 얼굴 도메인의 대표 모델이다.

프로덕션 노트: 단일 추론(one-shot inference)이 GAN의 오래 남은 강점이다

GAN은 개방 도메인 생성에서 표본 품질로는 더 이상 이기지 못하지만, 추론 비용(inference cost) 측면에서는 여전히 강력합니다. 프로덕션 추론(production inference) 문헌의 용어로 표현하면 GAN의 특징은 다음과 같습니다.

  • 사전 채움(prefill)과 디코드(decode) 단계가 없음. 단 한 번의 G(z) 순전파만 수행합니다. 첫 토큰 지연(TTFT)은 사실상 전체 지연(total latency)과 같습니다.
  • KV 캐시(KV-cache) 부담이 없음. 유일한 상태는 가중치뿐입니다. 배치 크기는 캐시가 아니라 활성값 메모리(activation memory)로만 제한됩니다.
  • 연속 배치(continuous batching)가 매우 단순. 모든 요청이 동일한 고정 FLOPs를 소비하므로, 서버의 목표 점유율(target occupancy)에 맞춘 정적 배치(static batch)면 보통 충분합니다. 비행 중 스케줄러(in-flight scheduler)가 필요 없습니다.

이것이 GAN 증류(SDXL-Turbo, SD3-Turbo, ADD, LCM)가 2026년 빠른 텍스트-이미지 변환의 지배적 기법인 이유입니다. 2050 스텝짜리 확산 파이프라인을 14회의 GAN 양식 순전파로 압축하면서도 확산 베이스의 분포는 유지합니다. 적대적 손실은 느린 생성기를 빠른 생성기로 바꾸는 학습 단계의 손잡이(training-time knob)로 살아남았습니다.

더 읽을거리

실습 코드

이 강의의 실습 코드 1개

main
Code

산출물

이 강의에서 생성된 프롬프트, 스킬, 코드 산출물 1개

gan-debugger

Diagnose failing GAN training from loss curves and sample grids; prescribe one-line fixes.

Skill

확인 문제

3문제 · 모두 맞추면 완료 표시가 가능합니다

1.GAN의 판별자 정확도가 98%에 도달해 그 상태를 유지하고, 생성자 손실은 계속 올라갑니다. 가장 가능성 높은 문제와 첫 번째 해결책은 무엇인가요?

2.두 봉우리 가우시안 혼합(two-mode Gaussian mixture) 데이터로 학습한 GAN이 한쪽 모드에서만 표본을 생성합니다. 이 실패의 이름은 무엇이며, 이를 직접 해결하는 구조적 변경은 무엇인가요?

3.2026년에 GAN은 더 이상 최첨단 범용 생성기가 아니지만, 적대적 학습(adversarial training)은 프로덕션에서 여전히 핵심입니다. 어떤 현대 파이프라인에서 적대적 손실이 핵심 역할을 하나요?

0/3 답변 완료

추가 문제 풀기

AI가 강의 내용을 바탕으로 새로운 문제를 생성합니다