Загружаем научный разбор
Подготавливаем текст, источники и редакционные примечания без изменения разметки страницы.
Подготавливаем текст, источники и редакционные примечания без изменения разметки страницы.
Автор: Казачкин Даниил Михайлович · Обновлено
Исследование DDPM и собственный одномерный опыт: зашумление, оценка шума, обратные шаги и различие условного среднего и нового образца.
Если известен добавленный шум, его можно вычесть. Но генератор изображений начинает со случайного массива, для которого нет скрытого «правильного оригинала». Значит, объяснение диффузии как обычной очистки испорченной фотографии пропускает главный вопрос: откуда берётся направление изменения, когда исходного изображения вообще не существует?
Базовая карта генераторов есть в [уроке о мультимодальности](/lessons/without-university/generative-ai-foundations/generative-ai-11). Здесь исследуем вероятностную постановку DDPM и проведём маленький эксперимент с двумя возможными значениями вместо изображений. В такой модели распределение известно точно, поэтому можно отделить арифметику обратных шагов от задачи обучения нейросети.
Работа Jonathan Ho, Ajay N. Jain и Pieter Abbeel, опубликованная на NeurIPS 2020, исследует обучение обратной цепочки для постепенного зашумления данных. Авторы используют параметризацию через предсказание шума и сравнивают варианты цели обучения; упрощённая цель связана с denoising score matching. Для безусловной генерации CIFAR-10 сообщается FID 3,17. Это показатель конкретного эксперимента с данным набором и протоколом, не вероятность правильности отдельного изображения. Публикация NeurIPS.
DDPM не означает, что шум содержит зашифрованную копию будущей картинки. Информация о характерных данных находится в обученных параметрах обратного процесса. При новом запуске случайность помогает выбрать конкретный результат из освоенного распределения. Чтобы понять это утверждение, достаточно рассмотреть ситуацию с двумя возможными ответами.
Обозначим долю сохраняемого сигнала на шаге через alpha = 1 - beta, а произведение этих долей до момента t через alpha_bar[t]. Зашумлённый пример имеет вид x_t = sqrt(alpha_bar[t]) * x_0 + sqrt(1 - alpha_bar[t]) * epsilon, где epsilon — стандартный нормальный шум. Формулы прямого распределения, цели предсказания шума и среднего обратного перехода приведены в авторской версии, разделы 2–3.
Из этой записи следует собственная простая проверка: если известны x_0 и epsilon, x_t вычисляется без прохождения всех промежуточных шагов. Именно поэтому для одного обучающего примера можно выбрать случайный t. Но при генерации x_0 неизвестен. Сеть получает текущий массив и номер шага и оценивает шум по закономерностям обучающих данных, а не извлекает сохранённое рядом секретное значение.
Возьмём данные, которые с равными вероятностями равны −2 или +2. После зашумления наблюдаемое x_t может подходить обоим исходам. По формуле Байеса условное среднее исходного значения равно 2 * tanh(2 * sqrt(alpha_bar[t]) * x_t / (1 - alpha_bar[t])). При x_t = 0 оно равно нулю. Однако ноль отсутствует в исходном распределении: средний ответ на неоднозначный вопрос не обязан быть возможным объектом.
Следующий код использует выведенное условное среднее вместо нейросети. Это аналитический предсказатель для нашего искусственного распределения, не обучение DDPM и не реализация генератора картинок. Нужен только Python 3 со стандартной библиотекой. Число шагов и постоянный beta выбраны для демонстрации, а не взяты из эксперимента статьи.
import math
import random
rng = random.Random(29)
beta = 0.02
steps = 400
alpha = 1.0 - beta
alpha_bar = [alpha ** t for t in range(steps + 1)]
def conditional_original(x, t):
retained = alpha_bar[t]
return 2.0 * math.tanh(2.0 * math.sqrt(retained) * x / (1.0 - retained))
def predict_noise(x, t):
retained = alpha_bar[t]
return (x - math.sqrt(retained) * conditional_original(x, t)) / math.sqrt(1.0 - retained)
def sample():
x = rng.gauss(0.0, 1.0)
for t in range(steps, 0, -1):
estimate = predict_noise(x, t)
mean = (x - beta * estimate / math.sqrt(1.0 - alpha_bar[t])) / math.sqrt(alpha)
variance = beta * (1.0 - alpha_bar[t - 1]) / (1.0 - alpha_bar[t])
x = mean + math.sqrt(variance) * rng.gauss(0.0, 1.0) if t > 1 else mean
return x
assert conditional_original(0.0, 100) == 0.0
assert alpha_bar[-1] < 0.001 # На старте обратной цепочки сигнал почти исчез.
samples = [sample() for _ in range(2000)]
positive_fraction = sum(x > 0 for x in samples) / len(samples)
mean_distance = sum(abs(abs(x) - 2.0) for x in samples) / len(samples)
assert 0.45 < positive_fraction < 0.55
assert mean_distance < 0.05
# Если предсказывать нулевой шум, средние шаги только усиливают начальное x.
wrong = 1.0
for _ in range(steps):
wrong /= math.sqrt(alpha)
assert wrong > 10.0
print(round(positive_fraction, 3), round(mean_distance, 6))С фиксированным seed ожидается доля положительных результатов около 0.496 и расстояние до ближайшего из значений −2/+2, округляющееся до нуля. Допуски проверяют смысл результата и не требуют одинаковых последних битов на всех платформах. Около половины результатов попадает в каждую область, хотя условное среднее при нулевом наблюдении равно нулю. Цепочка позволяет развить неоднозначность в конкретный вариант.
Обратите внимание на последний шаг: дополнительный шум там не добавляется. В выбранной формуле дисперсия этого шага также равна нулю. Во всех остальных шагах случайная добавка и предсказанное среднее играют разные роли. Просто прибавлять случайный шум к x без обученного или аналитического направления недостаточно. Контроль wrong показывает ещё одну ошибку: нулевой предсказатель вместе с коэффициентами обратной формулы лишь усиливает начальный сигнал.
Мы проверили, что конкретная цепочка с известным условным средним возвращает две области искусственного распределения и примерно сохраняет их равные частоты. Мы не доказали сходимость для всех расписаний, не измерили качество нейросети и не воспроизвели FID из статьи. Гауссов переход — часть выбранного DDPM приближения обратной динамики; знание условного среднего не делает конечную цепочку универсально точной для любого числа шагов.
Для обучения вместо функции predict_noise потребовалась бы параметрическая модель. В каждом примере известен добавленный epsilon, поэтому можно измерить ошибку его предсказания. Но малой средней ошибки на обучающих примерах недостаточно для вывода о качестве генерации: нужно получить независимую выборку результатов и оценить её распределение. В нашем опыте это два отдельных измерения — доля знаков и расстояние до допустимых значений.
Этот разрез помогает диагностировать и более сложные случаи. Если все результаты находятся около +2, качество отдельного объекта выглядит хорошим, но половина распределения потеряна. Если знаки сбалансированы, а значения лежат около −20 и +20, разнообразие не исправляет неверный масштаб. Одно число без понимания измеряемого свойства может скрыть оба дефекта.
В авторских материалах есть эксперименты с изображениями, интерполяцией и постепенным восстановлением, а также исходная реализация. Они относятся к модели и среде того исследования. У современных генераторов могут различаться пространство данных, условие по тексту, параметризация и sampler; внешнее сходство процесса не означает, что к ним применимы все настройки DDPM 2020 года.
При сравнении двух генераторов фиксируйте число выборок, вычислительный бюджет и правила подготовки данных. При сравнении двух sampler одной модели дополнительно сохраняйте веса и условия генерации. Иначе улучшение можно ошибочно приписать новому алгоритму шагов, хотя фактически поменялась сама модель. Это наш протокол чтения и постановки эксперимента, а не дополнительный результат исходной статьи.
Задание: сократите steps до 20 и сначала объясните, почему проверка остаточного сигнала перестала проходить. Затем подберите новое расписание и заново измерьте обе метрики. Не убирайте проверку ради успешного запуска: она выявляет несогласованность между конечным прямым распределением и стандартным нормальным распределением, с которого начинается генерация.
Самостоятельный русскоязычный разбор ЯдроКода. Результаты исследований отделены от авторских учебных данных, вычислительных опытов и выводов. Материал не является переводом или перепечаткой.
Учебные данные, расчёты и программные примеры созданы для этой публикации. Изображения, таблицы и программный код первоисточников не воспроизводятся.