Generative Adversarial Network
Mạng đối sinh
Bạn nhìn 2 bức tranh. Một do hoạ sĩ vẽ, một do AI tạo. Bạn có thể phân biệt không?
Hình minh họa
Bạn sắp đóng vai Discriminator — thám tử phân biệt thật/giả.
Mỗi vòng bạn thấy 2 bức pixel art. Hãy chọn bức nào là giả!
Qua 8 vòng, Generator sẽ ngày càng giỏi hơn. Bạn có giữ được độ chính xác?
Bạn vừa đóng vai Discriminator trong một GAN! Generator tạo ảnh giả, Discriminator (bạn) cố phân biệt. Hai bên cạnh tranh → ảnh giả ngày càng thật!
Hai đường loss dao động quanh điểm cân bằng
Không giống mạng bình thường (loss chỉ giảm), GAN có 2 mạng chơi tay đôi. Khi D giỏi hơn, loss G tăng. Khi G giỏi hơn, loss D tăng. Cuối cùng cả hai dao động gần đường log 2 ≈ 0.69.
Step 5/40 — quan sát 2 đường dao động ngược pha.
Khi Generator chọn đường "dễ" — mode collapse
Nếu G tìm được một mẫu nào đó lừa được D, nó có thể "lười" và sinh mẫu đó mãi. Dữ liệu thật có 4 modes (cụm), nhưng G chỉ phủ 1 — thiếu đa dạng hoàn toàn.
Dữ liệu thật (4 modes)
Generator bị collapse (1 mode)
Các chấm xám là mẫu Generator sinh. Khi healthy, chúng phủ đều 4 vòng; khi collapsed, tất cả tập trung về một vòng.
Conditional GAN: nói cho G biết muốn tạo gì
Trong GAN gốc, G tạo ảnh ngẫu nhiên. Trong cGAN, ta đưa thêm label y(ví dụ: "số 7", "ảnh chó", "ảnh mũi tên") vào cả G và D. Ta điều khiển được loại ảnh được sinh ra.
Nhiễu z
z ~ N(0,1)
Label y
y = 0
(tim)
cG
Conditional
Generator
cGAN học phân phối có điều kiện . Giữ nguyên y, đổi z → cùng loại, khác chi tiết. Đổi y → sang lớp khác.
- Pix2Pix: y = ảnh bản phác → x = ảnh thật (ví dụ: label map → ảnh đường phố).
- Super-resolution: y = ảnh thấp phân giải → x = ảnh cao phân giải.
- Text-to-image (early): y = câu mô tả → x = ảnh.
Đi dạo trong latent space (StyleGAN style)
Một Generator tốt học một không gian latent liên tục: mỗi điểm z tương ứng một ảnh, và các điểm gần nhau sinh ra ảnh giống nhau. Di chuyển z dọc theo một chiều = biến đổi ảnh theo một thuộc tính.
z_start
z(t), t = 0.00
z_end
StyleGAN học một latent space "disentangled": mỗi chiều kiểm soát một thuộc tính. Đi dạo mượt ở đây tương ứng với nội suy khuôn mặt, tuổi, hay phong cách trong các mô hình thực tế.
StyleGAN nổi bật nhờ điểm gì so với GAN gốc?
So sánh hai biến thể cơ bản
DCGAN (2015) là baseline CNN mạnh nhưng unstable. WGAN (2017) thay loss bằng Wasserstein distance — ổn định hơn nhiều, đổi lại tốc độ huấn luyện chậm hơn.
DCGAN
Loss: Binary cross-entropy
Mode collapse: Thường xuyên
So sánh chỉ số
Baseline mạnh, đơn giản, dùng CNN thay FC layers. Hay bị mode collapse và unstable training.
Giải thích
GAN (Generative Adversarial Network) gồm hai mạng huấn luyện đối kháng theo trò chơi minimax:
- D muốn tối đa V: phân biệt đúng thật/giả.
- G muốn tối thiểu V: lừa D nghĩ ảnh giả là thật.
- Cân bằng Nash: và khi thì cho mọi x.
Vòng huấn luyện: Mỗi bước, ta huấn luyện D trước (cố định G), rồi huấn luyện G (cố định D). Hai mạng luân phiên cải thiện cho đến khi đạt cân bằng — hoặc phân kỳ nếu không cẩn thận.
for epoch in range(epochs):
for real_batch in dataloader:
# 1. Huấn luyện Discriminator
z = torch.randn(batch_size, latent_dim, device=device)
fake = generator(z).detach()
loss_D = -torch.mean(
torch.log(discriminator(real_batch) + 1e-8)
+ torch.log(1 - discriminator(fake) + 1e-8)
)
optimizer_D.zero_grad()
loss_D.backward()
optimizer_D.step()
# 2. Huấn luyện Generator
z = torch.randn(batch_size, latent_dim, device=device)
fake = generator(z)
loss_G = -torch.mean(torch.log(discriminator(fake) + 1e-8))
optimizer_G.zero_grad()
loss_G.backward()
optimizer_G.step()def gradient_penalty(D, real, fake):
alpha = torch.rand(real.size(0), 1, 1, 1, device=real.device)
interp = alpha * real + (1 - alpha) * fake
interp.requires_grad_(True)
d_interp = D(interp)
grads = torch.autograd.grad(
outputs=d_interp, inputs=interp,
grad_outputs=torch.ones_like(d_interp),
create_graph=True, retain_graph=True,
)[0]
grads = grads.view(real.size(0), -1)
gp = ((grads.norm(2, dim=1) - 1) ** 2).mean()
return gp
# Trong training loop
for epoch in range(epochs):
for real in dataloader:
# D step (lặp 5 lần mỗi G step)
for _ in range(5):
z = torch.randn(real.size(0), latent_dim, device=device)
fake = generator(z).detach()
gp = gradient_penalty(discriminator, real, fake)
loss_D = (
discriminator(fake).mean()
- discriminator(real).mean()
+ 10.0 * gp
)
optimizer_D.zero_grad()
loss_D.backward()
optimizer_D.step()
# G step
z = torch.randn(real.size(0), latent_dim, device=device)
fake = generator(z)
loss_G = -discriminator(fake).mean()
optimizer_G.zero_grad()
loss_G.backward()
optimizer_G.step()Biến thể quan trọng:
- StyleGAN — kiểm soát phong cách ở nhiều mức (tóc, khuôn mặt, nền). Tạo khuôn mặt siêu thực.
- CycleGAN— chuyển đổi phong cách không cần cặp ảnh (ngựa ↔ ngựa vằn, ảnh ↔ tranh Monet).
- Pix2Pix— biến đổi ảnh theo cặp (bản phác → ảnh thật, nhãn → ảnh đường phố).
- BigGAN / StyleGAN-XL — scale lên hàng trăm triệu tham số, ảnh 1024×1024 chất lượng cao.
- GigaGAN — biến thể lớn cho text-to-image, cạnh tranh với diffusion về chất lượng nhưng nhanh hơn.
Chu trình lặp lại hàng nghìn lần — cả hai ngày càng giỏi hơn!
Generator dở, Discriminator dễ phân biệt.
- Dùng Adam với (không phải 0.9 như bình thường).
- Label smoothing: thay vì target 1.0 cho ảnh thật, dùng 0.9 — giảm quá tự tin của D.
- TTUR (Two Time-scale Update Rule): learning rate của D và G khác nhau, thường lr_D < lr_G.
- Theo dõi chất lượng bằng FID/IS, không chỉ loss — loss GAN không luôn phản ánh chất lượng.
Nếu Generator quá giỏi nhưng chỉ tạo được MỘT loại ảnh (luôn là mèo), vấn đề gì xảy ra?
- GAN gồm Generator (tạo dữ liệu giả từ z ~ N(0,1)) và Discriminator (phân biệt thật/giả), huấn luyện đối kháng.
- Mục tiêu minimax V(D,G): G cố lừa D, D cố phát hiện G — cân bằng Nash khi D(x) = 0.5 với mọi x.
- Loss G và D dao động ngược pha; không bao giờ giảm mượt như mạng bình thường — đừng hoảng khi thấy loss lên xuống.
- Thách thức lớn nhất: mode collapse — G chỉ học 1 pattern 'an toàn'. WGAN-GP giảm đáng kể rủi ro này.
- cGAN thêm label y vào cả G và D để điều khiển loại ảnh; StyleGAN thêm mapping network cho latent disentangled.
- Biến thể phổ biến: DCGAN (baseline CNN), WGAN-GP (ổn định), CycleGAN, Pix2Pix, BigGAN, StyleGAN. Diffusion Models đang dần thay thế GAN cho text-to-image.
Kiểm tra hiểu biết
Trong GAN, Generator nhận đầu vào là gì?