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

Дифузійні моделі: як із чистого шуму постає зображення

Прямий процес додавання шуму, мережа, що оцінює шум, DDPM і DDIM, написані з нуля, вісім кластерів без колапсу мод, скільки кроків семплювання потрібно, порівняння з VAE і GAN на цифрах і шлях до зображень за текстом.

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

Серія Основи ШІ Частина 46 з 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): нові зображення з неперервного латентного простору

Stable Diffusion, Midjourney, DALL·E 3 і моделі, що генерують відео, стоять на одній ідеї, і вона напрочуд проста. Зіпсувати зображення легко — досить поступово додавати до нього шум, доки не лишиться сам шум. Якби ми навчилися кожен маленький крок скасовувати, могли б почати з чистого шуму й крок за кроком вилущити з нього зображення. У цій частині ми запрограмуємо це з нуля й порівняємо з VAE і GAN на тих самих даних.

Спирається на частини Генеративні змагальні мережі та Варіаційні автокодувальники.

1. Прямий процес: зображення розчиняється в шумі

Означення — прямий (дифузійний) процес

Обирають кількість кроків T і розклад малих дисперсій β1, …, βT. На кожному кроці додається трохи шуму: xt = √(1 − βt) · xt−1 + √βt · ε, ε ~ N(0, I). Композиція кроків дає замкнений вигляд xt = √ᾱt · x0 + √(1 − ᾱt) · ε, де ᾱt = ∏s ≤ t (1 − βs). Для досить великого t маємо ᾱt ≈ 0, і xt — чистий шум.

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

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

xt = √ᾱt · x0 + √(1 − ᾱt) · ε

xt
зашумлене зображення на кроці t — саме те, що мережа отримує на вхід під час навчання
√ᾱt
скільки лишилося від початкового зображення; ᾱt — добуток усіх (1 − βs) до кроку t, тож з кожним кроком він спадає
x0
початкове зображення з даних
√(1 − ᾱt)
скільки там шуму; корені потрібні тому, що додаються дисперсії: (√ᾱ)² + (√(1 − ᾱ))² = 1, тож дані з дисперсією 1 мають дисперсію 1 на кожному кроці й наприкінці плавно переходять у N(0, I)
ε
один зразок шуму з N(0, I) — саме його мережа вгадуватиме; те, що ми його знаємо, робить із навчання звичайну регресію
Теорема — чому досить одного стрибка

Якщо xt−1 = √ᾱt−1 x0 + √(1 − ᾱt−1) ε′ з ε′ ~ N(0, I), то й xt = √ᾱt x0 + √(1 − ᾱt) ε з новим ε ~ N(0, I).

Доведення. Підставимо в один крок: xt = √(1 − βt) √ᾱt−1 x0 + √(1 − βt) √(1 − ᾱt−1) ε′ + √βt ε″. Перший доданок дорівнює √ᾱt x0, бо ᾱt = (1 − βt) ᾱt−1. Решта два — незалежні нормальні шуми із середнім 0; їхня сума знову нормальна, а дисперсії додаються: (1 − βt)(1 − ᾱt−1) + βt = 1 − (1 − βt) ᾱt−1 = 1 − ᾱt. Для t = 1 твердження справджується безпосередньо (ᾱ0 = 1), далі за індукцією. ∎

Приклад — наш розклад шуму в числах

β зростає лінійно: βt = β1 + (βT − β1) · (t − 1)/(T − 1), тобто на 0,00101 за крок.

tβtᾱt√ᾱt (сигнал)√(1 − ᾱt) (шум)
10,000100,99991,0000,010
20,001110,99880,9990,035
250,024320,73510,8570,515
370,036430,50450,7100,704
380,037440,48560,6970,717
500,049550,28300,5320,847
1000,100000,00560,0750,997

Другий рядок перевіримо вручну: ᾱ2 = (1 − β1)(1 − β2) = 0,9999 · 0,99889 = 0,99879. Сигнал і шум зрівнюються (ᾱ = 0,5) між кроками 37 і 38; на кроці 100 початкове зображення має вагу лише 0,075 проти 0,997 у шуму.

У нас T = 100, а β зростає лінійно від 0,0001 до 0,1. Частка початкового сигналу √ᾱt на кроці 25 становить 0,86, на кроці 50 — 0,53, а на кроці 100 — уже лише 0,07.

Трійка в прямому процесі (зліва t = 0, 10, 25, 50, 75, 100)

2. Зворотний процес: мережа, що вгадує шум

Означення — DDPM (denoising diffusion probabilistic model)

DDPM (Джонатан Го, Аджай Джейн і Пітер Аббіл, 2020; ідея Яші Золь-Дікштайна та ін., 2015) навчає мережу εθ(xt, t) за зашумленим зображенням і номером кроку оцінити, який шум ε було додано. Функція втрат — звичайна середньоквадратична похибка E ‖ε − εθ(√ᾱt x0 + √(1 − ᾱt) ε, t)‖² з випадковим t. Семплюють від xT ~ N(0, I) назад: xt−1 = (xt − βt/√(1 − ᾱt) · εθ) / √(1 − βt) + √βt · z.

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

Мережа отримує розмите, зашумлене фото й запитання «скільки в ньому шуму і який він?». Якщо вона вміє його оцінити, то вміє його й трохи відняти. Повторюємо це сто разів, щоразу з дрібкою свіжої випадковості, — і з шуму виринає зображення. Навчання при цьому — звичайна регресія: жодного суперника, як у GAN, жодних компромісів, як у VAE.

L(θ) = Ex0, t, ε ‖ε − εθ(√ᾱt x0 + √(1 − ᾱt) ε, t)‖²

ε
шум, який ми самі додали до зображення, — правильна відповідь, тому ми її знаємо без жодного розмічування даних
εθ(…, t)
оцінка шуму мережею; вона отримує й номер кроку t, бо при t = 2 їй треба знайти мало шуму, а при t = 100 в xt майже сам шум
√ᾱt x0 + √(1 − ᾱt) ε
зашумлене зображення xt, отримане одним стрибком, — завдяки замкненій формулі для кожного прикладу досить випадково вибрати t та ε, нічого не моделюється крок за кроком
Математичне сподівання береться за зображеннями з даних, рівномірно вибраним кроком t ∈ {1, …, T} і шумом ε ~ N(0, I); на практиці це середнє за пакетом. Го та ін. отримали цю просту функцію втрат, спростивши варіаційну нижню межу (ту саму, яку оптимізує й VAE), — вони відкинули в ній ваги окремих кроків.

xt−1 = 1/√(1 − βt) · (xt − βt/√(1 − ᾱt) · εθ(xt, t)) + √βt · z

xt
поточний зашумлений стан — починаємо з чистого шуму xT ~ N(0, I)
εθ(xt, t)
оцінка шуму, який є в xt
βt/√(1 − ᾱt)
яку частину оціненого шуму відняти — лише частку, що припадає на один крок (βt), перераховану на загальний рівень шуму √(1 − ᾱt); у нас 0,01 на кроці 1 і 0,10 на кроці 100
1/√(1 − βt)
скасовує зменшення з прямого кроку (там множили на √(1 − βt)); на кроці 100 це 1,054
√βt · z
свіжий шум z ~ N(0, I) (на останньому кроці z = 0) — зворотний процес випадковий, як і прямий; без нього зразки стягувалися б до усереднених зображень. Величина √βt — один із двох варіантів, які пробували Го та ін.
Дужка, помножена на перший множник, — це оцінка середнього зображення, на один крок менш зашумленого; потім до нього додається стільки випадковості, скільки належить цьому крокові.
# навчання (DDPM)
повторюй 16 000×:
    для кожного з 64 прикладів пакета:
        x₀ = випадковий приклад з даних
        t  = випадково з 1 … 100
        ε  = вектор випадкових чисел з N(0, 1)
        x_t = √ᾱ_t · x₀ + √(1 − ᾱ_t) · ε
        похибка = ‖ε − ε_θ(x_t, код(t))‖² / розмірність
    крок Adam за середньою похибкою

# семплювання (DDPM, 100 кроків)
x = вектор з N(0, 1)
для t = 100, 99, …, 1:
    ε̂ = ε_θ(x, код(t))
    z = вектор з N(0, 1), на кроці t = 1 нуль
    x = (x − β_t / √(1 − ᾱ_t) · ε̂) / √(1 − β_t) + √β_t · z
поверни x
Означення — синусоїдальне кодування часу

Мережа не отримує число t напряму, а вісім чисел код(t) = (sin(fπt/T), cos(fπt/T)) для f = 1, 2, 4, 8. Повільні частоти кажуть «приблизно де в процесі ми є», швидкі розрізняють сусідні кроки; усі числа лежать між −1 і 1, тож жоден вхід не переважує інших.

Для t = 25 (чверть процесу, кути π/4, π/2, π і 2π): код(25) = (0,707; 0,707; 1,000; 0,000; 0,000; −1,000; 0,000; 1,000).

Наша мережа — звичайна багатошарова мережа з частини про GAN: на вході xt і вісім чисел синусоїдального кодування часу t (як позиційне кодування в трансформері), на виході оцінка шуму. На колі вона має два приховані шари по 64 нейрони, на цифрах — по 128. Навчається методом Adam 16 000 кроків.

3. Вісім кластерів без колапсу

Ті самі дані, що й у попередній частині: вісім кластерів на колі. Ось як виглядають 400 зразків під час зворотного процесу:

t = 100 t = 50 t = 25 t = 10 t = 0 координата x₁ (без одиниць) x₂ (без одиниць)
Зворотний процес: від шуму (t = 100) до даних (t = 0)

Ще на кроці 25 точки розкидані майже рівномірно (якість 3 %), на кроці 10 вимальовується коло, а за останні десять кроків точки збігаються в кластери. Наприкінці покрито всі 8 кластерів, і кожен отримав від 28 до 50 з 500 зразків. Якість (частка в межах 3σ від центру) становить 63 %.

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

4. Скільки кроків потрібно

Означення — DDIM

DDIM (Цзямін Сун, Ченьлінь Мен і Стефано Ермон, 2020) використовує ту саму навчену мережу, але семплює детерміновано й більшими стрибками: з оцінки шуму обчислює оцінку чистого зображення x̂0 = (xt − √(1 − ᾱt) εθ) / √ᾱt і з неї одразу xs = √ᾱs x̂0 + √(1 − ᾱs) εθ для будь-якого попереднього часу s < t.

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

Замість сотні дрібних кроків робимо двадцять більших. На кожному мережа питає «як, певно, виглядало б готове зображення?» і відповідно до цього стрибає на частину шляху. Коли стрибки надто великі, мережа не влучає.

xs = √ᾱs · x̂0 + √(1 − ᾱs) · εθ(xt, t),   x̂0 = (xt − √(1 − ᾱt) εθ) / √ᾱt

xt
стан, у якому ми саме перебуваємо
εθ
оцінка шуму — та сама мережа, що й у DDPM, нічого не перенавчається
x̂0
оцінка готового зображення: замкнена формула прямого процесу, розв’язана відносно x0; ділиться на √ᾱt, яке на початку мале, тож саме тут оцінка найменш точна
√ᾱs
скільки зображення має бути в цільовий час s — той самий множник, що й у прямому процесі, лише для іншого часу
√(1 − ᾱs)
скільки шуму має лишитися; DDIM при цьому використовує той самий оцінений шум і нового не вибирає — тому він детермінований
Крок — це «знешум повністю, а потім знову зашум до рівня часу s». Тому DDIM може стрибнути як завгодно далеко.
Приклад — чому двох кроків замало (спрощено)

DDIM з n кроками йде рівномірно розподіленими моментами часу: з 5 кроками 100 → 80 → 60 → 40 → 20 → 0, з 2 кроками 100 → 50 → 0. Перший стрибок завжди з t = 100, де √ᾱ100 = 0,075.

Якщо мережа помилиться в оцінці шуму на δ, оцінка x̂0 помилиться на δ · √(1 − ᾱ100)/√ᾱ100 = 13,3 δ — похибка підсилюється більш ніж удесятеро. Після підстановки в стрибок до часу s новий стан відрізняється від правильного на δ · (√(1 − ᾱs) − √ᾱs · 13,3):

  • 5 кроків, стрибок 100 → 80: множник −1,59,
  • 2 кроки, стрибок 100 → 50: множник −6,23,

За малого стрибка хибна оцінка x̂0 домішується з малою вагою √ᾱ80 = 0,19, і наступні кроки її виправляють. За стрибка до середини процесу вона входить з вагою √ᾱ50 = 0,53, і лишається єдиний крок. Міркування стежить лише за однією похибкою на одному кроці й припускає, що в решті мережа оцінює точно; проте воно показує, чому перші, найбільш зашумлені кроки найчутливіші.

0 %25 %50 %75 %100 % 63 · 8/8 100 79 · 8/8 50 77 · 8/8 20 70 · 8/8 10 60 · 8/8 5 0 · 0/8 2 кроки семплювання (кількість) якість (% зразків у межах 3σ)
Якість і покриття на колі залежно від кількості кроків семплювання DDPM (100 кроків) DDIM найкращий запуск GAN

DDIM з 50 кроками досягає якості 79 % — більше, ніж DDPM зі 100 кроками (63 %), найімовірніше тому, що не додає випадкового шуму, який наша неточна мережа не встигає прибрати на останніх кроках. Навіть з 10 кроками це 70 %, з 5 кроками 60 %. При 2 кроках семплювання розвалюється (0 %). Кількість кроків — головна ціна дифузії: кожен крок — це один прохід мережею, тоді як GAN генерує зображення за один прохід.

5. Цифри: порівняння трьох генераторів

На цифрах 8 × 8 (пікселі переведені в діапазон від −1 до 1) мережа навчається 16 000 кроків.

дифузія GAN, сід 2 VAE
Перші десять зразків
модельвідстань до найближчої цифринайменш представлена цифра (з 200)цифр із менш ніж 10 зразками
VAE (k = 8)0,054100
GAN, сід 10,04933
GAN, сід 20,04206
дифузія (100 кроків)0,063120

Тут треба бути чесними: наша дифузія має відстань 0,063, гірше, ніж VAE (0,054) і GAN (0,042). На зображеннях видно залишковий шум. Зате цифри представлені рівномірно — найрідша цифра має 12 зразків, тоді як у GAN із сідом 2 дві цифри відсутні зовсім.

Чому чіткість гірша? Мала багатошарова мережа мусить знешумлювати зображення на всіх ста рівнях шуму водночас, а це складніше завдання, ніж одне відображення шум → зображення в GAN. Зате вона чесно покращується з обчисленнями: відстань зразків спадала під час навчання 0,096 (крок 4 000), 0,082 (крок 8 000), 0,068 (крок 12 000), 0,063 (крок 16 000) (швидка оцінка зі 100 зразків DDIM з 20 кроками). Жодного колапсу чи коливань. Справжні дифузійні моделі використовують згорткові мережі U-Net або трансформери із сотнями мільйонів параметрів і навчаються тижнями — і тоді виграють і в чіткості.

6. Від цифр до зображень за текстом

  • Умова. Мережа εθ(xt, t, c) отримує ще й опис c — ембединг тексту з мовної моделі, під’єднаний через увагу (частина про увагу). Навчається на мільярдах пар зображення–підпис.
  • Керування без класифікатора (classifier-free guidance, Джонатан Го і Тім Салиманс, 2021). Мережа навчається з описом і без нього, а під час семплювання оцінку зсувають у напрямку «з описом мінус без опису», підсиленому коефіцієнтом. Зображення тоді краще відповідає запиту ціною меншої різноманітності.
  • Латентна дифузія. Дифузія працює в малому латентному просторі автокодувальника, а не в пікселях — див. частину про VAE. Завдяки цьому Stable Diffusion (2022) працює навіть на ігровій відеокарті.
  • Менше кроків. Кращі семплери й дистиляція (мережа вчиться імітувати багато кроків за один чи кілька) скоротили генерування із сотень кроків до одиниць.

ε̃ = εθ(xt, t, ∅) + w · (εθ(xt, t, c) − εθ(xt, t, ∅))

εθ(…, ∅)
оцінка шуму без опису (порожня умова ∅) — «як виглядає будь-яке зображення»; мережа вчиться її тим, що під час навчання опис час від часу випадково відкидається
εθ(…, c) − εθ(…, ∅)
на скільки зміниться оцінка, коли мережа знає опис, — напрямок, у якому опис тягне зображення
w
сила керування: w = 0 ігнорує опис, w = 1 — звичайна умовна модель, w > 1 перебільшує вплив опису — зображення краще відповідає запиту, але зразки схожіші один на одного
Під час семплювання ε̃ підставляють замість εθ; ціна — два проходи мережею на крок. Го і Салиманс записують ту саму формулу як (1 + w′) εθ(…, c) − w′ εθ(…, ∅), тобто w = 1 + w′. Бібліотека diffusers має для Stable Diffusion типове значення w = 7,5.

7. Підсумок

  • Прямий процес поступово додає шум; до будь-якого кроку можна стрибнути формулою √ᾱ x₀ + √(1 − ᾱ) ε.
  • Мережа вчиться оцінювати доданий шум — звичайна регресія. Генерують назад від чистого шуму.
  • На восьми кластерах дифузія покрила всі в єдиному запуску (DDIM з 50 кроками 79 %); GAN — лише в одному з чотирьох запусків.
  • Менше кроків (DDIM) пришвидшує семплювання; з 10 кроками якість 70 %, з 2 кроками воно розвалюється.
  • На цифрах дифузія покриває всі цифри, за чіткістю з нашою малою мережею відстає; проте стабільно покращується з обчисленнями.

Хочете спробувати самі? Попросіть ШІ-агента навчити малу DDPM на двовимірних даних (скажімо, точках у формі ваших ініціалів) і намалювати, як точки під час зворотного процесу складаються в літери.

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

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