Перейти до вмісту
coden

Генеративні змагальні мережі (GAN): фальшувальник проти детектива

Гра генератора і дискримінатора, GAN, написаний з нуля, ненасичувана втрата, вісім кластерів на колі й колапс мод, цифри чіткіші, ніж у VAE, але не всі, і шлях від GAN до дифузійних моделей.

12 хвилин Matěj Žalmánek 2026-10-16

Серія Основи ШІ Частина 45 з 52
  1. Мапа штучного інтелекту: що є що і як усе це пов’язано
  2. Коротка історія штучного інтелекту: від Тюрінга до мовних моделей
  3. Дані, модель, тренування, інференс: основні поняття на одному прикладі
  4. Як читати математичний запис: символи, індекси, суми та квантори
  5. Множини й відношення: конструктор, з якого складаються означення в ШІ
  6. Функції й відображення: чому кожна модель у ШІ — це функція
  7. Логіка й доведення: правила, за якими міркують у ШІ
  8. Графи й дерева: структура, на якій тримаються пошук і нейронні мережі
  9. Лінійна алгебра для машинного навчання: вектори, матриці й чому ШІ передусім множить
  10. Похідні, градієнт і правило ланцюжка: як модель дізнається, у якому напрямку вчитися
  11. Градієнтний спуск: як навчається модель
  12. Що таке ймовірність: від кидка кубика до аксіом Колмогорова
  13. Умовна ймовірність і теорема Баєса: як змінити оцінку, коли дізнаєтеся щось нове
  14. Випадкова величина і функція розподілу: одна функція, яка каже про розподіл усе
  15. Функція щільності та функція маси ймовірності: чому неперервна величина має в точці ймовірність нуль
  16. Математичне сподівання, дисперсія і коваріація: де лежить розподіл, наскільки він широкий і що з чим пов’язано
  17. Огляд розподілів ймовірностей: Бернуллі, біноміальний, Пуассона, рівномірний, нормальний і експоненційний
  18. Закон великих чисел і центральна гранична теорема: чому середні поводяться так передбачувано
  19. Статистика й оцінювання параметрів: максимальна правдоподібність, MAP і довірчі інтервали
  20. Теорія інформації: ентропія, перехресна ентропія і KL-дивергенція — звідки беруться функції втрат
  21. Пошук у просторі станів: BFS, DFS, UCS і A* з анімаціями
  22. Ігри та суперник: мінімакс, альфа-бета відсікання і Monte Carlo tree search
  23. Задоволення обмежень: бектрекінг, поширення обмежень і AC-3 на судоку та мапі чеських країв
  24. Логіка й системи, засновані на знаннях: пряме і зворотне виведення, резолюція та експертні системи
  25. Планування: STRIPS, світ кубиків, евристики з релаксації та планування в AI-агентах
  26. Локальний пошук та імітація відпалу: комівояжер через обласні центри Чехії
  27. Генетичні алгоритми: популяція, схрещування, мутація і добір на рюкзаку для походу
  28. Еволюційні стратегії і генетичне програмування: від правила однієї п’ятої до закону Кеплера
  29. Оптимізація мурашиною колонією: як феромоновий слід знаходить короткий шлях
  30. Оптимізація роєм частинок: інерція, власний досвід і досвід рою
  31. Нейроеволюція: еволюція ваг і форми нейронних мереж та алгоритм NEAT
  32. Нечіткі множини й функції належності: як записати «трохи тепло»
  33. Нечітка логіка та ймовірність: чому «трохи тепло» не означає «імовірно тепло»
  34. Нечітка логіка: t-норми, імплікації та правила ЯКЩО–ТО
  35. Нечітке керування: Мамдані та Суґено від вентилятора до маятника на візку
  36. Нечітка кластеризація: алгоритм fuzzy c-means і точки між кластерами
  37. Нейро-нечіткі системи (ANFIS): нечіткі правила, які навчаються з даних
  38. Марковські ланцюги: матриця переходів, стаціонарний розподіл і PageRank
  39. Приховані марковські моделі: алгоритм Вітербі й нечесне казино
  40. Байєсівські мережі: чому трава мокра і що з цього випливає для дощувача
  41. Фільтр Калмана: як за неточними вимірюваннями оцінити, де авто і як швидко воно їде
  42. Види машинного навчання: з учителем, без учителя, з частковим залученням учителя та інші
  43. Промпти, контекст і RAG: як дати моделі правильну інформацію
  44. Варіаційні автокодувальники (VAE): нові зображення з неперервного латентного простору
  45. Генеративні змагальні мережі (GAN): фальшувальник проти детектива
  46. Дифузійні моделі: як із чистого шуму постає зображення
  47. Марковські процеси ухвалення рішень: стани, дії, винагороди й рівняння Беллмана
  48. Q-навчання і DQN: як навчитися цінності дій — від таблиці до нейронної мережі
  49. Policy gradient і PPO: навчання безпосередньо політики
  50. Як працює ШІ-агент: мовна модель у циклі з інструментами
  51. Програмування з AI-агентами: завдання, тести й перевірка
  52. Оцінювання і безпека систем ШІ: як вимірювати і як стежити

Повна програма серії Готово: 52 з 83 тем

Що ви винесете
  • Як генератор вчиться лише з градієнта дискримінатора.
  • Чому навчання GAN нестабільне і що таке колапс мод.
  • У чому GAN виграє у VAE, у чому програє і чому сьогодні їх замінила дифузія.

Що варто знати заздалегідь: Варіаційні автокодувальники (VAE): нові зображення з неперервного латентного простору, Ігри та суперник: мінімакс, альфа-бета відсікання і Monte Carlo tree search

Варіаційний автокодувальник з попередньої частини генерує чесно, але розмито. У 2014 році Ян Ґудфелло прийшов з ідеєю, яка виглядає майже як фокус: ми не міряємо, наскільки зразок відрізняється від даних, а доручаємо це оцінити іншій мережі. Дві мережі грають у гру — одна підробляє, друга розпізнає підробку, — і обидві при цьому покращуються. Так з’явилися перші згенеровані машиною обличчя, які ви не відрізните від фотографій. У цій частині ми напишемо обидві мережі з нуля і побачимо, чому їхнє навчання таке примхливе.

Спирається на частини Варіаційні автокодувальники, Логістична регресія (сигмоїда і перехресна ентропія) та Ігри та суперник.

1. Фальшувальник і детектив

Означення — генеративна змагальна мережа (GAN)

GAN (Ян Ґудфелло та ін., 2014) складається з двох мереж. Генератор G перетворює випадковий шум z ~ N(0, I) на зразок G(z). Дискримінатор D повертає ймовірність D(x), що x походить зі справжніх даних. Вони грають у гру двох гравців з нульовою сумою:

minG maxD Ex ~ data[log D(x)] + Ez[log(1 − D(G(z)))].

Для фіксованого G найкращий дискримінатор — це D*(x) = pdata(x) / (pdata(x) + pG(x)). У рівновазі G генерує точно розподіл даних, а D усюди повертає ½.

Простими словами

Фальшувальник друкує банкноти, детектив сортує їх на справжні й фальшиві. Детектив вчиться на тому, де помилився. Фальшувальник ніколи не бачив справжньої банкноти — він вчиться лише з того, що його видало детективу. Коли обидва покращуються, підробки стають дедалі кращими. Кінець гри: детектив може лише вгадувати, і вгадує навпіл.

minG maxD   Ex ~ data[ log D(x) ] + Ez ~ N(0, I)[ log(1 − D(G(z))) ]

Ex ~ data[log D(x)]
дискримінатор на справжніх даних — найбільший (0), коли D дає справжнім зразкам 1; логарифм карає самовпевнену помилку (D → 0) необмежено
Ez[log(1 − D(G(z)))]
дискримінатор на підробках — найбільший, коли дає їм 0; це єдиний член, у якому трапляється G, тож генератор вчиться лише з нього
maxD
дискримінатор значення збільшує — обидва члени разом є від’ємною бінарною перехресною ентропією, тож це звичайне навчання класифікатора «справжнє / підробка»
minG
генератор значення зменшує — хоче, щоб дискримінатор на підробках помилявся; що один гравець виграє, те другий втрачає (нульова сума)
Значення гри V(D, G); обидва математичні сподівання під час навчання оцінюються середнім по пакету.
Теорема — найкращий дискримінатор і що мінімізує генератор

Для фіксованого G значення гри дорівнює ∫ [pdata(x) log D(x) + pG(x) log(1 − D(x))] dx. У кожній точці x максимізуємо функцію a log y + b log(1 − y) для y ∈ (0, 1), де a = pdata(x), b = pG(x).

Доведення. Похідна a/y − b/(1 − y) дорівнює нулю при y = a/(a + b), а функція угнута (друга похідна −a/y² − b/(1 − y)² < 0), тож це максимум. Звідси D*(x) = pdata(x) / (pdata(x) + pG(x)). Підставивши й спростивши (Ґудфелло та ін., 2014):

V(D*, G) = −log 4 + 2 · JSD(pdata ‖ pG),   JSD(p ‖ q) = ½ KL(p ‖ m) + ½ KL(q ‖ m),   m = ½(p + q).

Дивергенція Єнсена — Шеннона невід’ємна і дорівнює нулю саме тоді, коли pG = pdata. Отже, з найкращим дискримінатором генератор мінімізує JSD, а мінімум −log 4 ≈ −1,386 досягається, коли він генерує точно дані. ∎

Приклад: там, де густина даних 0,3, а підробок 0,1, маємо D* = 0,3 / 0,4 = 0,75 (точка радше справжня); там, де генератор перестарався (дані 0,1, підробки 0,3), D* = 0,25. Там, де густини рівні, D* = ½, а втрата дискримінатора (бінарна перехресна ентропія на один зразок) дорівнює ln 2 ≈ 0,693.

Дискримінатор — звичайний класифікатор із сигмоїдою і перехресною ентропією, як логістична регресія, лише з додатковими шарами. Уся магія в генераторі: градієнт його втрати протікає зворотним поширенням крізь дискримінатор аж до зображення, а звідти у ваги генератора. Дискримінатор таким чином підказує йому, в якому напрямку зсунути кожен піксель, щоб той виглядав правдоподібніше.

2. Навчання: кроки по черзі

Навчання відбувається по черзі: крок дискримінатора (пакет справжніх даних і пакет підробок, збільшити D на справжніх, зменшити на фальшивих), потім крок генератора (зсунути підробки туди, де D вважає їх справжніми). Обидві мережі в нас мають два приховані шари з leaky ReLU і навчаються методом Adam.

Означення — ненасичувана втрата генератора

Замість мінімізації log(1 − D(G(z))) з початкової гри генератор вчиться максимізувати log D(G(z)), тобто мінімізувати −log D(G(z)). Обидві втрати мають ту саму мету, але різний градієнт: якщо D = σ(s), то |∂ log(1 − D)/∂s| = D, тоді як |∂(−log D)/∂s| = 1 − D. Її запропонували вже Ґудфелло та ін. у тій самій статті.

Простими словами

Спочатку підробки погані, і детектив легко їх викриває, D для них близьке до нуля. Початкова втрата в цей момент майже не надсилає жодного сигналу — фальшувальник не дізнається, що покращити, саме тоді, коли це найпотрібніше. Обернене запитання («як переконати детектива») дає сильний сигнал від самого початку.

∂/∂s log(1 − σ(s)) = −D,    ∂/∂s (−log σ(s)) = −(1 − D)

s
логіт — вихід дискримінатора перед сигмоїдою; диференціюємо за ним, бо звідси градієнт тече назад у дискримінатор і крізь нього в підробку
D = σ(s)
ймовірність, що підробка справжня; використовується σ′(s) = σ(s)(1 − σ(s)), тому й виходять такі прості вирази
log(1 − σ(s))
початкова втрата генератора (мінімізується) — її градієнт має величину D, тож коли дискримінатор упевнено викриває підробку (D ≈ 0), він майже нульовий: насичення
−log σ(s)
ненасичувана втрата — градієнт має величину 1 − D, тобто найбільший саме для підробок, які дискримінатор викрив
При D = 0,01 початкова втрата дає градієнт 0,01, ненасичувана — 0,99, тобто в дев’яносто дев’ять разів більше. Обидві втрати спадають, коли D зростає, тож мають ту саму мету. Кольори відповідають кривим на графіку нижче.
00,51 00,250,50,751 початок навчання D(G(z)) — ймовірність, що підробка справжня (0–1) градієнт |∂втрата/∂s| (0–1)
Сила сигналу для генератора залежно від того, наскільки дискримінатор вірить підробці початкова log(1 − D) ненасичувана −log D

Чесно кажучи, у наших невеликих експериментах навчалася й початкова втрата, бо дискримінатор на початку не був таким самовпевненим. У великих мереж на зображеннях, де дискримінатор швидко перемагає, різниця принципова. Далі використовуємо ненасичувану втрату.

Як градієнт дістається аж до генератора, показує ланцюгове правило. Підробка x = G(z) для дискримінатора — лише вхід, тож зворотне поширення не мусить на ньому зупинятися:

∂LG / ∂θG = ∂LG / ∂s · ∂s / ∂x · ∂x / ∂θG

∂LG / ∂s
одне число з втрати, для ненасичуваної −(1 − D) — «наскільки» має покращитися підробка
∂s / ∂x
градієнт дискримінатора за його входом (для кола 2 числа, для цифри 64) — «в якому напрямку» зсунути кожну координату, щоб підробка виглядала справжнішою; ваги дискримінатора на цьому кроці не змінюються
∂x / ∂θG
звичайне зворотне поширення генератором — перетворює потрібний зсув підробки на зміну ваг генератора
Генератор ніколи не бачить даних; єдина інформація про них надходить через середній член.
Означення — втрата дискримінатора і softplus

Дискримінатор повертає логіт s і D = σ(s). Для справжнього зразка з логітом sr і підробки з логітом sf його втрата — бінарна перехресна ентропія

LD = −log σ(sr) − log(1 − σ(sf)) = softplus(−sr) + softplus(sf),   softplus(u) = ln(1 + eu),

бо −log σ(s) = ln(1 + e−s) і 1 − σ(s) = σ(−s). Програма обчислює softplus через логіт, а не через D: для s = 40 значення σ(s) у числах з рухомою комою дорівнює точно 1, і log(1 − D) дало б −∞, тоді як softplus(40) ≈ 40. Градієнти: ∂LD/∂sr = σ(sr) − 1, ∂LD/∂sf = σ(sf).

for t in range(kroku):
    # 1. крок дискримінатора: справжні → 1, підробки → 0
    gD = 0
    for _ in range(davka):
        x = nahodny_vzorek(data)
        gD += D.zpet(D(x), dL_ds=sigmoid(D(x)) - 1)
        f = G(sum())                           # підробка, G зараз не вчиться
        gD += D.zpet(D(f), dL_ds=sigmoid(D(f)))
    adam_D(gD / davka)
    # 2. крок генератора: градієнт проходить крізь D аж до підробки
    gG = 0
    for _ in range(davka):
        x = G(sum())
        dL_ds = sigmoid(D(x)) - 1              # ненасичувана −log σ(s)
        dL_dx = D.zpet_do_vstupu(dL_ds)        # ваги D без змін
        gG += G.zpet(dL_dx)
    adam_G(gG / davka)                         # Adam з β₁ = 0,5, як у DCGAN

3. Вісім кластерів на колі

Класичний експеримент: дані — точки з восьми невеликих нормальних кластерів (σ = 0,05), розміщених на колі радіусом 2. Генератор отримує двовимірний шум і повертає точку на площині. Вимірюємо якість (частку зразків у межах 3σ від якогось центру) і покриття (у скільки кластерів потрапляє щонайменше 2 % зразків).

Означення — дані, якість і покриття

Центри кластерів — це cj = (r cos(2πj/8), r sin(2πj/8)) для j = 0, …, 7 з r = 2; точка даних — це cj з випадковим j плюс шум N(0, σ²I), σ = 0,05. Для зразків генератора x1, …, xn:

якість = (1/n) · #{i : minj ‖xi − cj‖ < 3σ},   покриття = #{j : nj ≥ 0,02 · n},

де nj — кількість зразків у межах 3σ від центру cj. Числа: 3σ = 0,15, сусідні центри віддалені один від одного на 2r sin(π/8) ≈ 1,53, тобто понад удесятеро далі. Знімки мають n = 400 зразків, тож кластер вважається покритим від 8 зразків.

Навіть ідеальний генератор не має якості 100 %: відстань точки від центру двовимірного нормального розподілу має розподіл Релея, і в межі 3σ потрапляє частка 1 − e−9/2 ≈ 0,989, тобто близько 98,9 %.

справжні дані крок 500 крок 2 000 крок 8 000 координата x₁ (без одиниць) x₂ (без одиниць)
Справжні дані та зразки генератора під час навчання (запуск із сідом 2)

Після 500 кроків генератор видає розмиту хмару (якість 6 %), після 2 000 кроків точки стягуються в 6 кластерів, а наприкінці (крок 8 000) покриває всі 8 з якістю 73 %. Генератор ніколи не бачив жодної справжньої точки — усе він дізнався з градієнта дискримінатора.

4. Колапс мод

Означення — колапс мод (mode collapse)

Генератор видає лише частину розподілу даних — кілька мод (кластерів, видів зображень), а решту пропускає. Втрата за це прямо не карає: дискримінатор оцінює кожен зразок окремо, і добра підробка одного виду для нього так само переконлива, як і строката колекція. За повного колапсу генератор для кожного z видає майже те саме.

Простими словами

Фальшувальник з’ясовує, що детектив найгірше розпізнає фальшиві сотні. Тож друкує лише сотні. Детектив з часом це помічає і починає підозрювати сотні — фальшувальник перескакує на двосотенні. Гра крутиться по колу, і фальшувальник ніколи не друкує всі банкноти одночасно.

Теорема — проти фіксованого дискримінатора найкраща одна-єдина точка

Для фіксованого D втрата генератора LG = Ez[−log D(G(z))] ≥ −log D(x*), де x* — точка, у якій D найбільший. Рівність досягається для генератора, який кожне z відправляє в x*.

Доведення. Для кожного z маємо D(G(z)) ≤ D(x*), а оскільки −log спадна, то −log D(G(z)) ≥ −log D(x*); математичне сподівання нерівність зберігає. ∎

Втрата — це середнє по окремих зразках, і ніщо в ній не винагороджує різноманітність. Проти фіксованого суперника повний колапс, отже, оптимальний; запобігає йому лише те, що дискримінатор реагує й починає підозрювати місце x*. Якщо генератор перескакує швидше, ніж дискримінатор забуває, гра крутиться по колу. Тому допомагають зміни, які дають дискримінатору погляд на весь пакет (minibatch discrimination, Тім Саліманс та ін., 2016), або інша відстань між розподілами (Вассерштейна, нижче).

Та сама мережа, ті самі дані, ті самі налаштування — лише інший випадковий сід:

сідпокритих кластерів після кроків 1 000 … 8 000наприкінціякість наприкінці
10 · 2 · 7 · 6 · 6 · 7 · 7 · 77 з 866 %
24 · 5 · 8 · 8 · 8 · 8 · 8 · 88 з 873 %
31 · 4 · 4 · 4 · 5 · 5 · 5 · 55 з 854 %
40 · 5 · 6 · 6 · 6 · 6 · 6 · 66 з 849 %
сід 1: 7 з 8 сід 3: 5 з 8 сід 4: 6 з 8 координата x₁ (без одиниць) x₂ (без одиниць)
Кінець навчання в інших запусках (зафарбоване кільце = покритий кластер)

Лише один із чотирьох запусків покрив усі вісім кластерів. Запуск із сідом 3 зупинився на 5 і з кроку 5 000 уже не зрушив. Це для GAN типово: навчання не має однієї втрати, яка б спадала, а є грою двох гравців, і результат залежить від випадку більше, ніж нам хотілося б.

5. Цифри: чіткіші, але не всі

Тепер ті самі цифри 8 × 8, що й у VAE. Генератор: восьмивимірний шум → 64 → 64 → 64 пікселі із сигмоїдою; дискримінатор дзеркально. 6 000 кроків, два запуски з різними сідами. Якість вимірюємо так само, як у попередній частині, — відстанню зразка до найближчої навчальної цифри.

GAN, сід 1 GAN, сід 2 VAE (попередня частина)
Перші десять зразків (код / шум з 8 вимірами)

Зразки GAN чіткіші: відстань 0,049 і 0,042 проти 0,054 у VAE (справжні цифри 0,017). GAN не карає розмитість усередненням, як втрата реконструкції VAE, — розмите зображення дискримінатор легко розпізнає. Але яких цифр і скільки генератор видає?

020406080 0 1 2 3 4 5 6 7 8 9 цифра (0–9) кількість зразків (з 200)
Скільки разів яка цифра трапляється серед 200 зразків (за найближчою навчальною цифрою) сід 1сід 2 рівномірно (20)

У даних кожної цифри порівну. Запуск із сідом 2 при цьому видає здебільшого шістки (69 з 200), вісімки і трійки, а цифри 0, 1, 2, 4, 7 майже зовсім ні (щонайбільше 3 зразки). Запуск із сідом 1 строкатіший, але й там цифри 0, 4, 9 мають менше половини своєї частки (щонайбільше 6 зразків замість 20). Це той самий колапс мод, що й на колі, лише на зображеннях: GAN виграє чіткістю, VAE — покриттям.

6. Від GAN до дифузії

  • DCGAN (Алек Редфорд та ін., 2015) показав, як будувати згорткові GAN, які можна надійно навчати на фотографіях.
  • Wasserstein GAN (Мартін Арйовскі та ін., 2017) замінив класифікатор «критиком», який вимірює відстань між розподілами; навчання стабільніше і менш схильне до колапсу мод.
  • StyleGAN (Теро Каррас та ін., Nvidia, 2018–2020) генерує фотореалістичні обличчя з роздільністю 1024 × 1024 — відомий сайт «this person does not exist».
  • Близько 2021 року GAN випередили дифузійні моделі (Прафулла Дхарівал і Алекс Ніколь: «Diffusion Models Beat GANs on Image Synthesis»). Вони повільніші, але навчаються стабільно й покривають увесь розподіл. Ідея дискримінатора, однак, живе далі — як допоміжна втрата, що додає зображенням чіткості, наприклад у кодеках зображень чи звуку.

Чому Вассерштейн допомагає, видно на найпростішому прикладі (спрощена версія прикладу зі статті Арйовскі та ін., 2017): дані — одна-єдина точка 0, генератор видає одну-єдину точку θ. Поки θ ≠ 0, розподіли не перекриваються і JSD = ln 2 ≈ 0,693 незалежно від того, наскільки далеко θ, — градієнт за θ нульовий, і генератор не знає, куди йти. Відстань Вассерштейна дорівнює |θ|, тож показує напрямок навіть здалеку.

W(pdata, pG) = sup‖f‖L ≤ 1 ( Ex ~ data[f(x)] − Ez[f(G(z))] )

sup‖f‖L ≤ 1
критик f — мережа, яка замість ймовірності повертає довільне число; умова «1-ліпшицева» (|f(a) − f(b)| ≤ ‖a − b‖) не дозволяє йому розрізняти дві близькі точки як завгодно різко, інакше різниця могла б зростати до нескінченності
Edata[f(x)]
середня оцінка справжніх даних — критик хоче, щоб вона була якомога більшою
Ez[f(G(z))]
середня оцінка підробок — критик хоче, щоб вона була якомога меншою, генератор — якомога більшою; різниця неперервна за параметрами генератора, тож градієнт не зникає, навіть коли розподіли не перекриваються
Двоїстість Канторовича — Рубінштейна: найменша «робота», потрібна, щоб перемістити масу одного розподілу на інший, дорівнює найбільшій різниці середніх по 1-ліпшицевих функціях. У прикладі вище достатньо f(x) = −x · sgn θ, і різниця дорівнює |θ|.

7. Підсумок

  • GAN = генератор і дискримінатор у грі; генератор вчиться лише з градієнта, який йому надсилає дискримінатор.
  • Ненасичувана втрата −log D(G(z)) дає генераторові сильний сигнал навіть на початку, коли дискримінатор перемагає.
  • На восьми кластерах усі покрив лише один із чотирьох запусків (7, 8, 5, 6); результат сильно залежить від випадку.
  • На цифрах зразки чіткіші, ніж у VAE (0,042 проти 0,054), але деяких цифр бракує — колапс мод.
  • Сьогодні зображення генерують здебільшого дифузійні моделі; дискримінатор залишився як помічник для чіткості.

Хочете спробувати самі? Доручіть ШІ-агенту навчити маленький GAN на восьми кластерах на колі й запустити його п’ять разів з різними сідами. Потім нехай спробує Wasserstein GAN з тією самою мережею і порівняє, скільки кластерів він щоразу покриває.

Маєте іншу думку? Напишіть на support@coden-app.com.

Агент на вашому комп’ютері, керований з телефона