Теория информации
Практика: от кросс-энтропии до VAE
Собрать блок воедино — вывести CE из MLE, ELBO на бумаге, перплексию руками, VAE на MNIST
Блок на одной странице
Шесть уроков связаны одним неравенством и одним тождеством. Стоит увидеть их вместе, прежде чем писать код.
| результат | как получается из Йенсена |
|---|---|
| KL совместного от произведения | |
| , вогнута, знак обратный |
И одно тождество, из которого выводится вся практика:
Кросс-энтропия из MLE, на бумаге
Первое упражнение — без кода. Начните с MLE и дойдите до nn.CrossEntropyLoss:
- запишите правдоподобие категориального: ;
- возьмите логарифм и минус: получится , то есть только член истинного класса;
- усредните по выборке: это для one-hot ;
- подставьте и убедитесь, что градиент равен .
Четвёртый шаг — тот, что был в блоке 2 (урок 080). Смысл упражнения в том, чтобы увидеть: «кросс-энтропия», «минус log-правдоподобие категориального» и «NLL после log_softmax» — три названия одного объекта, и в PyTorch они буквально живут в разных функциях с одним результатом.
Проверьте на виджете, что при one-hot кросс-энтропия равна и от остальных не зависит вовсе — выключите все веса , кроме одного, и подвигайте .
цель p (one-hot)
предсказание q
- H(p)
- 0 бит
- H(p, q) — лосс
- 1 бит
- KL(p‖q)
- 1 бит
- KL(q‖p)
- бесконечна
- H(q)
- 1.4855 бит
Обратите внимание, что при one-hot цели , поэтому кросс-энтропия равна KL — весь лосс оказывается «зазором». Это единственный случай, когда «минимум лосса равен нулю» действительно верно, и он же объясняет, почему label smoothing меняет картину: сделав цель не жёсткой, вы поднимаете и вместе с ним минимум лосса.
ELBO на бумаге
Второе упражнение — вывести ELBO двумя путями и убедиться, что получается одно.
Путь 1, через Йенсена. .
Путь 2, через KL. Начните с , подставьте и раскройте. Получите то же неравенство и вдобавок точное выражение для зазора.
Второй путь сильнее: он даёт не только границу, но и её погрешность. Проверьте численно на виджете — сумма ELBO и зазора не меняется, куда бы вы ни увели .
веса q(z)
- log p(x)
- -0.91629
- ELBO(q)
- -1.23909
- зазор KL
- 0.3228
Перплексия руками
Третье упражнение — считать перплексию, не пользуясь библиотекой, на игрушечном корпусе:
- возьмите текст из сотни слов, постройте биграммную модель со сглаживанием ;
- посчитайте среднюю кросс-энтропию на отложенном тексте в натах, затем перплексию как ;
- пересчитайте в биты и убедитесь, что ;
- уберите сглаживание и получите бесконечность на первом же незнакомом биграмме;
- сравните перплексию юниграммной и биграммной моделей на одном тексте.
Пятый пункт даёт число, которое стоит запомнить как ориентир: биграммная модель обычно улучшает перплексию в разы, а не на проценты, и это самое дешёвое улучшение в истории языковых моделей.
VAE на MNIST
Основное упражнение. Минимальный рабочий вариант — энкодер и декодер из двух линейных слоёв каждый, латент размерности (специально маленький, чтобы его можно было нарисовать).
Что реализовать:
- энкодер выдаёт и — логарифм дисперсии, чтобы не требовать положительности;
- репараметризация , ;
- KL к стандартному prior в закрытой форме — её стоит вывести самому:
- реконструкционный член как бинарная кросс-энтропия по пикселям;
- один сэмпл на пример: оценка шумная, но несмещённая.
Что посмотреть после обучения:
- нарисуйте латентное пространство. Двумерный , раскрашенный по цифрам, — классы должны разделиться, хотя метки в обучении не участвовали;
- пройдите по сетке в латенте и декодируйте. Переходы должны быть плавными — это то, чего автоэнкодер без KL-члена не даёт;
- следите за двумя членами лосса порознь. Их сумма — не то, что нужно смотреть; интересно именно соотношение;
- воспроизведите posterior collapse. Умножьте KL-член на и убедитесь, что KL уходит в нуль, латент перестаёт зависеть от , а реконструкции становятся одинаковыми;
- сравните с . Это обычный автоэнкодер: реконструкции резче, а сэмплы из prior — мусор, потому что латентное пространство «дырявое».
Пункты 4 и 5 важнее самого обучения. Они показывают, что ELBO — не произвольная сумма двух слагаемых, а равновесие, и что оба его нарушения выглядят как «модель обучилась», если смотреть только на суммарный лосс.
Что должно сойтись
Числовые ориентиры, по которым видно, что всё правильно:
| проверка | ожидание |
|---|---|
| KL-член в начале обучения | близок к нулю (, при малой инициализации) |
| KL-член после обучения | десятки нат, растёт с размерностью латента |
| ELBO | монотонно растёт, но не гладко — оценка по одному сэмплу шумная |
| против | совпадают до машинной точности |
| KL , реконструкции вырождаются |
И одна вещь, которая не должна сойтись: ELBO вашего VAE и . Зазор неизвестен и не равен нулю. Если хочется сравнить модели честно, нужна importance-weighted оценка (IWAE) — она берёт сэмплов вместо одного и даёт границу тем туже, чем больше , сходясь к при .
Источники
- Kingma, Welling — An Introduction to Variational Autoencoders — VAE от вывода до реализации
- Higgins и др. — beta-VAE — Что делает коэффициент перед KL
Проверки
0 из 2Блок целиком
Отметьте все верные утверждения, связывающие уроки этого блока.
Лосс VAE по частям
Реализуйте
vae_terms(mu, logvar, recon, targets)для одного примера с одномерным латентом — верните[kl, reconstruction, elbo]в натах:kl= в закрытой форме, где :reconstruction— бинарная кросс-энтропия по пикселям, сумма по всем компонентам, а не среднее:elbo= .
Знак в последней строке — та самая ловушка, из-за которой в чужом коде путаются: лосс, который минимизируют, равен
reconstruction + kl, а ELBO, которую максимизируют, равна ему с минусом.Проверить
klлегко: при и она обязана быть ровно нулём, потому что тогда совпадает с prior.Загрузка редактора…
Ctrl/⌘ + Enter