Диффузия и потоки
Практика: DDPM с нуля
Обучить диффузию на MNIST, добавить DDIM и flow matching — и проверить каждое утверждение ветки
Ветка в двух формулах
Слева — урок 060, справа — урок 030. Между ними ровно одно связующее утверждение: предсказанный шум и есть score с точностью до множителя. Всё остальное в ветке — расписания, guidance, потоки — это варианты того, как выбрать путь и как по нему пройти.
Что реализовать
1. Прямой процесс и расписания
Начните с того, что не требует обучения вовсе.
- реализуйте
alpha_bar(t)для линейного и косинусного расписаний; - нарисуйте для одного изображения при ;
- посчитайте, при каком отношение сигнал/шум равно единице.
Ожидание из урока 070: для линейного и для косинусного. Если получилось иначе — ошибка в накоплении произведения, и её лучше найти сейчас, чем после суток обучения.
данные при t
сигнал/шум, log-шкала
- ᾱ
- 0.4967
- √ᾱ
- 0.7047
- √(1−ᾱ)
- 0.7095
- сигнал/шум
- 0.987
- равенство при t
- 0.259
Шум преобладает. Если ваш выбор t для отладки лежит здесь, ожидать осмысленной реконструкции не стоит.
2. Обучение
Модель — маленький U-Net на MNIST. Обязательные детали:
- подаётся как эмбеддинг, синусоидальный (блок 6, урок 110) или через SNR;
- на каждый пример один случайный и один ;
- цель — упрощённая, без весов ELBO (урок 060).
Проверка, которую стоит сделать до обучения: при случайной инициализации лосс обязан быть около единицы. Причина в том, что цель — MSE до , а необученная сеть предсказывает примерно нуль; значит ошибка равна дисперсии шума. Значение сильно другое означает ошибку в масштабировании входа.
3. Три сэмплера
Один и тот же обученный набор весов, три способа пройти обратный путь:
| сэмплер | формулировка | шагов |
|---|---|---|
| DDPM | стохастическая | |
| DDIM | детерминированная, каждый -й шаг | |
| Хойн по probability-flow ОДУ | детерминированная, второй порядок |
Из урока 030: третий имеет смысл только потому, что второй детерминированный. Проверьте это измерением — сравните качество Хойна и Эйлера при равном числе вызовов сети, а не при равном числе шагов (урок 020).
4. Пять измерений
Как и в практике блока 6, работающая генерация ничего не доказывает. Проверьте утверждения ветки на своей реализации.
Измерение 1: замкнутая форма совпадает с цепью. Прогоните цепь сто раз и сравните выборочные среднее и дисперсию с и . Ожидание — совпадение в пределах статистической ошибки. Это проверяет самый фундаментальный кирпич.
Измерение 2: score и — одно и то же. Возьмите предсказание сети, переведите его в score по , затем восстановите по формуле Tweedie. Сравните с прямым переводом . Ожидание: побитовое совпадение с точностью арифметики.
Измерение 3: DDIM детерминирован. Дважды сгенерируйте из одного и того же стартового шума. Ожидание: одинаковые изображения. У DDPM — разные. Если DDIM даёт разные, где-то остался случайный член.
Измерение 4: инверсия работает. DDIM обратим: пройдите от шума к изображению, затем обратно к шуму, и сравните с исходным шумом. Ожидание: расхождение мало и растёт при уменьшении числа шагов — это ошибка интегрирования, а не ошибка модели.
Измерение 5: guidance уменьшает разнообразие. Сгенерируйте по пятьдесят образцов при и посчитайте попарное расстояние внутри каждого набора. Ожидание из урока 080: монотонное падение. Заодно посмотрите на долю пикселей, вышедших за допустимый диапазон, — она растёт.
5. Flow matching для сравнения
Та же архитектура, другая цель:
Изменения в коде минимальны — путь и цель, — и это само по себе поучительно. Сравните число шагов, нужное для сопоставимого качества.
Ожидание из урока 090, сформулированное осторожно: путей прямее, шагов меньше, но не «один шаг». Если хотите увидеть настоящее спрямление, добавьте minibatch OT (урок 110): решите задачу назначения внутри батча и составляйте пары по ней, а не случайно.
- длина пути
- 2.702
- прямое расстояние
- 2.702
- кривизна
- ×1
- ошибка ломаной
- 0.0e+0
Прямой путь: число шагов перестаёт влиять на геометрию.
Куда смотреть, если не получается
| симптом | что проверять первым |
|---|---|
| лосс на первом шаге сильно не единица | нормировку входа, масштаб |
| сэмплы — шум | знак в обратном шаге, порядок обхода |
| сэмплы — серое пятно | подачу в сеть (модель усредняет по всем уровням шума) |
| DDIM даёт разные результаты из одного шума | оставшийся случайный член |
| сэмплы приемлемы при 1000 шагов и мусор при 50 | использование стохастической формулы вместо ОДУ |
| guidance ломает картинку при | выход за диапазон, нужна обрезка |
Третья строка — самая коварная и стоит объяснения. Если до сети не доходит (забытый эмбеддинг, потерянный аргумент), обучение не падает: сеть выучивает средний по всем шумоподавитель. Лосс при этом заметно выше оптимального, но снижается, а генерация даёт размытое нечто. Проверяется за минуту: подайте одно и то же при двух разных и убедитесь, что выход изменился.
Чем закончить
Прогоните все пять измерений на обученной модели. Особенно второе и третье: они проверяют понимание того, что предсказание шума, score и восстановление — один объект, и что детерминированное сэмплирование действительно детерминировано. Красивые картинки получаются и при ошибках; эти проверки — нет.
Источники
- Karpathy и др. — minDiffusion / annotated diffusion — Разбор DDPM по строкам, эталонная реализация нужного масштаба
- Karras и др. — Elucidating the Design Space of Diffusion-Based Generative Models — Единая система координат для расписаний, параметризаций и сэмплеров
Проверки
0 из 2Отладка диффузионной модели
Отметьте все верные утверждения о сборке и отладке диффузионной модели.
Шаг DDIM
Реализуйте
ddim_step(alpha_bar_t, alpha_bar_prev, x_t, eps)— один шаг детерминированного сэмплера. Он состоит из двух действий:- восстановить чистые данные по текущему состоянию и предсказанному шуму: ;
- заново зашумить их до предыдущего уровня тем же самым : .
Верните
[x0_hat, x_prev, delta, signal_gain]:x0_hatиx_prev— из формул выше;delta= — насколько сдвинулось состояние;signal_gain= — насколько прибавилось сигнала за шаг.
Обратите внимание: случайности здесь нет вовсе — тот же используется дважды. Именно поэтому шаг детерминирован, и именно поэтому его можно обратить.
Загрузка редактора…
Ctrl/⌘ + Enter