← AI 놀이터 홈으로

⚔️ GAN — 위조범과 감별사의 대결 (Generative Adversarial Network)

위조범(생성자)은 진짜 같은 가짜를 만들고, 감별사(판별자)는 가려내요. 반대 목표를 가진 둘의 대결만으로 AI가 '진짜 데이터 만드는 법'을 배웁니다.

📖 따라하기 가이드 — 1 / 7 단계

Step 1. 위조범과 감별사

위조범(생성자)은 가짜 지폐를 찍어내고, 감별사(판별자)는 진짜와 가짜를 가려내요. 화면에서 파랑은 진짜 돈의 분포, 주황은 위조 지폐의 분포, 초록 선은 감별사의 판단(위로 갈수록 "진짜다!")이에요. 지금은 위조 실력이 형편없어서 주황 무더기가 파랑에서 멀리 떨어져 있죠.

가로축은 데이터 값 x(0~10). 파란 막대는 진짜 데이터의 분포, 주황 막대는 위조범이 만든 가짜의 분포예요. 초록 선은 감별사의 판단(오른쪽 0~1 축, 1=진짜다!, 0=가짜다!)입니다. 주황이 파랑 위에 겹치고 초록 선이 그 근처에서 0.5로 평평해지면 — 위조범의 완승이에요.

🎛️ 대결 조종하기

📊 지금 상태

위조범 평균 μ_g (진짜 6.5)
—
위조범 퍼짐 σ_g (진짜 0.6)
—
가짜가 받은 평균 점수
—
라운드
—

μ_g와 σ_g는 진짜의 6.5와 0.6에 가까워지고, 가짜가 받는 점수는 0.5(감별사도 반반으로 헷갈림)에 가까워지면 성공이에요.

🧮 수식과 파이썬

minG maxD E[log D(x)] + E[log(1 − D(G(z)))]
감별사는 구분을 잘하려 하고, 위조범은 속이려 해요 — 둘의 줄다리기
🐍 파이썬 코드로 보면? (펼치기)
import torch
import torch.nn as nn

G = nn.Sequential(nn.Linear(64, 128), nn.ReLU(),
                  nn.Linear(128, 784), nn.Tanh())     # 위조범: 노이즈 → 이미지
D = nn.Sequential(nn.Linear(784, 128), nn.LeakyReLU(0.2),
                  nn.Linear(128, 1), nn.Sigmoid())    # 감별사: 이미지 → 진짜일 확률
loss_fn = nn.BCELoss()
opt_D = torch.optim.Adam(D.parameters(), lr=2e-4)
opt_G = torch.optim.Adam(G.parameters(), lr=2e-4)

for step in range(10000):
    real = next(loader)                    # 진짜 이미지 배치
    z = torch.randn(real.size(0), 64)      # 노이즈
    fake = G(z)                            # 위조범이 가짜 생성
    ones, zeros = torch.ones(real.size(0), 1), torch.zeros(real.size(0), 1)

    # 1) 감별사 학습: 진짜엔 1, 가짜엔 0을 주도록
    loss_D = loss_fn(D(real), ones) + loss_fn(D(fake.detach()), zeros)
    opt_D.zero_grad(); loss_D.backward(); opt_D.step()

    # 2) 위조범 학습: 감별사가 가짜를 "진짜(1)"로 믿게 만들도록
    loss_G = loss_fn(D(fake), ones)
    opt_G.zero_grad(); loss_G.backward(); opt_G.step()