GAN — দু'টি network-এর minimax খেলা
এই পাঠে যা শিখবেন
- GAN-এর adversarial intuition — জালিয়াত বনাম পুলিশের খেলা
- Minimax objective ও তার ভিত্তির গণিত
- Vanishing gradient সমস্যা ও non-saturating fix
- PyTorch দিয়ে একটি ছোট GAN — MNIST digit generation
১ · GAN-এর জন্ম
২০১৪ সালে Ian Goodfellow ও সহকর্মীরা একটি অসাধারণ idea proposalকরেন — "দু'টি neural network-কে পরস্পরের প্রতিদ্বন্দ্বী বানিয়ে train করো।" Yann LeCun এই idea-কে "the most interesting idea in the last 10 years in ML" বলেছিলেন। আজকের StyleGAN, image generation-এর সূচনা সেখানেই।
১) Generator $G$: noise $z \sim p_z$ থেকে fake sample $G(z)$ তৈরি করে — যেন real মনে হয়।
২) Discriminator $D$: একটি sample দেখে বলতে চায় "এটি real (training data থেকে) নাকি fake ($G$-র তৈরি)।"
$G$ চায় $D$-কে ঠকাতে; $D$ চায় ঠিক বলতে। এই adversarial dynamic-ই GAN।
২ · Minimax objective
Goodfellow-এর মূল formulation:
$$\min_G \max_D V(D, G) = \mathbb{E}_{x \sim p_{\text{data}}}[\log D(x)] + \mathbb{E}_{z \sim p_z}[\log(1 - D(G(z)))]$$
Discriminator-এর দৃষ্টিতে ($\max_D$): real $x$-এ $D(x) \to 1$ চাই (প্রথম term বড়); fake $G(z)$-তে $D(G(z)) \to 0$ চাই (দ্বিতীয় term-ও বড়)।
Generator-এর দৃষ্টিতে ($\min_G$): দ্বিতীয় term ছোট চাই — অর্থাৎ $D(G(z)) \to 1$, যাতে $D$ ঠকে যায়।
Theoretical optimum: Goodfellow প্রমাণ করলেন — fixed $G$-এর জন্য optimal discriminator $D^*(x) = \frac{p_{\text{data}}(x)}{p_{\text{data}}(x) + p_g(x)}$। এটা সম্পূর্ণ minimize হলে $p_g = p_{\text{data}}$, এবং objective = $-\log 4$ (Jensen-Shannon divergence-এর সাথে সংযোগ)।
৩ · Vanishing gradient ও non-saturating loss
Practice-এ original $\log(1 - D(G(z)))$ সমস্যা তৈরি করে — training-এর শুরুতে $D$ অনেক শক্তিশালী, $D(G(z)) \approx 0$, এবং $\log(1-0) = 0$ — gradient vanish।
Goodfellow নিজেই একটি practical fix দিলেন — generator-এর জন্য objective বদলে দাও:
$$\mathcal{L}_G = -\mathbb{E}_{z}[\log D(G(z))]$$
এটি non-saturating lossNon-saturating GAN lossGoodfellow ২০১৪ পেপারে বর্ণিত — vanishing gradient রোধে generator objective-কে $\log D(G(z))$ maximize করতে বদলানো। আজও practice-এ standard। — gradient large থাকে যখন $D(G(z))$ ছোট, generator দ্রুত শেখে।
৪ · Training algorithm
Alternating updates:
- Real batch $x$ ও noise $z$ sample।
- Discriminator step: $D$-এর parameter update করুন $\nabla_D [\log D(x) + \log(1 - D(G(z)))]$ ascent।
- Generator step: $G$-এর parameter update করুন $\nabla_G \log D(G(z))$ ascent (non-saturating)।
- পুনরাবৃত্তি।
কখনো $D$-কে ১ step, কখনো ৫ step train করে তারপর $G$-এর ১ step — হিসাব করে balance রাখা হয়। অস্থিরতা GAN-এর কুখ্যাত সমস্যা।
৫ · PyTorch — সাধারণ Generator
import torch
import torch.nn as nn
class Generator(nn.Module):
def __init__(self, z_dim=100, img_dim=784):
super().__init__()
self.net = nn.Sequential(
nn.Linear(z_dim, 256), nn.LeakyReLU(0.2),
nn.Linear(256, 512), nn.LeakyReLU(0.2),
nn.Linear(512, 1024), nn.LeakyReLU(0.2),
nn.Linear(1024, img_dim), nn.Tanh(), # output -1 to 1
)
def forward(self, z):
return self.net(z)
class Discriminator(nn.Module):
def __init__(self, img_dim=784):
super().__init__()
self.net = nn.Sequential(
nn.Linear(img_dim, 1024), nn.LeakyReLU(0.2), nn.Dropout(0.3),
nn.Linear(1024, 512), nn.LeakyReLU(0.2), nn.Dropout(0.3),
nn.Linear(512, 256), nn.LeakyReLU(0.2),
nn.Linear(256, 1), nn.Sigmoid(),
)
def forward(self, x):
return self.net(x)
৬ · Training loop
G = Generator(); D = Discriminator()
opt_G = torch.optim.Adam(G.parameters(), lr=2e-4, betas=(0.5, 0.999))
opt_D = torch.optim.Adam(D.parameters(), lr=2e-4, betas=(0.5, 0.999))
bce = nn.BCELoss()
for epoch in range(50):
for real, _ in train_loader:
bs = real.size(0)
real = real.view(bs, -1) * 2 - 1 # to [-1, 1]
z = torch.randn(bs, 100)
fake = G(z)
# ── D step ──
d_real = D(real); d_fake = D(fake.detach())
loss_D = bce(d_real, torch.ones_like(d_real)) \
+ bce(d_fake, torch.zeros_like(d_fake))
opt_D.zero_grad(); loss_D.backward(); opt_D.step()
# ── G step (non-saturating) ──
d_fake_for_g = D(fake)
loss_G = bce(d_fake_for_g, torch.ones_like(d_fake_for_g))
opt_G.zero_grad(); loss_G.backward(); opt_G.step()
৭ · Sampling নতুন digit
G.eval()
with torch.no_grad():
z = torch.randn(16, 100)
samples = G(z).view(-1, 28, 28)
samples = (samples + 1) / 2 # back to [0, 1]
print(samples.shape)
৮ · কুখ্যাত সমস্যা
- Mode collapse: $G$ একই কয়েকটি sample-ই বানায়। (পরের পাঠের বিষয়।)
- Non-convergence: দু'টি network oscillate করে — কোনো equilibrium-এ পৌঁছায় না।
- Vanishing gradient: $D$ অনেক শক্তিশালী হলে $G$ গাইডলাইন পায় না।
- Hyperparameter sensitive: learning rate, batch size একটু বদলে training ভেঙে যেতে পারে।
৯ · GAN-এর প্রভাব AI-তে
- StyleGAN — photorealistic human face।
- BigGAN — class-conditional ImageNet image।
- Pix2Pix, CycleGAN — image-to-image translation।
- Bangla handwriting synthesis — small dataset থেকে বেশি sample তৈরি।
- Daraz product photo enhancement, fashion try-on।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ Goodfellow-র মূল paper-এ minimax objective Jensen-Shannon divergence-এর সাথে সমান। JSD কী, এবং কেন এই connection বিকল্প GAN-loss-এর প্রেরণা?
Goodfellow ২০১৪-এর paper-এ একটি সুন্দর mathematical result আছে — optimal discriminator-এর জন্য minimax objective-কে rewrite করলে এটি real ও fake distribution-এর Jensen-Shannon divergence (JSD)-এর সমান।
JSD definition:
- $\mathrm{JSD}(P\|Q) = \tfrac{1}{2} \mathrm{KL}(P \| M) + \tfrac{1}{2} \mathrm{KL}(Q \| M)$, যেখানে $M = \tfrac{1}{2}(P + Q)$।
- Symmetric (KL-এর বিপরীতে), bounded $[0, \log 2]$, defined সবসময়।
- $P = Q$ হলে JSD = 0; সম্পূর্ণ disjoint হলে $\log 2$।
Goodfellow-র derivation summary:
- Optimal $D^*(x) = p_{\text{data}}/(p_{\text{data}} + p_g)$ plug করলে — $V(D^*, G) = -\log 4 + 2 \cdot \mathrm{JSD}(p_{\text{data}} \| p_g)$।
- অর্থাৎ, generator effectively JSD minimize করছে।
- JSD = 0 হলে $p_g = p_{\text{data}}$ — perfect generation।
সমস্যা — JSD-এর pathology:
- যদি $p_g$ ও $p_{\text{data}}$-এর support disjoint হয় (training-এর শুরুতে সাধারণত হয়), JSD সর্বদা $\log 2$ — gradient zero।
- "Non-overlapping manifolds" — এজন্যই vanishing gradient।
- Real-world image data low-dimensional manifold-এ থাকে; random $G$-এর support অন্য manifold-এ — overlap সম্ভাবনা ০।
বিকল্প divergence-এর প্রেরণা:
- WGAN (Arjovsky et al., ২০১৭): Wasserstein/Earth Mover's distance — non-overlapping support-এও meaningful gradient। (পরের পাঠ।)
- f-GAN (Nowozin et al., ২০১৬): general f-divergence framework — KL, JSD, Pearson, etc.
- Least Squares GAN (Mao et al., ২০১৬): Pearson $\chi^2$ — vanishing gradient কম।
- Hinge loss GAN: SVM-style margin — BigGAN, StyleGAN-এ ব্যবহৃত।
ব্যবহারিক implication:
- Vanilla GAN training-এর প্রথম epoch-গুলোয় unstable — এই JSD pathology-র জন্য।
- Spectral normalization (Miyato et al., ২০১৮) — Lipschitz constraint যোগ করে stability বাড়ায়।
- Training tricks (instance noise, label smoothing) — disjoint support সমস্যা mitigate।
মূল উপলব্ধি: "GAN = JSD minimization" — এই গাণিতিক চশমা পরে দেখলে, পুরো GAN literature-এর evolution বোঝা সহজ হয়। প্রতিটি improvement (WGAN, LS-GAN, GAN-GP) আসলে divergence-এর উপর ভিন্ন trick।
প্র ০২ Discriminator অনেক শক্তিশালী হলে generator শেখা বন্ধ — এটা কেন? "Two timescale update rule (TTUR)" কীভাবে এ সমস্যা মোকাবিলা করে?
GAN training-এর সবচেয়ে কুখ্যাত problem — adversaries-এর "ভারসাম্য" ধরে রাখা। দুটোই ভালো হলে একে অপরকে গাইড করে, কিন্তু একজন বেশি শক্তিশালী হলে সব ভেঙে পড়ে।
Discriminator dominance — কী হয়:
- $D$ যদি প্রায় সব fake-এ $D(G(z)) \approx 0$ output দেয়, তখন $\log(1 - D(G(z))) \to 0$।
- Original objective-এ gradient $\nabla_G \log(1 - D(G(z))) \to 0$ — vanishing।
- Generator-কে "কোন দিকে যাব" এই information আর নেই।
- Non-saturating loss এই সমস্যা partially fix করে — কিন্তু $D$ পুরোপুরি saturated হলে তাও ভাঙে।
সমাধানগুলো:
(১) $D$-কে দুর্বল রাখা:
- $D$-কে ১ step, $G$-কে ৫ step train — ratio ভিন্ন।
- Label smoothing — real label ১ না, ০.৯ ব্যবহার।
- Instance noise — input-এ Gaussian noise যোগ।
(২) Two Timescale Update Rule (TTUR — Heusel et al., ২০১৭):
- $D$-এর learning rate ($lr_D = 4 \times 10^{-4}$) > $G$-এর learning rate ($lr_G = 1 \times 10^{-4}$)।
- Theoretically প্রমাণিত — local Nash equilibrium-এ converge।
- Practice-এ সব serious GAN paper TTUR ব্যবহার করে।
- Intuition: $D$ এক step-এ অনেক shift করে, $G$ ধীরে adjust — অস্থিরতা কম।
(৩) Spectral Normalization (Miyato et al., ২০১৮):
- $D$-এর প্রতিটি weight matrix-এর spectral norm $\leq 1$।
- Lipschitz constraint → $D$ "smooth" থাকে → vanishing gradient কম।
- SAGAN, BigGAN, StyleGAN — সবার backbone।
(৪) WGAN approach:
- Critic optimal হলেও gradient meaningful — JSD-এর বদলে Wasserstein।
- $D$-কে শক্তিশালী রাখাই বরং পরামর্শ। (পরের পাঠ।)
(৫) Diagnostic monitoring:
- D-loss খুব ছোট ($\to 0$) মানে $D$ overpowering।
- G-loss diverging মানে generator গাইড পাচ্ছে না।
- Sample diversity track — same image বারবার এলে mode collapse।
মূল উপলব্ধি: GAN training "engineering art" — গাণিতিক রুমের চেয়ে অনেক বেশি। TTUR, spectral norm, Adam-এর $\beta_1 = 0.5$ — সবই empirically discovered tricks যা literature-এর সম্মিলিত প্রজ্ঞা। Diffusion-এর জনপ্রিয়তার একটা বড় কারণ — এই অস্থিরতা থেকে মুক্তি।
প্র ০৩ VAE-র "ELBO" বনাম GAN-এর "adversarial" — দু'টি train objective-র ফিলোসফিক্যাল পার্থক্য কী? কোনটি কখন ভাল?
Generative modeling-এ দু'টি দার্শনিক ঘরানা আছে — likelihood-based ও likelihood-free। VAE প্রথমটি, GAN দ্বিতীয়টি। দু'টিরই principle ও practice ভিন্ন।
Likelihood-based (VAE, Flow, Autoregressive):
- Explicit density $p_\theta(x)$ model — ELBO maximize।
- "Data কতটা likely এই model-এর অধীনে?" — quantifiable।
- Training stable — single objective।
- Anomaly detection, density estimation, compression সম্ভব।
- Sample blurry — pixel-wise loss-এর mean-seeking nature।
Likelihood-free (GAN, score-based partly):
- $p_\theta$ explicit না — শুধু sample যেতে পারি।
- "Real vs fake distinguishable?" — adversarial test।
- Training unstable — minimax saddle point।
- Likelihood হিসাব করা যায় না।
- Sharp, photorealistic sample।
Philosophical difference:
- VAE: "I know the rules of probability — let me write them down explicitly."
- GAN: "I don't need explicit probability — if you can't tell my output from real, I've succeeded."
- Frequentist বনাম empirical।
কখন কোনটি ভাল:
- Anomaly detection / density estimation: VAE/Flow।
- High-fidelity image synthesis: GAN/Diffusion।
- Stable training, small data: VAE।
- Limited compute, sharp output চাই: GAN।
- Time-series, audio likelihood চাই: Flow/Autoregressive।
- Compositional/disentangled control: VAE/StyleGAN hybrid।
আধুনিক convergence:
- Diffusion model — likelihood-based + sharp। দু'টোর সুবিধা।
- VAE-GAN hybrid: recon + adversarial।
- Score-based generative: NCSN (Song et al., ২০১৯) — likelihood থেকে score function-এ shift।
- Latent diffusion: VAE encoder + diffusion + GAN-tuned decoder।
Bangladesh context:
- BTRC compliance reports-এ "synthetic data" সম্ভাব্যতা analyze করতে likelihood লাগে → VAE।
- Daraz fashion catalog enhancement → GAN/Diffusion-এর sharp output।
মূল উপলব্ধি: দু'টি approach competitor নয়, complementary। আজকের best system (Stable Diffusion) দু'টোর elements মেশায় — VAE encoder + diffusion + perceptual loss + adversarial finetune। AI-র ভবিষ্যৎ সম্ভবত এই hybridization-এ।
প্র ০৪ একটি Bangla calligraphy GAN train করছেন — মাত্র ২,০০০ image আছে। কী strategy নেবেন? Data augmentation, transfer learning, regularization-এর role আলোচনা করুন।
Small data-তে GAN train করা অত্যন্ত কঠিন — discriminator training data মুখস্থ করে ফেলে, generator-কে কোনো useful signal দেয় না। Bangla এর low-resource setting-এ এটি বাস্তব সমস্যা।
Step 1 — Data audit:
- ২,০০০ image কতটা diverse? একই hand, একই font?
- Resolution? GAN-এ ৬৪×৬৪ থেকে শুরু করুন, ২৫৬×২৫৬ যেতে হলে অনেক বেশি data দরকার।
- Quality control — blurry/mislabeled image বাদ।
Step 2 — Aggressive data augmentation:
- Standard: rotation, scale, translation, brightness।
- StyleGAN2-ADA (Karras et al., ২০২০): adaptive augmentation — discriminator-এর overfitting অনুসারে strength tune। ১,০০০-৫,০০০ image-এও কাজ করে।
- Bangla-specific: ink thickness vary, paper texture, slight slant।
- Augmentation discriminator-এ apply করুন real ও fake দুটোতেই — generator distribution corrupt না হয়।
Step 3 — Transfer learning:
- একটি large dataset-এ pretrained GAN দিয়ে শুরু করুন (FFHQ, MNIST, English handwriting)।
- Higher layers freeze বা low LR; lower layers fine-tune।
- "Freeze-D" technique — discriminator-এর কিছু layer freeze, সব না shift।
- Bangla character + English handwriting share লাগে stroke-level features।
Step 4 — Regularization:
- R1 gradient penalty (Mescheder et al., ২০১৮) — real data-এ discriminator-এর gradient norm penalize।
- Spectral normalization — D-এর Lipschitz constraint।
- Path length regularization (StyleGAN2) — generator smoothness।
- Dropout in D — overfitting-এর প্রথম প্রতিরোধ।
Step 5 — Architecture choice:
- Smaller model — overfitting কম। StyleGAN3 over কurrently overshoot।
- Progressive growing — ছোট resolution থেকে বড়।
- Conditional GAN — character class label দিয়ে structure।
Step 6 — Evaluation:
- FID score limited (Inception ImageNet-trained, Bangla character-এ অপ্রয়োজনীয় bias)।
- Manual inspection — diverse sample দেখুন।
- Nearest-neighbor in training set — generator কি memorize করছে?
- Native speaker evaluation — Bangla-জ্ঞ কেউ "real-looking?" বলবেন।
Step 7 — Modern alternatives consider করুন:
- Diffusion model — small data-তে GAN-এর চেয়ে stable।
- Few-shot GAN — research area।
- Stable Diffusion fine-tuning + LoRA — pretrained weight + tiny dataset।
মূল উপলব্ধি: Bangla-এর মতো low-resource language-এ generative model train করা শুধু গণিত নয় — data engineering, augmentation, transfer, regularization-এর সমন্বয়। ABCL TECH-এর মতো প্রতিষ্ঠানের জন্য এটি একটি competitive frontier।
অনুশীলন
-
হাতে-কলমে: Optimal $D^*(x) = \frac{p_d(x)}{p_d(x) + p_g(x)}$ derive করুন। $V(D, G)$-এর integrand-কে $D(x)$-এর সাপেক্ষে differentiate করে।
$V(D, G) = \int p_d(x) \log D(x) + p_g(x) \log(1 - D(x)) \, dx$।
প্রতি $x$-এর জন্য $a \log y + b \log(1-y)$ form। $y = D(x)$ ধরে differentiate: $\frac{a}{y} - \frac{b}{1-y} = 0$ → $y^* = \frac{a}{a+b} = \frac{p_d}{p_d + p_g}$। QED।
-
কোডে চেষ্টা: উপরের training loop-এ Adam-এর $\beta_1 = 0.9$ (default) করে দেখুন। Loss curve কেমন আচরণ করে?
সাধারণত training অস্থির — D-loss ও G-loss দু'টোই oscillate করে, sample quality আগের চেয়ে অনেক কম। DCGAN paper এ কারণেই $\beta_1 = 0.5$ recommend করেছে — আজও standard practice।
-
ভাবুন: Bangla newspaper headline-এর synthetic font generate করতে GAN ব্যবহার করতে চান। কী conditioning দরকার? কী challenge আশা করেন?
- Conditioning: character identity (which অক্ষর), font style label।
- Challenge: যুক্তাক্ষর (compound characters) অনেক — দীর্ঘ tail। Diversity বনাম legibility trade-off।
- Resolution চাই vector-grade quality, raster GAN sufficient হবে না — possibly diffusion + post-processing।
- Evaluation: native speaker readable কিনা।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পাঠ ৯ · DCGAN ও StyleGAN পরবর্তী পাঠ Vanilla GAN-কে production-quality করার দু'টি landmark architecture।
- পাঠ ৭ · VAE — ELBO ও reparameterization আগের পাঠ VAE-র probabilistic দৃষ্টি — GAN-এর adversarial-এর বিকল্প।
- পাঠ ১০ · WGAN ও mode collapse এই পাঠের সাথে সম্পর্কিত GAN-এর কুখ্যাত সমস্যা ও তার গাণিতিক সমাধান।
- সব AI Courses দেখুন ABCL TECH Python, ML, DL, NLP, CV, GenAI, RL, MLOps — সব AI কোর্স একসাথে।