Phase 08 - Lesson 04
Conditional GANs & Pix2Pix
A GAN Condicional (Mirza & Osindero, 2014) adiciona uma condição c como entrada tanto para G quanto para D. O Pix2Pix (Isola et al., 2017) especializou isso: a condição é uma imagem de entrada completa, o gerador é uma U-Net, o discriminador é um classificador baseado em patches (PatchGAN) e a perda é adversarial + L1. Essa receita supera modelos de texto para imagem do zero em domínios restritos de imagem para imagem mesmo em 2026 porque é treinada em dados pareados — você tem exatamente o sinal que precisa.
O Conceito
G Condicional. G(x, z) → y. No Pix2Pix, z é o dropout dentro de G (sem ruído de entrada — Isola descobriu que o ruído explícito era ignorado).
D Condicional. D(x, y) → [0, 1]. A entrada é o par (condição, saída). Essa é a diferença fundamental: D deve julgar se y é consistente com x, e não apenas se y parece real.
Gerador U-Net. Encoder-decoder com conexões de salto (skip connections) através do gargalo (bottleneck). Crítico para tarefas onde a entrada e a saída compartilham estrutura de baixo nível (bordas, silhueta). Sem os saltos, os detalhes de alta frequência desaparecem.
Discriminador PatchGAN. Em vez de produzir uma única pontuação de real/falso, D produz uma grade N×N onde cada célula julga um campo receptivo de ~70×70 pixels. Calculando a média. Essa é uma suposição de campo aleatório de Markov: o realismo é local. Muito mais rápido para treinar, menos parâmetros, saída mais nítida.
Perda.
loss_G = -log D(x, G(x)) + λ · ||y - G(x)||_1
loss_D = -log D(x, y) - log (1 - D(x, G(x)))
O termo L1 estabiliza o treinamento e direciona G para o alvo conhecido. L1 fornece bordas mais nítidas do que L2 (medianas, não médias). λ = 100 era o padrão do Pix2Pix.
CycleGAN — quando você não tem pares
O Pix2Pix precisa de dados pareados (x, y). O CycleGAN (Zhu et al., 2017) remove essa exigência ao custo de uma perda extra: a perda de consistência de ciclo (cycle consistency). Dois geradores G: X → Y e F: Y → X. Treine-os de modo que F(G(x)) ≈ x e G(F(y)) ≈ y. Isso permite traduzir cavalos em zebras, verão em inverno, sem exemplos pareados.
Em 2026, a conversão de imagem para imagem não pareada é feita principalmente via difusão (ControlNet, IP-Adapter) em vez de CycleGAN, mas a ideia de consistência de ciclo sobrevive em quase todos os artigos de adaptação de domínio não pareado.
Construa
code/main.py implementa uma pequena GAN condicional em dados 1-D. A condição c é um rótulo de classe (0 ou 1). A tarefa: produzir uma amostra da distribuição condicional para a classe dada.
Passo 1: anexar a condição às entradas de G e D
def G(z, c, params):
return mlp(concat([z, one_hot(c)]), params)
def D(x, c, params):
return mlp(concat([x, one_hot(c)]), params)
A codificação one-hot é a maneira mais simples. Modelos maiores usam embeddings aprendidos, modulação FiLM ou atenção cruzada (cross-attention).
Passo 2: treinar o condicional
for step in range(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)
O gerador deve corresponder à distribuição real para a condição dada, não à marginal.
Passo 3: verificar a saída por classe
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)
Armadilhas
- Condição ignorada. G aprende a marginalizar, D nunca penaliza porque o sinal da condição é fraco. Correção: condicione D de forma mais agressiva (camada inicial, não apenas no final), use um discriminador de projeção (Miyato & Koyama 2018).
- Peso L1 muito baixo. G deriva para saídas realistas arbitrárias, não fiéis. Comece com λ≈100 para tarefas do tipo Pix2Pix.
- Peso L1 muito alto. G produz saídas borradas porque L1 ainda é uma norma L_p. Reduza gradualmente (anneal down) assim que o treinamento estabilizar.
- Vazamento de ground-truth em D. Concatene
(x, y)como entrada de D, não apenasy. Sem isso, D não pode verificar a consistência. - Colapso de modo por classe. Cada classe pode colapsar independentemente. Execute verificações de diversidade condicionais por classe.
Use
Estado das tarefas de imagem para imagem em 2026:
| Tarefa | Melhor abordagem |
|---|---|
| Esboço → foto, mesmo domínio, dados pareados | Pix2Pix / Pix2PixHD (ainda rápido, ainda nítido) |
| Esboço → foto, não pareado | ControlNet com um modelo de condicionamento Scribble |
| Seg semântica → foto | SPADE / GauGAN2 ou SD + ControlNet-Seg |
| Transferência de estilo | Difusão com IP-Adapter ou LoRA; métodos GAN são legados |
| Profundidade → foto | ControlNet-Depth sobre Stable Diffusion |
| Super-resolução | Real-ESRGAN (GAN), ESRGAN-Plus ou SD-Upscale (difusão) |
| Colorização | ColTran, colorizadores baseados em difusão ou Pix2Pix-color |
| Dia → noite, estações, clima | Baseado em CycleGAN ou ControlNet |
O Pix2Pix continua sendo a ferramenta certa quando (a) você tem milhares de exemplos pareados, (b) a tarefa é restrita e repetível e (c) você precisa de inferência rápida. Em tarefas genéricas de domínio aberto, a difusão vence.
Envie
Salve outputs/skill-img2img-chooser.md. A Skill recebe uma descrição da tarefa, disponibilidade de dados (pareados vs não pareados, N amostras) e orçamento de latência/qualidade, e então gera: abordagem (Pix2Pix, CycleGAN, variante ControlNet, SDXL + IP-Adapter), requisitos de dados de treinamento, custo de inferência e protocolo de avaliação (LPIPS, FID, específico da tarefa).
Exercícios
- Fácil. Modifique
code/main.pypara adicionar uma terceira classe. Confirme se G ainda mapeia o ruído de cada classe para o modo correto. - Médio. Substitua L1 por uma perda do tipo perceptual no cenário 1-D (por exemplo, um pequeno D congelado atuando como extrator de características). Isso altera a nitidez da distribuição condicional?
- Difícil. Esboce um CycleGAN no cenário 1-D: duas distribuições, dois geradores, perda de ciclo. Mostre que ele aprende a mapear entre eles sem dados pareados.
Termos-Chave
| Termo | O que as pessoas dizem | O que realmente significa |
|---|---|---|
| GAN Condicional | "GAN com rótulos" | G(z, c), D(x, c). Ambas as redes veem a condição. |
| Pix2Pix | "GAN de imagem para imagem" | cGAN pareada com G U-Net e D PatchGAN + perda L1. |
| U-Net | "Encoder-decoder com saltos" | Rede convolucional simétrica; os saltos preservam alta frequência. |
| PatchGAN | "Classificador de realismo local" | D produz uma pontuação por patch em vez de uma pontuação global. |
| CycleGAN | "Tradução de imagem não pareada" | Dois Gs + perda de consistência de ciclo; sem dados pareados. |
| SPADE | "GauGAN" | Normaliza as ativações intermediárias com o mapa semântico; segmentação para imagem. |
| FiLM | "Modulação linear por característica" | Transformação afim por característica a partir da condição; condicionamento barato. |
Nota de produção: Pix2Pix como baseline limitada por latência
Quando você tem dados pareados e uma tarefa restrita (esboço → renderização, mapa semântico → foto, dia → noite), a inferência de disparo único (one-shot) do Pix2Pix supera a difusão por uma ordem de magnitude em latência. A comparação em produção geralmente é:
| Caminho | Passos | Latência típica em 512² em uma única L4 |
|---|---|---|
| Pix2Pix (U-Net forward) | 1 | ~30 ms |
| SD-Inpaint ou SD-Img2Img | 20 | ~1,2 s |
| SDXL-Turbo Img2Img | 1-4 | ~0,15-0,35 s |
| ControlNet + SDXL base | 20-30 | ~3-5 s |
O Pix2Pix vence em vazão (throughput) em lotes estáticos (toda requisição consome os mesmos FLOPs). A difusão vence em qualidade e generalização. A abordagem moderna costuma ser implantar um modelo destilado no estilo Pix2Pix para a tarefa restrita e um fallback de difusão para entradas menos comuns (tail inputs).
Leitura Adicional
- Mirza & Osindero (2014). Conditional Generative Adversarial Nets — o artigo da cGAN.
- Isola et al. (2017). Image-to-Image Translation with Conditional Adversarial Networks — Pix2Pix.
- Zhu et al. (2017). Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks — CycleGAN.
- Wang et al. (2018). High-Resolution Image Synthesis with Conditional GANs — Pix2PixHD.
- Park et al. (2019). Semantic Image Synthesis with Spatially-Adaptive Normalization — SPADE / GauGAN.
- Miyato & Koyama (2018). cGANs with Projection Discriminator — o D de projeção.