فاز 4 · درس 9

آموزش تولید تصویر با شبکه‌های زایشی رقابتی (GAN) و DCGAN در PyTorch

نوع
ساختنی
زمان
حدود 75 دقیقه
زبان‌ها
Python
دو روبات که یکی بوم نقاشی را ترسیم می‌کند و دیگری با ذره‌بین خطاهای طرح را بررسی می‌کند
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفاهیم پایه
  4. دو شبکه
  5. بازی
  6. تابع زیان غیراشباع‌کننده
  7. قواعد معماری DCGAN
  8. حالت‌های شکست و نشانه‌های آن‌ها
  9. ارزیابی
  10. پیاده‌سازی از صفر
  11. مرحله 1: مولد
  12. مرحله 2: تفکیک‌کننده
  13. مرحله 3: گام آموزش
  14. مرحله 4: حلقه کامل آموزش روی اشکال هندسی ساختگی
  15. مرحله 5: نمونه‌برداری
  16. مرحله 6: نرمال‌سازی طیفی
  17. استفاده از ابزارهای واقعی
  18. خروجی این درس
  19. تمرین‌ها
  20. اصطلاحات کلیدی
  21. برای مطالعه‌ی بیشتر

تولید تصویر مصنوعی یکی از جذاب‌ترین حوزه‌های یادگیری عمیق است؛ اما آموزش شبکه‌های زایشی رقابتی (Generative Adversarial Networks یا GAN) معمولاً با چالش‌های بزرگی مثل ناپایداری گرادیان‌ها یا فروپاشی مُد (Mode Collapse) همراه می‌شود. بدون شناخت دقیق قواعد معماری و تنظیمات ریاضیِ آموزش، مدل به‌جای تولید تصاویر واقع‌گرایانه، دچار نوسان دائم یا تولید نمونه‌های تکراری می‌شود.

در این درس یاد می‌گیرید که چطور یک معماری استاندارد DCGAN را در کمتر از 60 خط کد در پایتورچ پیاده‌سازی کنید و با بهره‌گیری از تکنیک‌های اثبات‌شده‌ای مانند تابع زیان غیراشباع‌کننده، نرمال‌سازی طیفی (Spectral Normalization) و قاعده TTUR، پایداری فرایند آموزش را به شکل چشمگیری افزایش دهید.

کدها و تمرین‌های این درس به‌گونه‌ای طراحی شده‌اند که بدون نیاز به GPUهای ابری گران‌قیمت یا پرداخت‌های ارزی غیرقابل دسترس، به‌راحتی روی سخت‌افزار شخصی، پردازنده‌های معمولی (CPU) یا تراشه‌های Apple Silicon قابل اجرا و آزمایش هستند.

یک GAN (شبکه زایشی رقابتی یا Generative Adversarial Network) از دو شبکه عصبی در یک بازی مشخص تشکیل شده است: یکی نقاشی می‌کشد و دیگری نقد می‌کند. آن‌ها پا‌به‌پای هم پیشرفت می‌کنند تا جایی که نقاشی‌ها منتقد را فریب دهند.

اهداف یادگیری

  • بازی مینی‌ماکس (minimax) بین مولد و تفکیک‌کننده و دلیل تطابق نقطه تعادل آن با pmodel=pdatap_{\text{model}} = p_{\text{data}} را توضیح دهید.
  • یک DCGAN را در PyTorch پیاده‌سازی کنید و با کمتر از 60 خط کد، تصاویر ساختگیِ 32x32 منسجم بسازید.
  • آموزش GAN را با سه ترفند استاندارد پایدار کنید: تابع زیان غیراشباع‌کننده (non-saturating loss)، نرم طیفی (spectral norm) و قانون به‌روزرسانی در دو مقیاس زمانی (TTUR یا two-timescale update rule).
  • نمودارهای آموزش را طوری تحلیل کنید که همگرایی سالم از فروپاشی مد (mode collapse)، نوسان شدید (oscillation) و برد کامل تفکیک‌کننده متمایز شود.

صورت مسئله

در دسته‌بندی، به شبکه یاد می‌دهیم که تصاویر را به برچسب‌ها نگاشت کند. در تولید داده مسئله برعکس است: نمونه‌برداری از تصاویر جدیدی که انگار از همان توزیع داده‌های واقعی آمده‌اند. در اینجا هیچ خروجیِ «درستِ» مشخصی وجود ندارد که بتوانید با آن تفاضل بگیرید؛ فقط یک توزیع آماری در دست دارید که می‌خواهید شبیه‌سازی‌اش کنید.

توابع زیان استاندارد (مانند MSE و آنتروپی متقاطع) نمی‌توانند بسنجند که «آیا این نمونه واقعاً از دل توزیع واقعی آمده یا نه». کمینه‌سازی خطای پیکسلی فقط میانگین‌های مات و تار تحویل می‌دهد، نه نمونه‌های واقع‌گرایانه. نقطه عطف ماجرا یادگیریِ خودِ تابع زیان (loss) بود: آموزش یک شبکه دوم که کارش تشخیص واقعیت از جعل باشد، و استفاده از قضاوت آن برای هدایت مولد.

شبکه‌های GAN (معرفی‌شده توسط Goodfellow و همکاران، 2014) این چارچوب را بنا نهادند. تا سال 2018، مدل StyleGAN چهره‌هایی با رزولوشن 1024x1024 تولید می‌کرد که تشخیص آن‌ها از عکس واقعی غیرممکن بود. هرچند امروزه مدل‌های انتشار (diffusion models) از نظر کیفیت و کنترل‌پذیری جایگاه اول را گرفته‌اند، اما تمام ترفندهایی که استفاده از مدل‌های انتشار را عملی کردند — مثل انتخاب‌های نرمال‌سازی، فضاهای نهفته (latent spaces) و توابع زیانِ ویژگی‌محور — ابتدا روی GANها درک و تثبیت شدند.

مفاهیم پایه

دو شبکه

z ~ N(0, I)نویزمولد (Generator)کانولوشن‌های ترانهادهتصویر جعلیتصویر واقعیتفکیک‌کننده (Discriminator)طبقه‌بند کانولوشنالP(real)

مولد (Generator یا G) یک بردار نویز z را می‌گیرد و یک تصویر تحویل می‌دهد. تفکیک‌کننده (Discriminator یا D) یک تصویر می‌گیرد و یک اسکالر خروجی می‌دهد: احتمال این‌که تصویر واقعی باشد.

بازی

شبکه G می‌خواهد D اشتباه کند؛ شبکه D می‌خواهد درست تشخیص دهد. به بیان ریاضی:

min⁡Gmax⁡D  Ex[log⁡D(x)]+Ez[log⁡(1−D(G(z)))]\min_G \max_D \; \mathbb{E}_x[\log D(x)] + \mathbb{E}_z[\log(1 - D(G(z)))]

از راست به چپ بخوانید: D در حال بیشینه‌سازی دقت روی تصاویر واقعی (log D(real)) و جعلی (log (1 - D(fake))) است. در مقابل، G دقت D را روی تصاویر جعلی کمینه می‌کند — یعنی می‌خواهد مقدار D(G(z)) بالا باشد.

گودفلو اثبات کرد که این بازی مینی‌ماکس یک تعادل سراسری دارد که در آن p_G = p_data، خروجی D در تمام نقاط برابر 0.5 است و واگرایی جنسن-شنون بین توزیع داده‌های تولیدی و واقعی به صفر می‌رسد. بخش سخت ماجرا، رساندن آموزش به این نقطه است.

تابع زیان غیراشباع‌کننده

فرمول بالا از نظر عددی ناپایدار است. در اوایل آموزش، مقدار D(G(z)) برای همه تصاویر جعلی نزدیک صفر است؛ در نتیجه گرادیان log(1 - D(G(z))) نسبت به G محو می‌شود (vanishing gradients). راه‌حل: معکوس کردن تابع زیان G.

LD=−Ex[log⁡D(x)]−Ez[log⁡(1−D(G(z)))]LG=−Ez[log⁡D(G(z))](non-saturating)\begin{aligned} L_D &= -\mathbb{E}_x[\log D(x)] - \mathbb{E}_z[\log(1 - D(G(z)))] \\ L_G &= -\mathbb{E}_z[\log D(G(z))] \qquad \text{(non-saturating)} \end{aligned}

حالا وقتی D(G(z)) نزدیک صفر باشد، تابع زیان G بزرگ است و گرادیان آن اطلاعات مفیدی برای یادگیری دارد. تمام مدل‌های مدرن GAN با همین شیوه آموزش می‌بینند.

قواعد معماری DCGAN

ردفورد، متز و چینتالا (2015) سال‌ها آزمون‌وخطای ناموفق را در قالب پنج قاعده خلاصه کردند که آموزش GAN را پایدار می‌کند:

  1. لایه‌های ادغام (pooling) را با کانولوشن‌های گام‌دار (strided convolutions) در هر دو شبکه جایگزین کنید.
  2. از نرمال‌سازی دسته‌ای (batch norm) در هر دو شبکه استفاده کنید، به‌جز خروجی G و ورودی D.
  3. لایه‌های تمام‌متصل (fully connected) را در معماری‌های عمیق‌تر حذف کنید.
  4. در G برای تمام لایه‌ها از ReLU استفاده کنید، به‌جز خروجی که برای قرار گرفتن در بازه [-1, 1] از tanh بهره می‌برد.
  5. در D برای تمام لایه‌ها از LeakyReLU (با negative_slope=0.2) استفاده کنید.

تمام مدل‌های مدرن GAN مبتنی بر کانولوشن (StyleGAN، BigGAN و GigaGAN) کار را با همین قواعد شروع می‌کنند و سپس بخش‌ها را یکی‌یکی ارتقا می‌دهند.

حالت‌های شکست و نشانه‌های آن‌ها

فروپاشی مد (Mode collapse)تولید بازه محدودیاز خروجی‌ها توسط Gزیان D پایین،زیان G نوسانی،کاهش تنوع نمونه‌هامحو شدگی گرادیانپیروزی کامل Dدقت D حدود 100%،زیان G بسیار بالا و ایستانوسان مداومدست‌به‌دست شدن بردبین G و D تا ابدنوسان شدید هر دو زیانبدون روند کاهشی
  • فروپاشی مد (Mode collapse): شبکه G فقط یک تصویر پیدا می‌کند که D را فریب می‌دهد و مدام همان را تولید می‌کند. راه‌حل: افزودن تفکیک مینی‌دسته (minibatch discrimination)، نرم طیفی یا شرطی‌سازی با برچسب.
  • برد تفکیک‌کننده (Discriminator wins): شبکه D خیلی سریع قوی می‌شود و گرادیان‌های G محو می‌شوند. راه‌حل: کوچک‌تر کردن D، کاهش نرخ یادگیری D، یا اعمال هموارسازی برچسب‌ها (label smoothing) روی برچسب‌های واقعی.
  • نوسان شدید (Oscillation): دو شبکه مدام از یکدیگر سبقت می‌گیرند بدون این‌که به تعادل نزدیک شوند. راه‌حل: استفاده از TTUR (آموزش D با سرعتی 2 تا 4 برابر G)، یا تغییر تابع زیان به واسرشتاین (Wasserstein loss).

ارزیابی

در GANها داده مبنای قطعی (ground truth) وجود ندارد؛ پس چطور متوجه عملکرد درست آن‌ها شویم؟

  • بررسی چشمی نمونه‌ها — در انتهای هر دور آموزش (epoch)، 64 نمونه را بررسی کنید. این کار بدون چون‌وچرا ضروری است.
  • معیار FID (فاصله فرشه اینسپشن یا Fréchet Inception Distance) — فاصله بین توزیع ویژگی‌های Inception-v3 در مجموعه‌داده واقعی و تولیدی. هرچه کمتر باشد بهتر است و استاندارد فعلی جامعه پژوهشی به شمار می‌رود.
  • امتیاز اینسپشن (Inception Score) — معیاری قدیمی‌تر و شکننده‌تر؛ ترجیحاً از FID استفاده کنید.
  • دقت و بازخوانی (Precision/Recall) برای مدل‌های زایشی — کیفیت (دقت) و پوشش تنوع (بازخوانی) را جداگانه می‌سنجد و اطلاعات بیشتری نسبت به FIDِ تنها ارائه می‌دهد.

برای یک اجرای آزمایشی روی داده‌های ساختگی کوچک، همان بررسی چشمی نمونه‌ها کفایت می‌کند.

شبکهٔ GAN · بازی مینی‌مکسیکی رسم می‌کند، یکی نقد می‌کند
GAN · THE MINIMAX GAMEThe generator turns a noise vector into an image; the critic scores how real it looks. They train against each other: the generator pushes the critic's P(real) up, the critic pushes it down. As the seesaw settles toward balance the fake image sharpens from noise into structure.نویز zمولد Gتصویر جعلینقاد DP(real) →مینی‌مکس — G امتیاز را بالا می‌برد و D آن را پایین می‌کشدGD
مولد یک بردار نویز را به تصویر تبدیل می‌کند؛ نقاد امتیاز واقعی بودن آن را می‌سنجد. آن‌ها علیه یکدیگر آموزش می‌بینند: مولد P(real) نقاد را push می‌کند به سمت بالا، نقاد آن را push می‌کند به سمت پایین. همگام با برقراری تعادل در این الاکلنگ، تصویر جعلی از نویز به ساختاری واضح تبدیل می‌شود.

پیاده‌سازی از صفر

مرحله 1: مولد

یک مولد کوچک DCGAN که نویز 64-بُعدی را دریافت کرده و تصویری با ابعاد 32x32 تولید می‌کند.

import torch
import torch.nn as nn

class Generator(nn.Module):
    def __init__(self, z_dim=64, img_channels=3, feat=64):
        super().__init__()
        self.net = nn.Sequential(
            nn.ConvTranspose2d(z_dim, feat * 4, kernel_size=4, stride=1, padding=0, bias=False),
            nn.BatchNorm2d(feat * 4),
            nn.ReLU(inplace=True),
            nn.ConvTranspose2d(feat * 4, feat * 2, kernel_size=4, stride=2, padding=1, bias=False),
            nn.BatchNorm2d(feat * 2),
            nn.ReLU(inplace=True),
            nn.ConvTranspose2d(feat * 2, feat, kernel_size=4, stride=2, padding=1, bias=False),
            nn.BatchNorm2d(feat),
            nn.ReLU(inplace=True),
            nn.ConvTranspose2d(feat, img_channels, kernel_size=4, stride=2, padding=1, bias=False),
            nn.Tanh(),
        )

    def forward(self, z):
        return self.net(z.view(z.size(0), -1, 1, 1))

چهار لایه کانولوشن ترانهاده (transposed conv) که هرکدام با kernel_size=4, stride=2, padding=1 ابعاد فضایی را دقیقاً دو برابر می‌کنند. خروجی با تابع tanh در بازه [-1, 1] مقیاس‌بندی می‌شود.

مرحله 2: تفکیک‌کننده

قرینه مولد: با لایه‌های LeakyReLU، کانولوشن‌های گام‌دار، و یک لاجیت اسکالر در انتها.

class Discriminator(nn.Module):
    def __init__(self, img_channels=3, feat=64):
        super().__init__()
        self.net = nn.Sequential(
            nn.Conv2d(img_channels, feat, kernel_size=4, stride=2, padding=1),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Conv2d(feat, feat * 2, kernel_size=4, stride=2, padding=1, bias=False),
            nn.BatchNorm2d(feat * 2),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Conv2d(feat * 2, feat * 4, kernel_size=4, stride=2, padding=1, bias=False),
            nn.BatchNorm2d(feat * 4),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Conv2d(feat * 4, 1, kernel_size=4, stride=1, padding=0),
        )

    def forward(self, x):
        return self.net(x).view(-1)

آخرین کانولوشن، نقشه ویژگی 4x4 را به 1x1 فشرده می‌کند. خروجی به ازای هر تصویر یک اسکالر است؛ تابع سیگموئید را فقط هنگام محاسبه تابع زیان اعمال کنید.

مرحله 3: گام آموزش

به‌صورت متناوب: در هر بچ (batch)، ابتدا یک بار D و سپس یک بار G را به‌روزرسانی کنید.

import torch.nn.functional as F

def train_step(G, D, real, z, opt_g, opt_d, device):
    real = real.to(device)
    bs = real.size(0)

    # D step
    opt_d.zero_grad()
    d_real = D(real)
    d_fake = D(G(z).detach())
    loss_d = (F.binary_cross_entropy_with_logits(d_real, torch.ones_like(d_real))
              + F.binary_cross_entropy_with_logits(d_fake, torch.zeros_like(d_fake)))
    loss_d.backward()
    opt_d.step()

    # G step
    opt_g.zero_grad()
    d_fake = D(G(z))
    loss_g = F.binary_cross_entropy_with_logits(d_fake, torch.ones_like(d_fake))
    loss_g.backward()
    opt_g.step()

    return loss_d.item(), loss_g.item()

استفاده از G(z).detach() در مرحله تفکیک‌کننده حیاتی است: نمی‌خواهیم گرادیان‌ها در طول این به‌روزرسانی وارد G شوند. فراموش کردن این نکته باگ کلاسیک تازه‌کارهاست.

مرحله 4: حلقه کامل آموزش روی اشکال هندسی ساختگی

from torch.utils.data import DataLoader, TensorDataset
import numpy as np

def synthetic_images(num=2000, size=32, seed=0):
    rng = np.random.default_rng(seed)
    imgs = np.zeros((num, 3, size, size), dtype=np.float32) - 1.0
    for i in range(num):
        r = rng.uniform(6, 12)
        cx, cy = rng.uniform(r, size - r, size=2)
        yy, xx = np.meshgrid(np.arange(size), np.arange(size), indexing="ij")
        mask = (xx - cx) ** 2 + (yy - cy) ** 2 < r ** 2
        color = rng.uniform(-0.5, 1.0, size=3)
        for c in range(3):
            imgs[i, c][mask] = color[c]
    return torch.from_numpy(imgs)

device = "cuda" if torch.cuda.is_available() else "cpu"
data = synthetic_images()
loader = DataLoader(TensorDataset(data), batch_size=64, shuffle=True)

G = Generator(z_dim=64, img_channels=3, feat=32).to(device)
D = Discriminator(img_channels=3, feat=32).to(device)
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))

for epoch in range(10):
    for (batch,) in loader:
        z = torch.randn(batch.size(0), 64, device=device)
        ld, lg = train_step(G, D, batch, z, opt_g, opt_d, device)
    print(f"epoch {epoch}  D {ld:.3f}  G {lg:.3f}")

تنظیمات Adam(lr=2e-4, betas=(0.5, 0.999)) پیش‌فرض کلاسیک DCGAN است؛ پایین بودن پارامتر beta1 جلوی تثبیت بیش از حد تکانه (momentum) را در این بازی رقابتی می‌گیرد.

مرحله 5: نمونه‌برداری

@torch.no_grad()
def sample(G, n=16, z_dim=64, device="cpu"):
    G.eval()
    z = torch.randn(n, z_dim, device=device)
    imgs = G(z)
    imgs = (imgs + 1) / 2
    return imgs.clamp(0, 1)

همیشه قبل از نمونه‌برداری مدل را به حالت eval ببرید. این کار در DCGAN اهمیت زیادی دارد؛ چون آمار تجمعی نرمال‌سازی دسته‌ای را جایگزین آمارهای بچ جاری می‌کند.

مرحله 6: نرمال‌سازی طیفی

جایگزینی مستقیم برای نرمال‌سازی دسته‌ای در تفکیک‌کننده که تضمین می‌کند شبکه 1-لیپشیتز است. این کار بیشتر موارد شکست ناشی از «برد کامل تفکیک‌کننده» را درمان می‌کند.

from torch.nn.utils import spectral_norm

def build_sn_discriminator(img_channels=3, feat=64):
    return nn.Sequential(
        spectral_norm(nn.Conv2d(img_channels, feat, 4, 2, 1)),
        nn.LeakyReLU(0.2, inplace=True),
        spectral_norm(nn.Conv2d(feat, feat * 2, 4, 2, 1)),
        nn.LeakyReLU(0.2, inplace=True),
        spectral_norm(nn.Conv2d(feat * 2, feat * 4, 4, 2, 1)),
        nn.LeakyReLU(0.2, inplace=True),
        spectral_norm(nn.Conv2d(feat * 4, 1, 4, 1, 0)),
    )

کافی است Discriminator را با build_sn_discriminator() تعویض کنید؛ در بیشتر مواقع دیگر نیازی به ترفند TTUR هم نخواهید داشت. نرم طیفی ساده‌ترین و موثرترین ارتقای پایداری است که می‌توانید اعمال کنید.

استفاده از ابزارهای واقعی

برای پروژه‌های جدیِ تولید تصویر، از وزن‌های پیش‌آموزش‌دیده استفاده کنید یا سراغ مدل‌های انتشار بروید. دو کتابخانه استاندارد در این زمینه:

  • ابزار torch_fidelity که مقادیر FID و IS را بدون نیاز به نوشتن کد ارزیابی سفارشی برای مولد شما محاسبه می‌کند.
  • مخزن pytorch-gan-zoo (قدیمی) و StudioGAN که پیاده‌سازی‌های آزموده‌شده‌ای از DCGAN، WGAN-GP، SN-GAN، StyleGAN و BigGAN دارند.

در سال 2026، GANها هنوز بهترین گزینه برای این کاربردها هستند: تولید تصویر درلحظه (تاخیر کمتر از 10 میلی‌ثانیه)، انتقال سبک (style transfer)، و تبدیل تصویر به تصویر با کنترل دقیق (مانند Pix2Pix و CycleGAN). در مقابل، مدل‌های انتشار در زمینه واقع‌گرایی تصاویر و تنظیم با پرامپت متنی دست بالاتر را دارند.

خروجی این درس

این درس دو خروجی تولید می‌کند:

  • فایل outputs/prompt-gan-training-triage.md — پرامپتی که توضیحات منحنی آموزش را تحلیل کرده و حالت شکست (فروپاشی مد، غلبه تفکیک‌کننده، نوسان) را همراه با یک راه‌حل پیشنهادیِ مشخص شناسایی می‌کند.
  • فایل outputs/skill-dcgan-scaffold.md — مهارتی که اسکلت کد یک DCGAN را بر اساس مقادیر z_dim، ابعاد هدف image_size و تعداد کانال‌های num_channels، همراه با حلقه آموزش و ذخیره‌ساز نمونه‌ها می‌سازد.

تمرین‌ها

  1. (ساده) مدل DCGAN بالا را روی مجموعه‌داده اشکال دایره‌ای ساختگی آموزش دهید و در پایان هر دور، یک شبکه 16تایی از نمونه‌ها ذخیره کنید. دایره‌های تولیدی از کدام دور شکل واضحی به خود می‌گیرند؟
  2. (متوسط) نرمال‌سازی دسته‌ای تفکیک‌کننده را با نرم طیفی جایگزین کنید. هر دو نسخه را موازی آموزش دهید. کدام مدل زودتر همگرا می‌شود؟ واریانس نتایج کدام مدل در طول سه سید (seed) مختلف کمتر است؟
  3. (سخت) یک DCGAN شرطی بسازید: برچسب کلاس را به ورودی هر دو شبکه G و D تزریق کنید (در G برچسب one-hot را به نویز بچسبانید، و در D یک کانال امبدینگ کلاس اضافه کنید). مدل را روی مجموعه‌داده ساختگی «دایره‌ها در برابر مربع‌ها» از درس 7 آموزش دهید و با نمونه‌برداری با برچسب‌های مشخص نشان دهید که شرطی‌سازی کار می‌کند.

اصطلاحات کلیدی

اصطلاح در گفت‌وگوها معنای دقیق فنی
مولد (G) «شبکه نقاش» نویز را به تصویر نگاشت می‌کند؛ آموزش می‌بیند تا تفکیک‌کننده را فریب دهد
تفکیک‌کننده (D) «منتقد» یک دسته‌بند دودویی؛ آموزش می‌بیند تا تصاویر واقعی را از تصاویر جعلی متمایز کند
مینی‌ماکس (Minimax) «بازی» کمینه‌سازی روی G و بیشینه‌سازی روی D در یک تابع زیان رقابتی؛ نقطه تعادل برابر با pG=pdatap_G = p_{\text{data}} است
زیان غیراشباع‌کننده (Non-saturating loss) «نسخه پایدار عددی» زیان G برابر با −log⁡(D(G(z)))-\log(D(G(z))) است، نه log⁡(1−D(G(z)))\log(1 - D(G(z)))؛ این فرمول مانع از بین رفتن گرادیان‌ها در ابتدای آموزش می‌شود
فروپاشی مد (Mode collapse) «مولد فقط یک چیز می‌سازد» شبکه G فقط زیرمجموعه کوچکی از تنوع توزیع داده را تولید می‌کند؛ راه‌حل: نرم طیفی، تفکیک مینی‌دسته، یا بچ بزرگ‌تر
قاعده TTUR «دو نرخ یادگیری متفاوت» آموزش سریع‌ترِ D نسبت به G (معمولاً 2 تا 4 برابر) که باعث پایداری روند آموزش می‌شود
نرم طیفی (Spectral norm) «لایه 1-لیپشیتز» یک تکنیک نرمال‌سازی وزن‌ها که ثابت لیپشیتز هر لایه را محدود می‌کند و مانع از شیب‌های تند و بی‌رویه در D می‌شود
معیار FID «فاصله فرشه اینسپشن» فاصله بین توزیع ویژگی‌های Inception-v3 برای داده‌های واقعی و تولیدی؛ معیار استاندارد ارزیابی مدل‌ها

برای مطالعه‌ی بیشتر

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درسچرا در آموزش GAN به‌جای log(1 - D(G(z))) از تابع زیان (loss) اشباع‌ناپذیر مولد یعنی ‎-log(D(G(z)))‎ استفاده می‌شود؟
  2. پیش از درسدستورالعمل DCGAN توصیه می‌کند به‌جای pooling از کانولوشن‌های گام‌دار (strided convolutions) استفاده شود. چرا؟
  3. پس از درسیک GAN را آموزش می‌دهید و متوجه می‌شوید که G صرف‌نظر از نویز ورودی، نمونه‌های تقریباً یکسانی تولید می‌کند. این چه نوع شکستی است؟
  4. پس از درسچرا اسکریپت‌های آموزش DCGAN از بهینه‌ساز Adam با betas=(0.5, 0.999) به‌جای پیش‌فرض (0.9, 0.999) استفاده می‌کنند؟
  5. پس از درسهمکاری گزارش می‌دهد که تابع زیان (loss) شبکه D نزدیک صفر است و تابع زیان G در طول آموزش افزایش می‌یابد. چه اتفاقی رخ داده و چگونه آن را برطرف می‌کنید؟

سؤالات متداول

چرا در ابتدای آموزش GAN از تابع زیان غیراشباع‌کننده استفاده می‌شود؟

در آغاز آموزش چون تفکیک‌کننده تصاویر جعلی را فوراً تشخیص می‌دهد، گرادیان فرمول اولیه به سمت صفر میل می‌کند و مولد چیزی یاد نمی‌گیرد. با معکوس کردن هدف مولد، گرادیان‌های غنی و بزرگی در مراحل ابتدایی فراهم می‌شود.

فروپاشی مُد (Mode Collapse) چیست و چگونه برطرف می‌شود؟

حالتی است که مولد تنها یک یا چند تصویر تکراریِ گول‌زننده می‌سازد و تنوع توزیع داده را نادیده می‌گیرد؛ این مشکل با نرمال‌سازی طیفی، تفکیک مینی‌دسته یا شرطی‌سازی داده‌ها کنترل می‌شود.

چرا نرمال‌سازی طیفی (Spectral Normalization) در تفکیک‌کننده اهمیت دارد؟

نرمال‌سازی طیفی با محدود کردن ثابت لیپشیتز لایه‌ها مانع از رشد بیش از حد قدرت تفکیک‌کننده نسبت به مولد شده و از پدیده محو شدن گرادیان‌ها جلوگیری می‌کند.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.