2014~2017년 GAN(Generative Adversarial Network) 연구에서 처음으로 크게 열린 가능성은 "무엇을 만들지"를 제어(control)할 수 있게 된 점이었습니다. 라벨(label)을 붙이거나, 이미지(image)를 붙이거나, 문장(sentence)을 붙이는 방식으로 조건을 줍니다. Pix2Pix는 그중에서도 이미지 버전(image version)에 해당하며, 좁은 범위의 이미지-투-이미지(image-to-image) 작업에서는 지금까지도 범용 텍스트-투-이미지(text-to-image) 모델을 능가합니다.
유형: Build
언어: Python
선수 지식: Phase 8 · 03 (GAN — 생성자와 판별자), Phase 4 · 06 (U-Net), Phase 3 · 07 (CNNs)
예상 시간: 약 75분
문제
무조건 GAN(Unconditional GAN)은 임의의 얼굴(face)을 표본으로 추출합니다. 데모(demo) 용도로는 그럴듯하지만, 실제 운영(production) 환경에서는 쓰임새가 매우 제한됩니다. 우리가 진짜로 원하는 것은 스케치(sketch)를 사진(photo)으로 바꾸거나, 지도를 항공 사진(aerial photo)으로 바꾸거나, 낮 풍경(daytime scene)을 밤 풍경(nighttime)으로 바꾸거나, 회색조 이미지(grayscale image)에 색을 입히는(colorize) 일입니다. 이러한 모든 작업에서는 입력 이미지(input image) x가 주어지고, 그것과 의미적 대응(semantic correspondence)을 갖는 출력 y를 만들어야 합니다. 하나의 x에 대해 그럴듯한(plausible) y는 여러 개일 수 있습니다. 평균제곱오차(mean-squared error)는 이러한 후보들을 평균 내버려 흐릿한 결과로 뭉개버립니다. 반면 적대적 손실(adversarial loss)은 "진짜처럼 보이는가"라는 기준을 날카롭게 보상하기 때문에 결과가 뭉개지지 않습니다.
조건부 GAN(Conditional GAN, Mirza & Osindero, 2014)은 조건(condition) c를 생성자 G와 판별자 D의 입력에 모두 추가하는 구조입니다. Pix2Pix(Isola et al., 2017)는 이 아이디어를 한층 특화한 방식입니다. 조건은 입력 이미지 전체이고, 생성자(generator)는 U-Net이며, 판별자(discriminator)는 패치 기반 분류기(patch-based classifier)인 PatchGAN이고, 손실(loss)은 적대적 손실에 L1 손실을 더한 형태입니다. 이 레시피(recipe)는 2026년 시점에도 좁은 범위의 이미지-투-이미지 도메인(domain)에서는 처음부터 학습한 텍스트-투-이미지 모델보다 더 강력합니다. 짝지어진 데이터(paired data)를 사용하기 때문에 필요한 신호(signal)를 정확하게 갖고 있는 셈입니다.
사전 테스트
2문제 · 이 강의를 시작하기 전에 얼마나 알고 있는지 확인해보세요
1.Pix2Pix의 판별자(discriminator)가 생성 이미지 y만이 아니라 쌍(pair) (x, y)을 입력으로 받는 이유는 무엇인가요?
2.입력과 출력이 저수준 구조를 공유하는 Pix2Pix 작업에서, U-Net 생성자가 일반 인코더-디코더보다 어떤 구조적 이점을 제공하나요?
0/2 답변 완료
개념
조건부 생성자(Conditional G).G(x, z) → y 형태입니다. Pix2Pix에서 z는 생성자 내부의 드롭아웃(dropout)으로 들어갑니다. Isola는 명시적으로 입력 노이즈(input noise)를 주어도 모델이 이를 무시한다는 사실을 발견했기 때문에, 입력 노이즈를 따로 넣지 않는 구조를 선택했습니다.
조건부 판별자(Conditional D).D(x, y) → [0, 1] 형태입니다. 입력은 조건과 출력의 쌍(pair) 입니다. 이 부분이 핵심적인 차이입니다. 판별자는 y가 단순히 진짜처럼 보이는지만 보는 것이 아니라, y가 x와 일관적인지(consistent) 함께 판단해야 합니다.
U-Net 생성자(U-Net generator). 병목(bottleneck) 구간을 가로지르는 스킵 연결(skip connection)이 있는 인코더-디코더(encoder-decoder) 구조입니다. 입력과 출력이 윤곽선(edge)이나 실루엣(silhouette) 같은 저수준 구조(low-level structure)를 공유하는 작업에서 매우 중요합니다. 스킵 연결이 없으면 고주파 디테일(high-frequency detail)이 사라집니다.
PatchGAN 판별자(PatchGAN discriminator). 진짜/가짜 점수(real/fake score) 하나를 내놓는 대신, 판별자는 N×N 격자(grid)를 출력합니다. 각 셀(cell)은 약 70×70 픽셀(pixel) 크기의 수용 영역(receptive field)을 판단하고, 결과를 평균 냅니다. 이는 사실성(realism)이 국소적(local)이라는 마르코프 랜덤장 가정(Markov random field assumption)에 해당합니다. 파라미터(parameter) 수가 적고, 학습이 더 빠르며, 출력이 한층 선명해집니다.
L1 항(term)은 학습을 안정화하고 생성자가 알려진 목표(known target)를 향해 가도록 밀어줍니다. L1은 L2보다 윤곽선을 더 선명하게 유지합니다. 평균(mean) 대신 중앙값(median)에 가깝게 수렴하기 때문입니다. Pix2Pix의 기본값은 λ = 100입니다.
CycleGAN — 짝지어진 데이터가 없을 때
Pix2Pix는 짝지어진 (x, y) 데이터가 필요합니다. CycleGAN(Zhu et al., 2017)은 이러한 요구를 없애는 대신, 추가 손실인 사이클 일관성 손실(cycle consistency loss) 을 도입합니다. 생성자를 두 개 둡니다: G: X → Y와 F: Y → X. F(G(x)) ≈ x이고 G(F(y)) ≈ y가 되도록 학습합니다. 이렇게 하면 짝지어진 예시 없이도 말(horse)을 얼룩말(zebra)로, 여름 풍경(summer)을 겨울 풍경(winter)으로 변환할 수 있습니다.
2026년 시점에는 짝지어지지 않은(unpaired) 이미지-투-이미지 작업이 대부분 CycleGAN이 아니라 디퓨전 모델(diffusion; ControlNet, IP-Adapter)로 처리됩니다. 하지만 사이클 일관성이라는 아이디어 자체는 거의 모든 짝지어지지 않은 도메인 적응(domain adaptation) 논문에 살아남아 있습니다.
직접 만들기
code/main.py는 1차원(1-D) 데이터 위에서 동작하는 아주 작은 조건부 GAN을 구현합니다. 조건 c는 0 또는 1의 클래스 라벨(class label)입니다. 작업은 주어진 클래스에 해당하는 조건부 분포(conditional distribution)에서 표본을 생성하는 것입니다.
원-핫 인코딩(one-hot encoding)이 가장 단순한 방식입니다. 더 큰 모델에서는 학습된 임베딩(learned embedding), FiLM 변조(FiLM modulation), 교차 어텐션(cross-attention)을 사용합니다.
Step 2: 조건부 학습 수행
for step inrange(steps):
x, c = sample_real_conditional()
noise = sample_noise()
update_D(x_real=x, x_fake=G(noise, c), c=c)
update_G(noise, c)
생성자는 주변 분포(marginal distribution)가 아니라 주어진 조건에 대한 실제 분포(real distribution)를 맞춰야 합니다.
Step 3: 클래스별 출력 확인
for c in [0, 1]:
samples = [G(noise, c) for noise in batch]
mean_c = mean(samples)
assert_near(mean_c, real_mean_for_class_c)
자주 빠지는 함정(Pitfalls)
조건이 무시되는 경우. 생성자가 주변 분포(marginalize)를 학습해버리고, 판별자는 조건 신호가 약해서 그것을 충분히 페널티(penalize)로 잡아내지 못합니다. 해결책은 판별자에 조건을 더 공격적으로 주입하는 것입니다. 후반 레이어가 아니라 초기 레이어(early layer)부터 조건을 넣거나, 사영 판별자(projection discriminator; Miyato & Koyama 2018)를 사용합니다.
L1 가중치가 너무 낮은 경우. 생성자가 실제 목표에 충실한(faithful) 출력 대신, 단지 진짜처럼 보이는 임의의 출력으로 떠내려가게(drift) 됩니다. Pix2Pix 류의 작업에서는 λ≈100에서 시작합니다.
L1 가중치가 너무 높은 경우. L1도 결국 L_p 노름(norm)이기 때문에 출력이 흐릿(blurry)해집니다. 학습이 안정화되면 가중치를 점차 낮춥니다(anneal down).
판별자의 정답 누출(ground-truth leakage). 판별자의 입력은 y 단독이 아니라 (x, y)를 결합(concatenate)한 형태여야 합니다. 그렇지 않으면 판별자가 일관성(consistency)을 확인할 수 없습니다.
클래스별 모드 붕괴(mode collapse). 각 클래스가 독립적으로 붕괴할 수 있습니다. 클래스 조건부 다양성 검사(class-conditional diversity check)를 함께 수행합니다.
사용해보기
2026년 시점의 이미지-투-이미지 작업 현황은 다음과 같습니다.
작업
최적 접근법
스케치 → 사진, 동일 도메인, 짝지어진 데이터
Pix2Pix / Pix2PixHD (여전히 빠르고 선명합니다)
스케치 → 사진, 짝지어지지 않은 데이터
Scribble 조건화 모델을 사용하는 ControlNet
의미 분할(semantic seg) → 사진
SPADE / GauGAN2 또는 SD + ControlNet-Seg
스타일 전이(style transfer)
IP-Adapter나 LoRA를 결합한 디퓨전. GAN 방식은 레거시(legacy)
깊이(depth) → 사진
Stable Diffusion 위에서 동작하는 ControlNet-Depth
초해상도(super-resolution)
Real-ESRGAN(GAN), ESRGAN-Plus, 또는 SD-Upscale(디퓨전)
색상화(colorization)
ColTran, 디퓨전 기반 색상화 모델, 또는 Pix2Pix-color
낮 → 밤, 계절, 날씨 변환
CycleGAN 또는 ControlNet 기반 방식
Pix2Pix는 다음 세 조건이 맞을 때 여전히 좋은 선택입니다. (a) 짝지어진 예시가 수천 개 있고, (b) 작업이 좁고 반복적이며(narrow and repeatable), (c) 빠른 추론(inference)이 필요한 경우입니다. 범용적인 오픈 도메인 작업에서는 디퓨전이 우세합니다.
산출물 만들기
outputs/skill-img2img-chooser.md를 저장합니다. 이 스킬(skill)은 작업 설명(task description), 데이터 가용성(짝지어진 데이터인지 아닌지, 표본 수 N), 지연시간(latency)과 품질(quality) 예산을 입력으로 받아 다음을 출력합니다: 접근법(Pix2Pix, CycleGAN, ControlNet 변형, SDXL + IP-Adapter), 학습 데이터 요건(training data requirements), 추론 비용(inference cost), 그리고 평가 프로토콜(LPIPS, FID, 작업 특화 지표 등).
연습문제
쉬움.code/main.py에 세 번째 클래스를 추가합니다. 생성자가 각 클래스의 노이즈를 올바른 모드(mode)로 매핑하는지 확인합니다.
중간. 1차원 설정에서 L1을 지각 손실(perceptual-style loss)로 교체합니다. 예를 들어 동결된(frozen) 작은 판별자를 특징 추출기(feature extractor)처럼 사용합니다. 조건부 분포의 선명도(sharpness)가 달라지는지 확인합니다.
어려움. 1차원 설정에서 CycleGAN을 스케치 수준으로 구현합니다. 두 분포, 두 생성자, 그리고 사이클 손실을 둡니다. 짝지어진 데이터 없이도 두 분포 사이의 매핑을 학습한다는 점을 보여줍니다.
핵심 용어
용어
흔한 설명
실제 의미
조건부 GAN(Conditional GAN)
"라벨이 붙은 GAN"
G(z, c), D(x, c) 구조이다. 두 신경망이 모두 조건을 본다.
Pix2Pix
"이미지-투-이미지 GAN"
U-Net 생성자와 PatchGAN 판별자, L1 손실을 사용하는 짝지어진 조건부 GAN이다.
의미 맵(semantic map)으로 중간 활성값(intermediate activation)을 정규화하는, 분할-투-이미지(segmentation-to-image) 방식이다.
FiLM
"특징별 선형 변조(feature-wise linear modulation)"
조건에서 유도된 특징별 어파인 변환(affine transform)이다. 비용이 저렴한 조건화 방식이다.
운영 노트(Production note): Pix2Pix는 지연시간 제약 환경의 기준선이다
짝지어진 데이터가 있고, 작업이 스케치 → 렌더링(render), 의미 맵 → 사진, 낮 → 밤처럼 좁은 범위라면 Pix2Pix의 한 번에 끝나는(one-shot) 추론은 디퓨전보다 지연시간 기준으로 한 자릿수 이상 빠릅니다. 운영 환경에서의 비교는 보통 다음과 같습니다.
경로
스텝 수(Steps)
단일 L4에서 512² 기준 일반적인 지연시간
Pix2Pix (U-Net 순전파)
1
약 30 ms
SD-Inpaint 또는 SD-Img2Img
20
약 1.2 s
SDXL-Turbo Img2Img
1-4
약 0.15-0.35 s
ControlNet + SDXL base
20-30
약 3-5 s
Pix2Pix는 정적 배치(static batch) 환경의 처리량(throughput)에서 우세합니다. 모든 요청이 동일한 FLOPs를 사용하기 때문입니다. 디퓨전은 품질과 일반화 측면에서 우세합니다. 현대적인 운영 전략은 좁은 작업에는 Pix2Pix 형태의 증류된(distilled) 모델을 배포하고, 꼬리 입력(tail input)에는 디퓨전을 대체 경로(fallback)로 두는 것입니다.