Вариационный автоэнкодер (VAE): как сеть учится генерировать

Вариационный автоэнкодер (VAE) - это порождающая модель, которая учится не просто сжимать данные, а описывать их распределение в латентном пространстве. Отличие от обычного автоэнкодера принципиальное: энкодер выдаёт не точку, а параметры распределения, из которого латент сэмплируется случайно. Благодаря этому из VAE можно генерировать новые правдоподобные объекты, а не только восстанавливать имеющиеся. Ниже разберём вероятностную постановку, трюк репараметризации, функцию потерь ELBO и роль KL-расхождения. Если нужно решить конкретную задачу по теме, соберите запрос в форме ниже.
Что такое вариационный автоэнкодер
VAE - это вероятностная модель, которая предполагает, что наблюдаемые данные порождаются из скрытой переменной через распределение , а сам латент берётся из простого априорного распределения , обычно стандартного нормального . Задача обучения - настроить параметры так, чтобы модель правдоподобно объясняла данные.
Проблема в том, что апостериорное распределение - то есть какой латент породил данный объект - вычислить напрямую невозможно: интеграл по всем неберущийся. VAE обходит это вариационным приближением: вводит обучаемое распределение , которое играет роль энкодера и приближает истинный апостериор. Декодер восстанавливает объект из латента. Обе части - нейросети, обучаемые совместно.

Вероятностный энкодер: среднее и дисперсия
Ключевое отличие от классического автоэнкодера - на выходе энкодера. Обычный автоэнкодер выдаёт код как одну точку. Вероятностный энкодер VAE выдаёт два вектора: вектор средних и вектор логарифмов дисперсий . Они задают нормальное распределение в латентном пространстве:
Латент для конкретного объекта не фиксирован - это целое облачко в латентном пространстве. Чтобы получить код, из этого облачка делают случайную выборку. Именно поэтому один и тот же объект при каждом проходе даёт чуть разный латент, и сеть учится тому, что близкие точки латента должны давать похожие реконструкции. Это и делает латентное пространство гладким и пригодным для генерации.
Энкодер выдаёт именно логарифм дисперсии, а не саму дисперсию. Так число на выходе может быть любым вещественным, а после экспоненты дисперсия всегда положительна - это устойчивее для оптимизации.
Трюк репараметризации
Сэмплирование из распределения - операция случайная, и через неё нельзя напрямую пропустить градиент при обратном распространении. Если бы латент брался как «в лоб», то градиент по и не посчитать: случайный узел разрывает граф вычислений.
Репараметризация (reparameterization trick) решает это элегантно. Случайность выносят в отдельную независимую переменную , а латент собирают детерминированной формулой:
Здесь - поэлементное умножение. Теперь зависит от и гладко и дифференцируемо, а вся случайность сидит в , через которую градиент пропускать не нужно. Это единственный приём, делающий VAE обучаемым обычным градиентным спуском.

Функция потерь: ELBO
VAE максимизирует нижнюю оценку правдоподобия данных - Evidence Lower Bound (ELBO). Для одного объекта её записывают так:
Первый член - ожидаемое логарифмическое правдоподобие реконструкции: насколько хорошо декодер восстанавливает вход из сэмплированного латента. Он играет ту же роль, что MSE или кросс-энтропия в обычном автоэнкодере. Второй член - KL-расхождение между распределением энкодера и априором : оно тянет облачка латентов к началу координат и не даёт им разбегаться.
На практике ELBO максимизируют, то есть минимизируют величину . Реконструкционный член оценивают по сэмплам, а KL-член при гауссовых распределениях имеет замкнутую формулу:
где - размерность латента. Никакого интегрирования по сэмплам для этого члена не нужно - он считается аналитически по выходам энкодера.
KL-расхождение и баланс двух сил
Две части ELBO тянут модель в разные стороны, и именно их баланс определяет поведение VAE. Реконструкционный член хочет, чтобы латенты были как можно более «информативными»: разнёс бы объекты подальше друг от друга, тогда декодер не путает их и восстанавливает точно. KL-член, наоборот, штрафует за отклонение от стандартного нормального - он сжимает латенты к нулю и заставляет распределения объектов перекрываться.
Если KL-член задавить, VAE вырождается в обычный автоэнкодер: латенты расползаются, между кластерами появляются «дыры», и генерация из априора даёт мусор. Если KL-член сделать слишком сильным, наступает posterior collapse - энкодер игнорирует вход, выдаёт почти для всех объектов, и реконструкции становятся одинаково размытыми. Рабочая точка - посередине.
Чтобы управлять этим балансом явно, в -VAE перед KL-членом ставят коэффициент :
При латентное пространство становится более структурированным и «развязанным» (disentangled): отдельные оси латента начинают отвечать за отдельные осмысленные факторы вариации. Расплата - реконструкция становится грубее.
Чем VAE отличается от обычного автоэнкодера
Различие глубже, чем просто «случайный латент». Обычный автоэнкодер оптимизирует только реконструкцию и никак не структурирует латентное пространство: точки между кластерами могут декодироваться в бессмыслицу, и сэмплировать из такого пространства нельзя. VAE добавляет к реконструкции вероятностную регуляризацию, которая делает латент непрерывным и совпадающим с известным априором. Поэтому из VAE можно просто взять , прогнать через декодер и получить новый правдоподобный объект.
| Свойство | Обычный автоэнкодер | Вариационный (VAE) |
|---|---|---|
| Выход энкодера | точка | параметры , |
| Латентное пространство | произвольное | согласовано с |
| Генерация новых объектов | нет | да, сэмплированием из априора |
| Функция потерь | реконструкция | реконструкция плюс KL |
По сути VAE - это автоэнкодер, превращённый в честную порождающую модель ценой одного дополнительного члена в потере и одного трюка с сэмплированием.
Где применяют вариационные автоэнкодеры
VAE используют там, где важна не только точность восстановления, но и осмысленная структура латента.
- Генерация данных. Из априора сэмплируют новые лица, цифры, молекулы, мелодии. По сравнению с GAN обучение VAE стабильнее, хотя картинки чуть более размытые.
- Интерполяция и редактирование. Плавное движение по прямой между двумя латентами даёт плавную морфировку объектов - лицо постепенно меняет выражение, цифра перетекает в другую.
- Поиск аномалий. Как и обычный автоэнкодер, VAE плохо реконструирует нетипичные объекты, но даёт ещё и вероятностную оценку правдоподобия.
- Снижение размерности с гладким латентом. Латент VAE удобнее для последующих задач, чем у обычного автоэнкодера, именно из-за непрерывности.
- Условная генерация (CVAE). Если подать в энкодер и декодер метку класса, можно генерировать объекты заданного класса.
Частые ошибки
- Путают выход энкодера с точкой. В VAE энкодер выдаёт и , а не готовый код. Латент получается сэмплированием - без него это уже не VAE.
- Забывают про репараметризацию. Если сэмплировать напрямую из , градиент по энкодеру не посчитается и сеть не обучится.
- Перекашивают баланс ELBO. Слишком сильный KL ведёт к posterior collapse и размытым реконструкциям, слишком слабый - к разрывному латенту и мусорной генерации.
- Берут дисперсию вместо логарифма. Энкодер должен выдавать , иначе приходится насильно держать выход положительным, и оптимизация становится неустойчивой.
- Ждут от VAE резких картинок. Усреднение по латентному облачку и MSE-потеря дают характерную размытость. За резкость отвечают другие модели или гибриды с GAN.
FAQ
Чем VAE отличается от GAN? VAE учит явное распределение и оптимизирует правдоподобие через ELBO, у него есть энкодер и стабильное обучение, но картинки получаются размытее. GAN не имеет энкодера и учится в игре генератора с дискриминатором - даёт резче, но обучается капризнее и не даёт оценки правдоподобия. Часто их комбинируют (VAE-GAN).
Зачем VAE репараметризация? Чтобы пропустить градиент через случайный шаг сэмплирования. Случайность выносят в независимую переменную , а латент собирают дифференцируемой формулой . Без этого трюка обратное распространение через сэмплирование невозможно.
Что такое posterior collapse? Это вырождение, когда энкодер перестаёт зависеть от входа и выдаёт для всех объектов почти стандартное нормальное распределение. KL-член обнуляется, но реконструкции становятся одинаково размытыми - модель фактически игнорирует латент. Лечат отжигом веса KL, -VAE или более слабым декодером.
Коротко
Вариационный автоэнкодер превращает обычный автоэнкодер в порождающую модель: энкодер выдаёт параметры распределения и , латент сэмплируется через трюк репараметризации , а обучение максимизирует ELBO - сумму реконструкции и KL-расхождения с априором . KL-член делает латентное пространство гладким и согласованным с априором, поэтому из VAE можно генерировать новые объекты простым сэмплированием. Баланс двух членов критичен: его перекос ведёт либо к разрывному латенту, либо к posterior collapse.
Читайте также

Автоэнкодер (autoencoder): как сеть сжимает данные
Автоэнкодер (autoencoder) простыми словами: энкодер, латентное пространство и декодер, функция потерь реконструкции, виды сетей и где их применяют для сжатия и поиска аномалий.

Абстрактный класс и интерфейс: в чём отличие
Абстрактный класс и интерфейс: чем отличаются в ООП, когда наследовать поведение, а когда задавать контракт, как выбрать на примерах Java, C# и Python.

Алгоритм AdaBoost: как слабые классификаторы дают сильный
Алгоритм AdaBoost простыми словами: адаптивный бустинг, перевзвешивание объектов, формула веса классификатора, итоговый ансамбль и разбор шага на примере с формулами.