Содержание курса 07 / 33

07 / 33 · Вариационные автоэнкодеры

Вариационные автоэнкодеры

Почему обычный автоэнкодер не может генерировать, модель с латентными переменными, лежащая в основе VAE, приближённое апостериорное распределение и ELBO, трюк репараметризации, KL-штраф в замкнутой форме в скалярном и матричном виде, на что на самом деле накладывает ограничение априорное распределение N(0, I), и условный VAE, которому можно указать, что генерировать.

На этой странице 13

Заметка об автоэнкодерах закончилась открытым вопросом: обычный автоэнкодер хорошо сжимает и реконструирует, но генератором не является. Мы не можем выбрать точку в его латентном пространстве и ожидать осмысленную картинку. Вариационный автоэнкодер (variational autoencoder, VAE), предложенный Kingma and Welling (2014) и независимо Rezende, Mohamed and Wierstra (2014), исправляет это, упорядочивая латентное пространство. Каждый вход кодируется не в одну точку, а в гауссиану, и эти гауссианы притягиваются к одному фиксированному априорному распределению. Кроме того, VAE — первая нейросетевая генеративная модель курса, которая обучается максимизацией правдоподобия (точнее, его нижней оценки), то есть по той целевой функции, которую заметка об энтропии назвала естественной.

Обозначения. x∈RDx \in \mathbb R^D — точка данных (изображение из DD значений пикселей), z∈Rdz \in \mathbb R^d — её латентный код, x^\hat x — реконструкция. p(z)p(z) — априорное распределение кодов. θ\theta — параметры декодера, φ\varphi — параметры энкодера, как в заметке об автоэнкодерах. N(μ,σ2)\mathcal N(\mu, \sigma^2) всегда означает распределение со средним μ\mu и дисперсией σ2\sigma^2. Для векторов N(μ,σ2)\mathcal N(\mu, \sigma^2) — сокращённая запись N(μ,diag⁡(σ2))\mathcal N(\mu, \operatorname{diag}(\sigma^2)), а N(0,I)\mathcal N(0, I) — стандартное нормальное распределение в dd измерениях. ⊙\odot — поэлементное произведение.

Порядок чтения. Основной путь идёт от модели через ELBO и трюк репараметризации к тому, что даёт упорядоченное латентное пространство, а затем к KL в замкнутом виде в разделе «Что фиксировано». Вывод ELBO, матричная форма KL и разложение слагаемого KL по агрегированному апостериорному распределению — дополнительный материал: они обосновывают и уточняют основное, и их можно прочитать позже.

От автоэнкодеров к генерации#

Напомним конвейер «энкодер — декодер»:

xданные  → энкодер   z  → декодер   x^реконструкция.\underset{\text{данные}}{x} \;\xrightarrow{\ \text{энкодер}\ }\; z \;\xrightarrow{\ \text{декодер}\ }\; \underset{\text{реконструкция}}{\hat x} .

Код zz — это представление меньшей размерности (lower-dimensional representation) (512 чисел у свёрточного автоэнкодера из предыдущей заметки), а задача декодера — реконструкция. Как обученный автоэнкодер мог бы генерировать новые изображения? Есть два очевидных способа, и оба не работают.

  1. Сэмплировать случайный zz и декодировать его. Возьмём, например, zz из стандартного нормального распределения. Коды обычного автоэнкодера ничем не привязаны к N(0,I)\mathcal N(0, I), поэтому такой zz может оказаться далеко от всех обучающих кодов, там, где декодер никогда не обучался, и нет никаких причин, чтобы он декодировался в цифру: латентное пространство не упорядочено. Обучение требует лишь, чтобы коды обучающих изображений декодировались обратно в эти изображения. Ничто не говорит, что лежит между кодами и даже где в Rd\mathbb R^d они находятся. Подгонка гауссианы к кодам каждого класса цифр, как в заметке об автоэнкодерах, работает лучше, но требует меток и статистик по классам, часть её сэмплов всё равно сильно искажена, а интерполированные коды декодируются в наложение двух цифр.
  2. Сэмплировать латентные векторы рядом с опорным. Закодируем реальное изображение в zrefz_{\text{ref}} и декодируем соседние точки z1,z2,z3z_1, z_2, z_3. Соседняя точка тоже не обязана быть осмысленным кодом: если она попадает в промежуток между кодами обучающих изображений, декодер на ней никогда не обучался, и декодированный сосед «7» вовсе не обязан походить на цифру.
Рисунок

Обычный автоэнкодер не умеет генерировать

Декодирование соседей опорного кода в обычном автоэнкодереСлева направо: входное изображение цифры 7 с подписью «данные»; энкодер, сужающийся к латентному пространству; двумерная латентная плоскость с серыми скоплениями обучающих кодов, красной опорной точкой z_ref на краю небольшого скопления других семёрок и тремя синими соседними точками z1, z2 и z3 внутри пунктирной окружности; декодер, расширяющийся обратно до размера изображения; и выходное изображение с бессмысленными каракулями, подписанное «мусор». Красная надпись: латентное пространство не упорядочено, соседи z_ref декодируются в бессмыслицу.данные xэнкодерлатентное пространство z512 чиселz₁z₂z₃zrefдекодермусорлатентное пространство не упорядочено: соседи zref декодируются в бессмыслицуДекодирование соседей опорного кода в обычном автоэнкодереСверху вниз: входное изображение цифры 7; энкодер; латентная плоскость с серыми скоплениями обучающих кодов, красной опорной точкой z_ref на краю небольшого скопления других семёрок и тремя синими соседними точками z1, z2, z3; декодер; и выходное изображение с бессмысленными каракулями, подписанное «мусор». Надпись: латентное пространство не упорядочено, соседи z_ref декодируются в бессмыслицу.данные xэнкодерлатентныйz: 512чиселz₁z₂z₃zrefдекодермусорлатентное пространство не упорядочено:соседи zref декодируются в бессмыслицу
Вход 7 кодируется в красный опорный код на краю небольшого островка других семёрок. Серые точки — коды обучающих изображений: они образуют островки с пустым пространством между ними, потому что ничто в обучении не упорядочивает латентное пространство. Соседние точки z₁, z₂, z₃ попадают в это пустое пространство, и декодер превращает их в каракули. Рисунок схематичный, а не результат обученной модели.

Решение — сделать распределение кодов частью модели. Для этого нужен язык моделей с латентными переменными (latent-variable models).

Совместное, маргинальное и условное распределения#

Возьмём две случайные величины: данные xx и латентную переменную zz. Их совместная плотность p(x,z)p(x, z) — облако на плоскости (x,z)(x, z). Проекции облака на каждую из осей дают маргинальные распределения p(x)p(x) и p(z)p(z). Маргинализация вычисляет маргинальное распределение, интегрируя по другой переменной:

p(x)=∫p(x,z) dz.p(x) = \int p(x, z)\, dz .

Условная вероятность — это совместная плотность, ограниченная на фиксированное значение условия и заново нормированная:

p(x∣z)=p(x,z)p(z).p(x \mid z) = \frac{p(x, z)}{p(z)} .

Например, p(x∣z=3)p(x \mid z = 3) — срез p(x,z)p(x,z) вдоль прямой z=3z = 3, делённый на p(z=3)p(z = 3), чтобы интеграл по xx был равен единице.

Рисунок

Совместное, маргинальные и условное распределения

Совместная плотность, её маргинальные распределения и один условный срезСэмплы на плоскости x–z образуют два наклонных облака: одно около x = 3.4, z = 4.2, другое около x = 7, z = 2.2. Под осью x красная кривая показывает маргинальное распределение p(x) с двумя горбами. Слева от оси z синяя кривая показывает маргинальное распределение p(z). На горизонтальной пунктирной прямой z = 3 стоит янтарная кривая: условная плотность p(x при условии z = 3), у которой тоже два горба, по одному под каждым облаком.xzсовместная p(x, z)p(z)p(x)= ∫ p(x, z) dx= ∫ p(x, z) dzмаргинальное: интегралпо другой переменнойz = 3p(x | z = 3)= p(x, 3) / p(z = 3)Совместная плотность, её маргинальные распределения и один условный срезСэмплы на плоскости x–z образуют два наклонных облака: одно около x = 3.4, z = 4.2, другое около x = 7, z = 2.2. Под осью x красная кривая показывает маргинальное распределение p(x) с двумя горбами. Слева от оси z синяя кривая показывает маргинальное распределение p(z). На горизонтальной пунктирной прямой z = 3 стоит янтарная кривая: условная плотность p(x при условии z = 3), у которой тоже два горба, по одному под каждым облаком.xzсовместная p(x, z)p(z)p(x)p(x) = ∫ p(x, z) dz, p(z) = ∫ p(x, z) dxмаргинальное: интегрируем по другой переменнойz = 3p(x | z = 3)= p(x, 3) / p(z = 3)
Серые точки — сэмплы из совместной плотности p(x, z), здесь это смесь двух коррелированных гауссиан. Интегрирование совместной плотности по z даёт маргинальное распределение p(x) под осью x; интегрирование по x даёт p(z) слева от оси z. Янтарная кривая — срез вдоль z = 3, перенормированный на p(z = 3), чтобы получилась плотность по x: условное распределение p(x | z = 3).

Модель с латентными переменными и её апостериорное распределение#

Модель с латентными переменными генерирует данные в два шага: сначала берёт код из априорного распределения (prior) p(z)p(z), затем изображение из декодера (правдоподобия) pθ(x∣z)p_\theta(x \mid z). Априорное распределение выбирается, а не обучается; стандартный выбор — p(z)=N(0,I)p(z) = \mathcal N(0, I). Распределение модели на изображениях — это маргинальное распределение

pθ(x)=∫pθ(x∣z) p(z) dz,p_\theta(x) = \int p_\theta(x \mid z)\, p(z)\, dz ,

которое называют обоснованностью (evidence). Обучение методом максимального правдоподобия означает максимизацию log⁡pθ(x)\log p_\theta(x) на данных.

Обратное направление, «какие коды объясняют это изображение», — это апостериорное распределение (posterior). По теореме Байеса

pθ(z∣x)=pθ(x∣z) p(z)pθ(x),p_\theta(z \mid x) = \frac{p_\theta(x \mid z)\, p(z)}{p_\theta(x)} ,

и обоснованность в знаменателе — интеграл по всему латентному пространству. Для декодера-нейросети замкнутой формы у него нет. В высокой размерности квадратурные формулы безнадёжны, а наивное усреднение pθ(x∣z)p_\theta(x \mid z) методом Монте-Карло по z∼p(z)z \sim p(z) имеет слишком большую дисперсию, чтобы применять его на каждом шаге обучения: почти все сэмплы из априорного распределения плохо объясняют данный xx. Поэтому и правдоподобие, которое мы хотим максимизировать, и апостериорное распределение, которое понадобилось бы для кодирования, вычислительно неразрешимы (intractable).

Рисунок

Распределение данных и латентное распределение

Отображения между распределением данных и латентным распределениемСлева — пятно неправильной формы с подписью p(x), распределение данных. Справа — концентрические окружности с подписью p(z) = N(0, I), латентное распределение. Изогнутая стрелка сверху идёт от пятна к окружностям и подписана: p(z при условии x), кодирование, апостериорное распределение. Изогнутая стрелка снизу идёт от окружностей обратно к пятну и подписана: p(x при условии z), декодирование, реконструкция.p(x)распределение данныхp(z) = N(0, I)латентное распределениекодирование: апостериорноеp(z | x)p(x | z)декодирование:реконструкцияОтображения между распределением данных и латентным распределениемСверху — пятно неправильной формы с подписью p(x), распределение данных. Снизу — концентрические окружности с подписью p(z) = N(0, I), латентное распределение. Стрелка вниз слева подписана: p(z при условии x), кодирование, апостериорное распределение; стрелка вверх справа подписана: p(x при условии z), декодирование, реконструкция.распределение данныхp(x)p(z | x)кодирование:апостериорноеp(x | z)декодирование:реконструкцияp(z) = N(0, I)латентное распределение
Неизвестное распределение данных p(x) неправильной формы (красное) и предполагаемое латентное распределение p(z) = N(0, I) (синее, линии уровня на 0.5, 1, 1.5 и 2 стандартных отклонениях). Апостериорное распределение p(z | x) переводит данные в коды; обратное направление p(x | z) переводит коды обратно в данные, то есть выполняет реконструкцию.

Вариационная аппроксимация и ELBO#

Выход в том, чтобы приблизить апостериорное распределение членом простого семейства распределений. VAE использует диагональную гауссиану, среднее и дисперсии которой выдаёт сеть-энкодер с параметрами φ\varphi:

qφ(z∣x)=N(μφ(x),σφ2(x))≈pθ(z∣x).q_\varphi(z \mid x) = \mathcal N\big(\mu_\varphi(x), \sigma_\varphi^2(x)\big) \approx p_\theta(z \mid x).

Замена неразрешимого апостериорного распределения ближайшим к нему по DKL(q ∥ pθ(z∣x))D_{\mathrm{KL}}\big(q \,\|\, p_\theta(z \mid x)\big) членом простого семейства — это вариационный вывод (variational inference) (Blei, Kucukelbir and McAuliffe, 2017). Поскольку одна сеть строит приближение для каждого xx вместо отдельной оптимизации для каждой точки данных, такой вывод называют амортизированным (amortized) (Kingma and Welling, 2019, §2.1). Максимизируемая величина — нижняя оценка обоснованности (evidence lower bound, ELBO):

L(x)=Eqφ(z∣x)[log⁡pθ(x∣z)]⏟реконструкция−DKL(qφ(z∣x) ∥ p(z))⏟регуляризация≤log⁡pθ(x).\begin{aligned} \mathcal L(x) ={}& \underbrace{\mathbb E_{q_\varphi(z\mid x)}\big[\log p_\theta(x \mid z)\big]}_{\text{реконструкция}} \\ &-\underbrace{D_{\mathrm{KL}}\big(q_\varphi(z \mid x)\,\|\,p(z)\big)}_{\text{регуляризация}} \\ \le{}& \log p_\theta(x). \end{aligned}

Неравенство выводится ниже. Два его слагаемых тянут в противоположные стороны.

Реконструкция измеряет, насколько хорошо изображение переживает путь «изображение → код → изображение». С гауссовским декодером она сводится к функции потерь реконструкции L2L_2. Если pθ(x∣z)=N(x; x^(z), s2I)p_\theta(x \mid z) = \mathcal N\big(x;\, \hat x(z),\, s^2 I\big), где сеть-декодер выдаёт среднее x^(z)\hat x(z), а s2s^2 — фиксированная дисперсия, то

−log⁡pθ(x∣z)=12s2 ∥x−x^(z)∥22+D2log⁡(2πs2),\begin{aligned} -\log p_\theta(x \mid z) ={}& \frac{1}{2s^2}\,\big\|x - \hat x(z)\big\|_2^2 \\ &+ \frac D2 \log(2\pi s^2), \end{aligned}

и последнее слагаемое не зависит от сети. При s2=12s^2 = \tfrac12 вес квадратичной ошибки равен ровно 1, поэтому квадратичная ошибка, просуммированная по DD пикселям, плюс слагаемое KL-дивергенции (KL divergence) — это отрицательная ELBO с точностью до константы. (Среднему по пикселям соответствовало бы s2=D/2s^2 = D/2.) Другая фиксированная s2s^2 меняет баланс между двумя слагаемыми: умножение функции потерь на 2s22s^2 даёт ∥x−x^(z)∥22+2s2 DKL\|x - \hat x(z)\|_2^2 + 2s^2\, D_{\mathrm{KL}}, то есть вес KL β=2s2\beta = 2s^2 (см. β-VAE ниже).

Регуляризация измеряет, насколько каждое апостериорное распределение qφ(z∣x)q_\varphi(z \mid x) далеко от априорного. Она тянет каждое распределение кода к N(0,I)\mathcal N(0, I), так что все коды живут в одной хорошо известной области латентного пространства.

Рисунок

Два слагаемых ELBO

Слагаемые реконструкции и регуляризации в ELBOФормула L(x) = математическое ожидание по q(z при условии x) от log p(x при условии z) минус KL между q(z при условии x) и p(z). Фигурная скобка под первым слагаемым подписана «реконструкция»: насколько хорошо мы реконструируем, сравнивая реальное изображение с изображением после пути «реальное → латентное → реальное»; с гауссовским декодером это слагаемое сводится к функции потерь реконструкции в виде суммы квадратов ошибок. Небольшой эскиз показывает x, энкодер, z, декодер, x с крышкой и красную двойную стрелку с подписью «сравнение» между x и x с крышкой. Фигурная скобка под вторым слагаемым подписана «регуляризация»: насколько апостериорное распределение q(z при условии x) близко к априорному p(z). Эскиз показывает пунктирные концентрические окружности для p(z) и небольшое синее пятно q(z при условии x) в стороне от центра внутри них; красные стрелки тянут его к центру и наружу, подписи: «тянем q к p» и «придаём нормальную форму».ℒ(x) =Eq(z|x)[log p(x | z)]−KL(q(z | x) ‖ p(z))реконструкциярегуляризациянасколько хорошо мы реконструируемсравниваем: реальное → латентное → реальноеxzx̂сравнениегауссовский декодер ⇒ квадратичная ошибка(сумма квадратов ошибок ‖x − x̂‖²)насколько апостериорное q(z | x)близко к априорному p(z)p(z)q(z | x)тянемq к pпридаём нормальную формуСлагаемые реконструкции и регуляризации в ELBOСверху: первое слагаемое ELBO, математическое ожидание по q(z при условии x) от log p(x при условии z), подписанное «реконструкция», насколько хорошо мы реконструируем, с эскизом x, энкодера, z, декодера, x с крышкой и красной стрелкой сравнения; с гауссовским декодером оно сводится к функции потерь в виде суммы квадратов ошибок. Снизу: минус KL между q(z при условии x) и p(z), подписанное «регуляризация», насколько апостериорное распределение близко к априорному, с эскизом небольшого синего пятна q внутри пунктирных окружностей p(z) и красными стрелками, которые тянут его к центру и наружу.ℒ(x) =Eq(z|x)[log p(x | z)]реконструкциянасколько хорошо мы реконструируем:реальное → латентное → реальноеxzx̂сравнениегауссовский декодер ⇒ квадратичная ошибка(сумма квадратов ошибок ‖x − x̂‖²)− KL(q(z | x) ‖ p(z))регуляризациянасколько апостериорное q(z | x)близко к априорному p(z)p(z)q(z | x)тянемq к pпридаём нормальную форму
Первое слагаемое требует, чтобы изображение пережило путь «реальное → латентное → реальное». Второе — штраф за то, насколько каждое апостериорное распределение q(z | x) далеко от априорного p(z) = N(0, I) (пунктирные линии уровня): он тянет смещённое и слишком узкое q к центру и расширяет его, приближая к нормальному распределению.

Итак, вместо того чтобы отображать вход в одну точку, VAE отображает его в гауссиану. Энкодер выдаёт μ\mu и log⁡σ2\log\sigma^2, мы сэмплируем z∼N(μ,σ2)z \sim \mathcal N(\mu, \sigma^2), и декодер реконструирует вход по zz. Функция потерь при обучении — отрицательная ELBO с s2=12s^2 = \tfrac12, оценённая по одному сэмплу z∼N(μ,σ2)z \sim \mathcal N(\mu, \sigma^2) на каждый вход:

LVAE(x)=∥x−x^(z)∥22⏟реконструкция+DKL(N(μ,σ2) ∥ N(0,I)).\begin{aligned} \mathcal L_{\text{VAE}}(x) ={}& \underbrace{\big\|x - \hat x(z)\big\|_2^2}_{\text{реконструкция}} \\ &+ D_{\mathrm{KL}}\big(\mathcal N(\mu, \sigma^2)\,\|\,\mathcal N(0, I)\big). \end{aligned}

Слагаемое KL теперь входит со знаком плюс, потому что мы минимизируем.

Трюк репараметризации#

Функция потерь содержит сэмпл z∼N(μ,σ2)z \sim \mathcal N(\mu, \sigma^2), а через сэмплирование нельзя провести обратное распространение ошибки: случайный сэмпл не является дифференцируемой функцией μ\mu и σ\sigma. Решение — трюк репараметризации (reparameterization trick): перенести случайность во вход, ровно как в заметке о гауссианах:

z=μ+σ⊙ε,ε∼N(0,I).z = \mu + \sigma \odot \varepsilon, \qquad \varepsilon \sim \mathcal N(0, I).

ε\varepsilon сэмплируется независимо от сети, затем масштабируется на σ\sigma и сдвигается на μ\mu. Распределение остаётся тем же, z∼N(μ,σ2)z \sim \mathcal N(\mu, \sigma^2), но теперь zz — дифференцируемая функция μ\mu и σ\sigma: ∂zj/∂μj=1\partial z_j / \partial \mu_j = 1 и ∂zj/∂σj=εj\partial z_j / \partial \sigma_j = \varepsilon_j. Градиенты слагаемого реконструкции проходят обратно в энкодер (Kingma and Welling, 2014, §2.4). Полученная оценка градиента обычно имеет гораздо меньшую дисперсию, чем универсальная оценка REINFORCE через градиент логарифма плотности (score-function estimator), дисперсию которой Kingma и Welling (§2.2) называют очень высокой.

Рисунок

Зачем нужен трюк репараметризации

VAE с сэмплированием и VAE с репараметризациейДва ряда. Ряд а: x поступает в энкодер, который выдаёт mu и sigma, затем блок z ~ N(mu, sigma в квадрате) сэмплирует z, и z проходит через декодер к x с крышкой. Зелёная стрелка обратного прохода от функции потерь идёт справа налево под рядом и обрывается красным крестиком под блоком сэмплирования с подписью: через сэмплирование градиент не проходит. Ряд б: тот же энкодер выдаёт mu и sigma, которые поступают в блок mu + sigma, умноженное на epsilon; epsilon ~ N(0, I) — случайная точка, которая подаётся сверху. Результат z идёт в декодер. Теперь зелёная стрелка обратного прохода доходит до самого энкодера, подпись: дифференцируемо, dz/dmu = 1, dz/dsigma = epsilon.(а) сэмплирование внутри сетиxэнкодерμσz ~ N(μ, σ²)случайный сэмплzдекодерx̂ℒчерез сэмплирование градиент не проходит(б) репараметризация: z = μ + σ ⊙ εxэнкодерμσμ + σ ⊙ εε~ N(0, I)случайная точкаzдекодерx̂ℒдифференцируемо: ∂z/∂μ = 1, ∂z/∂σ = εVAE с сэмплированием и VAE с репараметризациейДва ряда. Ряд а: x поступает в энкодер, который выдаёт mu и sigma, затем блок z ~ N(mu, sigma в квадрате) сэмплирует z, и z проходит через декодер к x с крышкой. Зелёная стрелка обратного прохода от функции потерь идёт справа налево под рядом и обрывается красным крестиком под блоком сэмплирования с подписью: через сэмплирование градиент не проходит. Ряд б: тот же энкодер выдаёт mu и sigma, которые поступают в блок mu + sigma, умноженное на epsilon; epsilon ~ N(0, I) — случайная точка, которая подаётся сверху. Результат z идёт в декодер. Теперь зелёная стрелка обратного прохода доходит до самого энкодера, подпись: дифференцируемо, dz/dmu = 1, dz/dsigma = epsilon.(а) сэмплирование внутри сетиxэнкодерμσz ~ N(μ, σ²)случайный сэмплzдекодерx̂через сэмплирование градиент не проходит(б) репараметризация: z = μ + σ ⊙ εxэнкодерμσμ + σ ⊙ εε~ N(0, I)случайная точкаzдекодерx̂дифференцируемо: ∂z/∂μ = 1, ∂z/∂σ = ε
Зелёные стрелки — обратный проход от функции потерь. (а) Если z сэмплируется внутри сети, градиент останавливается на случайном сэмпле и не доходит ни до μ и σ, ни до энкодера. (б) То же распределение получается, если сэмплировать ε ~ N(0, I) вне сети и вычислять z = μ + σ ⊙ ε — детерминированную дифференцируемую функцию μ и σ.

KL-часть функции потерь вообще не требует сэмплирования: между двумя гауссианами KL-дивергенция имеет замкнутую форму, выведенную ниже. Суммируя по dd латентным измерениям, получаем

LKL=−12∑j=1d(1+log⁡σj2−μj2−σj2).\mathcal L_{\mathrm{KL}} = -\frac12 \sum_{j=1}^{d} \big(1 + \log \sigma_j^2 - \mu_j^2 - \sigma_j^2\big) .

Что даёт упорядоченное латентное пространство#

  • Мы можем сэмплировать z∼N(0,I)z \sim \mathcal N(0, I) и декодировать его: слагаемое KL тянет коды к априорному распределению, поэтому сэмплы из него в основном попадают туда, где декодер обучался (насколько хорошо это работает, обсуждается ниже). Можно также сэмплировать рядом с кодом опорного изображения и получать его осмысленные вариации.
  • Мы можем интерполировать: декодировать zλ=(1−λ) za+λ zbz_\lambda = (1-\lambda)\, z_a + \lambda\, z_b для λ\lambda от 0 до 1 и плавно переходить от одного изображения или класса к другому — пока отрезок остаётся там, где коды хорошо представлены. Это не гарантировано: коды лишь приближённо согласуются с априорным распределением (ниже), а в высокой размерности прямой отрезок может пересекать области, где нет ни одного обучающего кода.
  • Мы можем выполнять арифметику атрибутов. Усредним коды изображений, у которых есть некоторый атрибут, например улыбка, и коды изображений, у которых его нет. Разность двух средних — вектор атрибута, и прибавление его кратного к коду другого изображения добавляет этот атрибут; Carter and Nielsen (2017) делают так с VAE, обученным на шрифтах, и вектором «жирности» (bolding vector). Liu et al. (2019) строят визуальный инструмент, который позволяет задавать такие направления в латентном пространстве и проверять, что они кодируют.
Рисунок

Интерполяция в упорядоченном латентном пространстве

Латентная интерполяция между двумя классамиЛатентная плоскость с пунктирными круговыми линиями уровня стандартного нормального априорного распределения. Синее облако кодов цифры 1 лежит левее центра около z_a, красное облако кодов цифры 7 — правее центра около z_b. Прямой отрезок соединяет z_a и z_b, на нём отмечены точки lambda = 0, 0.25, 0.5, 0.75 и 1. Рядом пять декодированных миниатюр показывают, как 1 постепенно превращается в 7.p(z) = N(0, I)коды «1»коды «7»zazbzλдекодируем zλ = (1 − λ) za + λ zbλ = 0λ = 0.25λ = 0.5λ = 0.75λ = 1Латентная интерполяция между двумя классамиЛатентная плоскость с пунктирными круговыми линиями уровня стандартного нормального априорного распределения. Синее облако кодов цифры 1 лежит левее центра около z_a, красное облако кодов цифры 7 — правее центра около z_b. Прямой отрезок соединяет z_a и z_b, на нём отмечены точки lambda = 0, 0.25, 0.5, 0.75 и 1. Рядом пять декодированных миниатюр показывают, как 1 постепенно превращается в 7.p(z) = N(0, I)коды «1»коды «7»zazbzλдекодируем zλλ = 0λ = 0.25λ = 0.5λ = 0.75λ = 1
В VAE коды всех изображений притягиваются к априорному распределению N(0, I) (пунктирные линии уровня 1σ и 2σ), поэтому прямой отрезок между кодом единицы и кодом семёрки задуман проходящим через осмысленные коды. Это схема желаемой картины, а не гарантия: коды лишь приближённо согласуются с априорным распределением, и в высокой размерности отрезок может пересекать области без обучающих кодов. Декодирование смеси (1 − λ)·(код единицы) + λ·(код семёрки) при растущем λ даёт постепенный переход между классами. Миниатюры схематичны и не являются выходами обученной модели.

Недостатки.

  • Размытые изображения. С факторизованным гауссовским декодером мы показываем его среднее x^(z)\hat x(z), а не сэмпл из pθ(x∣z)p_\theta(x \mid z). Там, где апостериорные распределения разных изображений перекрываются, один код может объясняться несколькими изображениями, и оптимум квадратичной ошибки x^(z)\hat x(z) — среднее по ним. Одно из объяснений размытости на уровне всей модели — то, что максимальное правдоподобие (прямая KL, forward KL) покрывает моды (mode-covering), см. заметку Подгонка распределений с помощью KL: модель, которая не может представить данные, размазывает вероятность по всему, что выглядит возможным (Theis, van den Oord and Bethge, 2016).
  • Результаты хуже, чем у других моделей, основанных на правдоподобии, на протяжении нескольких лет: Vahdat and Kautz (2020) отмечают, что VAE уступали нормализующим потокам (normalizing flows) и авторегрессионным моделям. Их иерархическая модель NVAE достигла наилучших на тот момент результатов среди неавторегрессионных моделей, основанных на правдоподобии, на CelebA 64 и CelebA HQ и стала первым VAE, применённым к естественным изображениям размером 256×256256 \times 256 пикселей.
  • Нет обусловливания в базовой модели: ей нельзя указать, что генерировать.

На эти недостатки нацелены расширения. Условный VAE (conditional VAE, Sohn, Lee and Yan, 2015) подаёт метку и в энкодер, и в декодер, так что ему можно сказать, что генерировать; он выводится ниже. β-VAE (Higgins et al., 2017) перевзвешивает слагаемое KL, VQ-VAE (van den Oord, Vinyals and Kavukcuoglu, 2017) заменяет гауссов код дискретным, а VAPNEV (Agrawal and Dukkipati, 2016) заменяет попиксельное слагаемое реконструкции точным правдоподобием нормализующего потока, зависящего от кода; всем трём посвящена следующая заметка.

Откуда берётся ELBO#

Дополнительный материал: вывод сформулированной выше оценки и точная величина её зазора. Остальная часть заметки на него не опирается.

В этом разделе мы опускаем θ\theta и φ\varphi. Начнём с обоснованности и умножим подынтегральное выражение на 1=q(z∣x)/q(z∣x)1 = q(z\mid x)/q(z\mid x). Такая запись требует, чтобы q(z∣x)>0q(z \mid x) > 0 везде, где p(x,z)>0p(x, z) > 0, и для гауссовской qq это выполняется:

log⁡p(x)=log⁡∫p(x,z) dz=log⁡∫q(z∣x)q(z∣x) p(x,z) dz=log⁡Eq(z∣x) ⁣[p(x,z)q(z∣x)]≥Eq(z∣x) ⁣[log⁡p(x,z)q(z∣x)]=L(x).\begin{aligned} \log p(x) &= \log \int p(x, z)\, dz \\ &= \log \int \frac{q(z \mid x)}{q(z \mid x)}\, p(x, z)\, dz \\ &= \log \mathbb E_{q(z \mid x)}\!\left[\frac{p(x, z)}{q(z \mid x)}\right] \\ &\ge \mathbb E_{q(z \mid x)}\!\left[\log \frac{p(x, z)}{q(z \mid x)}\right] = \mathcal L(x). \end{aligned}

Неравенство здесь — это неравенство Йенсена. Для выпуклой ff оно имеет вид E[f(Y)]≥f(E[Y])\mathbb E[f(Y)] \ge f(\mathbb E[Y]). Логарифм вогнут, поэтому знак меняется на противоположный:

log⁡E[Y]  ≥  E[log⁡Y].\log \mathbb E[Y] \;\ge\; \mathbb E[\log Y].
Рисунок

Неравенство Йенсена для вогнутого логарифма

Хорда log y лежит ниже кривойВогнутая кривая y = log Y для Y от 0.3 до 6.2. Две точки на ней, при Y = 0.6 и Y = 5.4, соединены прямой пунктирной хордой. В точке Y = E[Y] = 3 кривая находится на уровне log E[Y] = 1.10, а хорда ниже, на уровне E[log Y] = 0.59. Янтарный отрезок между ними подписан «зазор Йенсена». В рамке написано: log E[Y] больше или равно E[log Y].-1012Ylog YaE[Y]b(a, log a)(b, log b)log E[Y] = 1.10E[log Y] = 0.59зазор Йенсенахорда лежит ниже вогнутой кривойlog E[Y] ≥ E[log Y]Хорда log y лежит ниже кривойВогнутая кривая y = log Y для Y от 0.3 до 6.2. Две точки на ней, при Y = 0.6 и Y = 5.4, соединены прямой пунктирной хордой. В точке Y = E[Y] = 3 кривая находится на уровне log E[Y] = 1.10, а хорда ниже, на уровне E[log Y] = 0.59. Янтарный отрезок между ними подписан «зазор Йенсена». В рамке написано: log E[Y] больше или равно E[log Y].-1012Ylog YaE[Y]b(a, log a)(b, log b)log E[Y] = 1.10E[log Y] = 0.59зазор Йенсенахорда лежит ниже вогнутой кривойlog E[Y] ≥ E[log Y]
Y принимает значения 0.6 и 5.4 с вероятностью ½ каждое. Хорда между двумя точками графика логарифма лежит ниже графика, поэтому среднее логарифмов, E[log Y] = 0.59, меньше логарифма среднего, log E[Y] = log 3 = 1.10. Для выпуклой f картина переворачивается: E[f(Y)] ≥ f(E[Y]).

Запись p(x,z)=p(x∣z) p(z)p(x, z) = p(x \mid z)\, p(z) разбивает оценку на два знакомых слагаемых:

L(x)=Eq(z∣x) ⁣[log⁡p(x∣z)+log⁡p(z)q(z∣x)]=Eq(z∣x)[log⁡p(x∣z)]−DKL(q(z∣x) ∥ p(z)).\begin{aligned} \mathcal L(x) &= \mathbb E_{q(z\mid x)}\!\left[\log p(x \mid z) + \log \frac{p(z)}{q(z \mid x)}\right] \\ &= \mathbb E_{q(z\mid x)}\big[\log p(x \mid z)\big] \\ &\quad - D_{\mathrm{KL}}\big(q(z \mid x)\,\|\,p(z)\big). \end{aligned}

Обоснованность никогда не меньше ELBO, поэтому, максимизируя ELBO, мы максимизируем гарантированную нижнюю границу для log⁡p(x)\log p(x).

Насколько оценка отстаёт от правдоподобия? Ровно на KL-дивергенцию. Поскольку p(x,z)=p(z∣x) p(x)p(x, z) = p(z \mid x)\, p(x),

log⁡p(x)−L(x)=Eq(z∣x) ⁣[log⁡p(x)−log⁡p(z∣x) p(x)q(z∣x)]=Eq(z∣x)[log⁡q(z∣x)−log⁡p(z∣x)]=DKL(q(z∣x) ∥ p(z∣x))  ≥  0.\begin{aligned} &\log p(x) - \mathcal L(x) \\ &\quad= \mathbb E_{q(z\mid x)}\!\left[\log p(x) - \log\frac{p(z\mid x)\,p(x)}{q(z \mid x)}\right] \\ &\quad= \mathbb E_{q(z\mid x)}\big[\log q(z \mid x) - \log p(z \mid x)\big] \\ &\quad= D_{\mathrm{KL}}\big(q(z \mid x)\,\|\,p(z \mid x)\big) \;\ge\; 0 . \end{aligned}

Во второй строке log⁡p(x)\log p(x) сокращается, а на последнем шаге используется неотрицательность KL (см. заметку об энтропии). С параметрами это записывается как L=log⁡pθ(x)−DKL(qφ(z∣x) ∥ pθ(z∣x))\mathcal L = \log p_\theta(x) - D_{\mathrm{KL}}\big(q_\varphi(z \mid x)\,\|\,p_\theta(z \mid x)\big). Шаг по θ\theta увеличивает эту сумму: обычно за счёт роста log⁡pθ(x)\log p_\theta(x), но, возможно, и за счёт того, что истинное апостериорное распределение становится легче приблизить с помощью qq, а это смещает модель в сторону таких апостериорных распределений. Поэтому максимизация ELBO лишь приближённо максимизирует правдоподобие (Kingma and Welling, 2019, §2.2.1; Hoffman and Johnson, 2016, формула 5). По параметрам энкодера log⁡pθ(x)\log p_\theta(x) не меняется, поэтому энкодер может лишь сокращать зазор: он делает q(z∣x)q(z \mid x) лучшим приближением истинного апостериорного распределения в смысле обратной KL (reverse KL). Оценка точна ровно тогда, когда q(z∣x)=p(z∣x)q(z\mid x) = p(z\mid x).

Что фиксировано: априорное распределение, а не апостериорное#

Обязано ли апостериорное распределение быть N(0,I)\mathcal N(0, I)? Нет. Фиксировано априорное распределение p(z)=N(0,I)p(z) = \mathcal N(0, I). Апостериорное не фиксировано: для каждого входа энкодер выдаёт два вектора, μ(x)\mu(x) и log⁡σ2(x)\log \sigma^2(x).

Почему log⁡σ2\log \sigma^2, а не σ2\sigma^2?

  • σ2\sigma^2 — дисперсия и должна быть положительной. Линейный слой может выдать любое вещественное число, а σ2=elog⁡σ2>0\sigma^2 = e^{\log \sigma^2} > 0 всегда.
  • Так удобнее численно: крошечная дисперсия вроде 10−410^{-4} превращается в умеренное число, log⁡10−4≈−9.2\log 10^{-4} \approx -9.2.
  • Замкнутая форма KL между гауссианами записывается непосредственно через log⁡σ2\log\sigma^2.

Постоянное апостериорное распределение бесполезно. Предположим, что энкодер игнорирует вход и выдаёт q(z∣x)=N(0,I)q(z \mid x) = \mathcal N(0, I) для любого xx. Слагаемое KL было бы нулевым, но zz не нёс бы никакой информации об xx: декодер получал бы чистый шум. Декодер вроде нашего — факторизованная гауссиана с фиксированной дисперсией, сеть которой выдаёт среднее изображение, — в лучшем случае выдавал бы тогда среднее изображение. Более выразительный декодер, например авторегрессионный, может и без zz моделировать нетривиальное распределение изображений, и тогда ничто в ELBO не заставляет использовать код. Этот сбой известен как коллапс апостериорного распределения (posterior collapse), и на практике он случается, когда декодер достаточно мощный, чтобы моделировать данные без кода (Bowman et al., 2016). Вход должен оставаться восстановимым по своему коду.

Замкнутая форма. Для одного латентного измерения

DKL(N(μ,σ2) ∥ N(0,1))=12(μ2+σ2−1−log⁡σ2),\begin{aligned} &D_{\mathrm{KL}}\big(\mathcal N(\mu, \sigma^2)\,\|\,\mathcal N(0, 1)\big) \\ &\quad= \tfrac12\big(\mu^2 + \sigma^2 - 1 - \log \sigma^2\big), \end{aligned}

а для диагональной гауссианы вклады измерений складываются (Kingma and Welling, 2014, приложение B). При q=N(μ,σ2)q = \mathcal N(\mu, \sigma^2) и p=N(0,1)p = \mathcal N(0,1)

log⁡q(z)=−12log⁡(2πσ2)−(z−μ)22σ2,log⁡p(z)=−12log⁡(2π)−z22.\begin{aligned} \log q(z) &= -\tfrac12 \log(2\pi\sigma^2) - \frac{(z-\mu)^2}{2\sigma^2}, \\ \log p(z) &= -\tfrac12 \log(2\pi) - \frac{z^2}{2}. \end{aligned}

При z∼qz \sim q имеем E[(z−μ)2]=σ2\mathbb E[(z-\mu)^2] = \sigma^2 и E[z2]=μ2+σ2\mathbb E[z^2] = \mu^2 + \sigma^2, поэтому

DKL(q ∥ p)=Eq[log⁡q−log⁡p]=−12log⁡σ2−12+12(μ2+σ2)=12(μ2+σ2−1−log⁡σ2).\begin{aligned} D_{\mathrm{KL}}(q\,\|\,p) &= \mathbb E_q[\log q - \log p] \\ &= -\tfrac12\log \sigma^2 - \tfrac12 + \tfrac12(\mu^2 + \sigma^2) \\ &= \tfrac12\big(\mu^2 + \sigma^2 - 1 - \log\sigma^2\big). \end{aligned}

Если внести минус в скобку, получится формула для LKL\mathcal L_{\mathrm{KL}} выше. Значение равно нулю только при μ=0\mu = 0, σ=1\sigma = 1, потому что σ2−1−log⁡σ2≥0\sigma^2 - 1 - \log\sigma^2 \ge 0 с равенством только при σ2=1\sigma^2 = 1 (это следует из log⁡t≤t−1\log t \le t - 1 при t>0t > 0 с равенством только при t=1t = 1).

В матричном виде. Для dd-мерного q=N(μ,Σ)q = \mathcal N(\mu, \Sigma) с положительно определённой ковариационной матрицей Σ\Sigma

DKL(N(μ,Σ) ∥ N(0,I))=12(tr⁡Σ+μ⊤μ−d−log⁡det⁡Σ).\begin{aligned} &D_{\mathrm{KL}}\big(\mathcal N(\mu, \Sigma)\,\|\,\mathcal N(0, I)\big) \\ &\quad= \tfrac12\big(\operatorname{tr}\Sigma + \mu^\top\mu - d - \log\det\Sigma\big). \end{aligned}

Шаги те же, что выше. Логарифмы плотностей равны log⁡q(z)=−12log⁡det⁡(2πΣ)−12(z−μ)⊤Σ−1(z−μ)\log q(z) = -\tfrac12\log\det(2\pi\Sigma) - \tfrac12(z - \mu)^\top\Sigma^{-1}(z - \mu) и log⁡p(z)=−d2log⁡(2π)−12z⊤z\log p(z) = -\tfrac d2\log(2\pi) - \tfrac12 z^\top z. При z∼qz \sim q математическое ожидание квадратичной формы равно E[(z−μ)⊤Σ−1(z−μ)]=tr⁡(Σ−1 E[(z−μ)(z−μ)⊤])=tr⁡I=d\mathbb E\big[(z - \mu)^\top\Sigma^{-1}(z - \mu)\big] = \operatorname{tr}\big(\Sigma^{-1}\,\mathbb E[(z - \mu)(z - \mu)^\top]\big) = \operatorname{tr} I = d, поскольку скаляр равен своему следу и tr⁡(AB)=tr⁡(BA)\operatorname{tr}(AB) = \operatorname{tr}(BA). Точно так же E[z⊤z]=tr⁡Σ+μ⊤μ\mathbb E[z^\top z] = \operatorname{tr}\Sigma + \mu^\top\mu, а слагаемые с 2π2\pi сокращаются. Для диагональной матрицы энкодера Σ=diag⁡(σ2)\Sigma = \operatorname{diag}(\sigma^2) имеем tr⁡Σ=∑jσj2\operatorname{tr}\Sigma = \sum_j \sigma_j^2 и log⁡det⁡Σ=∑jlog⁡σj2\log\det\Sigma = \sum_j \log\sigma_j^2, так что формула распадается на сумму одномерных слагаемых. Например, μ=(1,0)\mu = (1, 0) и σ=(1,0.5)\sigma = (1, 0.5) дают 0.5+0.318=0.8180.5 + 0.318 = 0.818 ната (nats) — сумму второй и четвёртой строк таблицы ниже. Полная ковариационная матрица позволила бы координатам кода ещё и коррелировать, и у корреляции своя цена: при μ=0\mu = 0, единичных дисперсиях и коэффициенте корреляции ρ\rho имеем det⁡Σ=1−ρ2\det\Sigma = 1 - \rho^2, а KL равна −12log⁡(1−ρ2)-\tfrac12\log(1 - \rho^2), около 0.1440.144 ната при ρ=0.5\rho = 0.5. Диагональное апостериорное распределение VAE такие корреляции выразить вообще не может.

Как это читать: модель платит штраф, если μ≠0\mu \ne 0 или σ≠1\sigma \ne 1, и у штрафа вполне определённая форма.

  • Сдвиг среднего стоит 12μ2\tfrac12\mu^2: 0.5 при μ=1\mu = 1 и 2 при μ=2\mu = 2.
  • Уменьшение дисперсии стоит 12σ2−log⁡σ−12≈−log⁡σ−12\tfrac12\sigma^2 - \log\sigma - \tfrac12 \approx -\log\sigma - \tfrac12 при малых σ\sigma, поэтому штраф растёт лишь логарифмически: точные значения — 1.81 при σ=0.1\sigma = 0.1 и 4.11 при σ=0.01\sigma = 0.01. При σ→0\sigma \to 0 штраф неограниченно растёт, так что детерминированный точечный код, как в обычном автоэнкодере, заплатил бы бесконечный штраф. Точечная масса не абсолютно непрерывна относительно гауссианы, поэтому её KL бесконечна; см. случай «атом против плотности» в заметке Подгонка распределений с помощью KL.
  • Увеличение дисперсии стоит 12σ2−log⁡σ−12\tfrac12\sigma^2 - \log\sigma - \tfrac12, что растёт как 12σ2\tfrac12\sigma^2.

Поэтому каждый вход может позволить себе собственную довольно узкую гауссиану со смещённым центром, когда это помогает реконструкции, но никогда — одну точку.

Рисунок

Штраф KL растёт лишь логарифмически при σ → 0

KL-дивергенция относительно стандартного нормального распределения как функция σ и μДва графика KL-дивергенции между N(mu, sigma в квадрате) и N(0, 1). Первый — при mu = 0 как функция sigma от 0 до 3: U-образная кривая с минимумом 0 при sigma = 1, значением 1.81 при sigma = 0.1, 0.32 при sigma = 0.5 и 0.81 при sigma = 2; при малых sigma она растёт как минус log sigma минус одна вторая и уходит в бесконечность при sigma, стремящемся к 0. Второй — при sigma = 1 как функция mu от минус 2.5 до 2.5: парабола одна вторая mu в квадрате, 0.5 при mu = 1 и 2 при mu = минус 2, минимум 0 при mu = 0.μ = 0, меняем σ012300.5123σKL, наты1.810.320.81≈ −log σ − ½,→ ∞ при σ → 0½σ² − log σ − ½σ = 1, меняем μ0123-2-1012μKL, наты20.50½ μ²KL-дивергенция относительно стандартного нормального распределения как функция σ и μДва графика KL-дивергенции между N(mu, sigma в квадрате) и N(0, 1). Первый — при mu = 0 как функция sigma от 0 до 3: U-образная кривая с минимумом 0 при sigma = 1, значением 1.81 при sigma = 0.1, 0.32 при sigma = 0.5 и 0.81 при sigma = 2; при малых sigma она растёт как минус log sigma минус одна вторая и уходит в бесконечность при sigma, стремящемся к 0. Второй — при sigma = 1 как функция mu от минус 2.5 до 2.5: парабола одна вторая mu в квадрате, 0.5 при mu = 1 и 2 при mu = минус 2, минимум 0 при mu = 0.μ = 0, меняем σ012300.5123σKL, наты1.810.320.81≈ −log σ − ½,→ ∞ при σ → 0½σ² − log σ − ½σ = 1, меняем μ0123-2-1012μKL, наты20.50½ μ²
Замкнутая форма ½(μ² + σ² − 1 − log σ²) в натах. Первая панель: при μ = 0 уменьшение σ стоит ½σ² − log σ − ½ ≈ −log σ − ½ для малых σ, так что даже σ = 0.1 стоит всего 1.81. Штраф конечен при любом σ > 0, но при σ → 0 медленно растёт без ограничений; кривая уходит за верхний край графика при σ ≈ 0.025. Код из одной точки заплатил бы бесконечный штраф. Увеличение дисперсии стоит ½σ² − log σ − ½, что растёт как σ²/2. Вторая панель: при σ = 1 сдвиг среднего стоит ½μ². Штраф равен нулю только при μ = 0, σ = 1 (красные кольца).
μ\muσ\sigmaDKLD_{\mathrm{KL}} (наты, nats)
010
110.5
212
00.50.318
020.807
00.11.808
00.014.105

Какое распределение должно совпадать с априорным? Слагаемое KL тянет каждое q(z∣x)q(z \mid x) к априорному распределению лишь настолько, насколько позволяет реконструкция. Чтобы увидеть, чего оно требует от кодов в целом, возьмём NN обучающих изображений x1,…,xNx_1, \dots, x_N и определим агрегированное апостериорное распределение (aggregate posterior) — смесь всех их апостериорных распределений:

q(z)=1N∑n=1Nq(z∣xn).q(z) = \frac1N \sum_{n=1}^{N} q(z \mid x_n) .

Будем считать индекс nn случайной величиной, равномерно распределённой на {1,…,N}\lbrace 1, \dots, N\rbrace, так что q(n,z)=1N q(z∣xn)q(n, z) = \tfrac1N\, q(z \mid x_n). Тогда среднее слагаемое KL в ELBO распадается на две части (Hoffman and Johnson, 2016, формулы 11–12):

1N∑n=1NDKL(q(z∣xn) ∥ p(z))=Iq(n;z)+DKL(q(z) ∥ p(z)).\begin{aligned} &\frac1N \sum_{n=1}^{N} D_{\mathrm{KL}}\big(q(z \mid x_n)\,\|\,p(z)\big) \\ &\quad= I_q(n; z) + D_{\mathrm{KL}}\big(q(z)\,\|\,p(z)\big). \end{aligned}

Здесь Iq(n;z)=Eq(n,z)[log⁡q(n∣z)q(n)]I_q(n; z) = \mathbb E_{q(n, z)}\big[\log \frac{q(n \mid z)}{q(n)}\big] — взаимная информация (mutual information) между индексом изображения и его кодом; она лежит между 0 и log⁡N\log N. Второе слагаемое — маргинальная KL (marginal KL) между агрегированным апостериорным распределением и априорным. Чтобы проверить тождество, запишем по теореме Байеса для q(n,z)q(n, z) отношение q(z∣xn)/p(z)=(q(z)/p(z))⋅(q(n∣z)/q(n))q(z \mid x_n)/p(z) = \big(q(z)/p(z)\big)\cdot\big(q(n \mid z)/q(n)\big) и возьмём математическое ожидание его логарифма по q(n,z)q(n, z): первый множитель даёт маргинальную KL, а второй — взаимную информацию. Хорошая реконструкция требует, чтобы код идентифицировал изображение, поэтому это слагаемое должно оставаться большим, и именно поэтому каждое отдельное апостериорное распределение узкое. Чего-то от априорного распределения требует только второе слагаемое: смесь q(z)q(z) должна заполнить N(0,I)\mathcal N(0, I), не оставляя дыр. Обучение подталкивает смесь к априорному распределению, но совпадение получается лишь приближённым. Для VAE с 10 латентными измерениями на бинаризованном MNIST Hoffman и Johnson получают взаимную информацию, близкую к её максимуму log⁡N\log N, и маргинальную KL DKL(q(z) ∥ p(z))D_{\mathrm{KL}}(q(z)\,\|\,p(z)), равную 8.35 ната (§4, таблица 1). Там, где q(z)q(z) оставляет дыры, сэмплы из априорного распределения попадают в области, которые декодер видел редко, и декодируются плохо.

Метка как условие: условный VAE#

Базовому VAE нельзя указать, что генерировать. Условный VAE (CVAE) добавляет наблюдаемое условие cc, например метку класса или вектор бинарных атрибутов, в каждую часть модели (Sohn, Lee and Yan, 2015, раздел 4):

  • априорное распределение pθ(z∣c)p_\theta(z \mid c), часто просто фиксированное N(0,I)\mathcal N(0, I) при любом cc;
  • декодер pθ(x∣z,c)p_\theta(x \mid z, c);
  • энкодер qφ(z∣x,c)=N(μφ(x,c),σφ2(x,c))q_\varphi(z \mid x, c) = \mathcal N\big(\mu_\varphi(x, c), \sigma_\varphi^2(x, c)\big).

Распределение изображений модели при заданном условии — pθ(x∣c)=∫pθ(x∣z,c) pθ(z∣c) dzp_\theta(x \mid c) = \int p_\theta(x \mid z, c)\, p_\theta(z \mid c)\, dz. Вывод ELBO проходит без изменений, если в условие каждого распределения добавить cc (Sohn et al., формула 4):

log⁡pθ(x∣c)≥Eqφ(z∣x,c)[log⁡pθ(x∣z,c)]−DKL(qφ(z∣x,c) ∥ pθ(z∣c)),\begin{aligned} \log p_\theta(x \mid c) \ge{}& \mathbb E_{q_\varphi(z \mid x, c)}\big[\log p_\theta(x \mid z, c)\big] \\ &- D_{\mathrm{KL}}\big(q_\varphi(z \mid x, c)\,\|\,p_\theta(z \mid c)\big), \end{aligned}

и зазор снова равен KL-дивергенции DKL(qφ(z∣x,c) ∥ pθ(z∣x,c))D_{\mathrm{KL}}\big(q_\varphi(z \mid x, c)\,\|\,p_\theta(z \mid x, c)\big). Обучение максимизирует эту оценку, усреднённую по парам (x,c)(x, c) из данных, с той же репараметризацией и, для фиксированного априорного распределения N(0,I)\mathcal N(0, I), с той же KL в замкнутой форме. Обучаемому гауссовскому априорному распределению pθ(z∣c)p_\theta(z \mid c) нужна общая формула KL между двумя гауссианами; для диагональных это одномерная формула, просуммированная по координатам. В сетях cc обычно подаётся конкатенацией: ко входу энкодера или к его признакам и к zz перед декодером.

Что меняет условие. Декодер теперь получает cc даром, а за каждый нат, который несёт код, приходится платить KL. Поэтому целевая функция поощряет не включать в zz то, что уже сообщает cc, и код склонен хранить то, чего метка не описывает, например позу или освещение. Чтобы сгенерировать изображение, фиксируем cc, берём z∼pθ(z∣c)z \sim p_\theta(z \mid c) и декодируем. Если сохранить zz и изменить cc, например один из 40 бинарных атрибутов лиц CelebA, мы запрашиваем то же изображение с другим значением атрибута; насколько чисто это получается, зависит от того, какая часть атрибута просочилась в zz. Та же конструкция добавляет условие в любую модель этого семейства, включая декодер-поток условного VAPNEV, а условный GAN — её состязательный аналог.

Итоги#

  • Правдоподобие pθ(x)p_\theta(x) и апостериорное распределение pθ(z∣x)p_\theta(z \mid x) модели с латентными переменными вычислительно неразрешимы, потому что оба требуют интегрирования по латентному пространству.
  • Энкодер строит приближённое апостериорное распределение qφ(z∣x)q_\varphi(z \mid x) — диагональную гауссиану.
  • Обучение максимизирует ELBO, то есть реконструкцию минус KL-дивергенцию относительно априорного распределения; это нижняя оценка log⁡pθ(x)\log p_\theta(x) с зазором DKL(q ∥ p(z∣x))D_{\mathrm{KL}}(q\,\|\,p(z\mid x)).
  • Трюк репараметризации делает сэмплируемое слагаемое реконструкции дифференцируемым; слагаемое KL известно в замкнутой форме.
  • Фиксированное априорное распределение упорядочивает латентное пространство, поэтому декодирование z∼N(0,I)z \sim \mathcal N(0, I) порождает новые изображения. Агрегированное апостериорное распределение совпадает с априорным лишь приближённо, и дыры в нём дают плохие сэмплы.
  • Условный VAE добавляет метку cc в условие априорного распределения, энкодера и декодера и максимизирует ту же оценку, теперь для log⁡pθ(x∣c)\log p_\theta(x \mid c); ему можно указать, что генерировать.

Ноутбук#

Реализация следует ноутбуку о VAE из репозитория HSE-LAMBDA Deep Generative Models (закреплённый коммит; ячейки нумеруются с 1, считая все ячейки подряд). В ноутбуке нет сохранённых выходов, поэтому он документирует процедуру, а не результаты.

  • Ячейки 4–5: лица CelebA, приведённые к размеру 64×6464 \times 64 RGB и нормализованные в [−1,1][-1, 1], размер батча 128, drop_last=True. CelebA содержит 202 599 выровненных и обрезанных лиц размером 178 × 218 пикселей (ширина × высота), у каждого 40 бинарных атрибутов; класс датасета возвращает атрибуты, а этот ноутбук их не использует. Resize((64, 64)) масштабирует две стороны независимо и меняет соотношение сторон с 178 : 218 на 1 : 1; Resize(64) с последующим CenterCrop(64) сохранили бы его.
  • Ячейки 6–7: почему обычные автоэнкодеры не могут генерировать, и рассуждение через теорему Байеса, которое приводит к приближённому апостериорному распределению.
  • Ячейки 10 и 12: в энкодере четыре свёртки 4×44 \times 4 с шагом 2 и числом каналов 32→64→128→25632 \to 64 \to 128 \to 256, за каждой следуют LeakyReLU и затем BatchNorm (кроме последней), так что изображение 64×6464 \times 64 превращается в карту 4×4×2564 \times 4 \times 256; она вытягивается в 4096 признаков для двух линейных выходных слоёв (heads) mean_layer и logvar_layer по 100 выходов в каждом. Декодер не является буквальным зеркалом энкодера: линейный слой из 100 в 4096 нейронов с ReLU, изменение формы на 256×4×4256 \times 4 \times 4, затем четыре блока, каждый из которых состоит из повышения разрешения (×2\times 2) и свёртки 3×33 \times 3 (256→128→64→32→3256 \to 128 \to 64 \to 32 \to 3 каналов), на выходе Tanh со значениями в [−1,1][-1, 1]. nn.Upsample(scale_factor=2) без аргумента mode повышает разрешение методом ближайшего соседа.
  • Ячейка 15: класс VAE с latent_dim = 100. reparametrize вычисляет std_dev = exp(0.5 * logvar), берёт epsilon = randn_like(std_dev) и возвращает mean + epsilon * std_dev; sample(n) декодирует z∼N(0,I)z \sim \mathcal N(0, I).
  • Ячейки 16–17: loss_function: квадратичная ошибка, просуммированная по пикселям и усреднённая по батчу, плюс kld_loss = -0.5 * sum(1 + logvar - mean² - exp(logvar)), усреднённая по батчу и умноженная на beta (по умолчанию 1). Это оценка отрицательной ELBO по одному сэмплу с s2=12s^2 = \tfrac12 из абзаца о реконструкции с точностью до константы. exp(logvar) внутри KL ограничена снизу значением 10−810^{-8}. Стабилизирующего эффекта это ограничение не даёт: оно меняет функцию потерь, только когда σ2<10−8\sigma^2 < 10^{-8}, а само слагаемое log⁡σ2\log\sigma^2 не ограничено. Текстовая ячейка 16 правильно приводит KL в матричном виде, 12(tr⁡Σ+μ⊤μ−d−log⁡det⁡Σ)\tfrac12(\operatorname{tr}\Sigma + \mu^\top\mu - d - \log\det\Sigma), и её диагональный случай, но затем переписывает ∑ilog⁡σi2\sum_i \log\sigma_i^2 как ∥log⁡σ∥1\lVert\log\boldsymbol\sigma\rVert_1, что неверно: ∑ilog⁡σi2=2∑ilog⁡σi\sum_i \log\sigma_i^2 = 2\sum_i \log\sigma_i, а логарифмы могут быть отрицательными, поэтому в норме не сохраняются ни множитель 2, ни знак. Код в ячейке 17 использует правильную сумму.
  • Ячейки 18–21: обучение с Adam при шаге обучения (learning rate) 10−310^{-3} в течение 10 эпох с косинусным расписанием шага обучения (CosineAnnealingLR, T_max = 10); два слагаемых функции потерь логируются по отдельности, а после каждой эпохи декодируются 64 сэмпла из априорного распределения.
  • Ячейка 23: генерация из априорного распределения. Ячейка 24 (только текст) определяет функцию потерь β-VAE и распутывание на примере CelebA, где одна латентная координата отвечает за улыбку, а другая — за поворот головы (см. что даёт β); β-VAE не обучается, потому что train_vae вызывает loss_function со значением по умолчанию β=1\beta = 1.
  • Замечания о реализации. Логируемые и печатаемые значения функции потерь делятся на размер батча второй раз (mse_loss.item() / len(data), а суммы потерь на изображение за эпоху делятся на len(dataset)), поэтому они примерно в 128 раз меньше функции потерь на одно изображение. Модель ни разу не переключается в eval(): сэмплирование в ячейках 18 и 23 запускает BatchNorm декодера на статистиках сгенерированного батча и обновляет его скользящие средние.

Ноутбук с упражнениями 03_hw_vapnev.ipynb из того же репозитория продолжает эту модель. Ячейки 3–9 загружают CelebA: ячейка 5 применяет Resize(64) и CenterCrop(64) и переводит пиксели в [−1,1][-1, 1] преобразованием 2x−12x - 1, а ячейка 9 показывает 25 случайных лиц. Остальные ячейки формулируют задания и оставляют ячейки кода пустыми: ячейки 12–13 требуют обучить VAE на этих лицах и оценить его по FID; ячейки 14–15 требуют построить VAPNEV и его условную версию, описанные в следующей заметке; условная версия использует атрибуты как условие так же, как условный VAE. Единственные сохранённые выходы ноутбука — устройство, форма одного изображения и сетка лиц, так что цитировать нечего.

Дальше#

VAE обучает генератор через явную оценку правдоподобия и расплачивается за это размытостью и априорным распределением, которое его коды заполняют лишь приблизительно. Следующая заметка меняет части оценки: вес слагаемого KL, задающий, сколько может сообщать код, дискретный код, априорное распределение которого обучается после автоэнкодера, и точное правдоподобие потока вместо попиксельного слагаемого реконструкции.

Литература#