Понимание вариационных автоэнкодеров (VAE) от теории к практике с использованием PyTorch

VAE - это модели со скрытыми переменными [1,2]. Такие модели основаны на идее, что данные, сгенерированные моделью, могут быть параметризованы некоторыми переменными, которые будут генерировать некоторые конкретные характеристики данной точки данных. Эти переменные называются скрытыми переменными.

Одна из ключевых идей VAE заключается в том, что вместо того, чтобы пытаться явно построить скрытое пространство (пространство скрытых переменных) и брать из него образцы, чтобы найти образцы, которые действительно могли бы генерировать правильные выходные данные (как можно более близкие к нашему распределению), мы строим сеть, подобную кодеру-декодеру, которая разделена на две части:

  • Кодировщик учится генерировать распределение в зависимости от входных выборок X, из которых мы можем выбрать скрытую переменную, которая с большой вероятностью сгенерирует X выборок. Другими словами, мы изучаем набор параметров θ1, которые генерируют распределение Q (X, θ1), из которого мы можем выбрать скрытую переменную z, максимизирующую P (X | z).
  • Часть декодера учится генерировать выходные данные, которые принадлежат реальному распределению данных, учитывая скрытую переменную z в ​​качестве входных данных. Другими словами, мы изучаем набор параметров θ2, который генерирует функцию f (z, θ2), которая сопоставляет латентное распределение, которое мы узнали, с реальным распределением данных набора данных.

Чтобы понять математику, лежащую в основе вариационных автокодировщиков, мы рассмотрим теорию и увидим, почему эти модели работают лучше, чем старые подходы.

Эта статья будет охватывать следующие

  • Как определить конструкцию скрытого пространства
  • Как эффективно генерировать данные из выборки скрытого пространства.
  • Окончательная архитектура VAE
  • Некоторые эксперименты, показывающие интересные свойства VAE

1. Скрытые переменные модели

Модели со скрытыми переменными исходят из идеи, что данные, сгенерированные моделью, должны параметризоваться скрытыми переменными. Это название происходит от того факта, что, имея только точку данных, созданную моделью, мы не обязательно знаем, какие настройки скрытых переменных сгенерировали эту точку данных.

В более формальной обстановке у нас есть вектор скрытых переменных z в многомерном пространстве Z, который мы можем легко выбрать в соответствии с некоторой функцией плотности вероятности P ( z), определенный над Z. Тогда у нас есть семейство детерминированных функций f (z; θ), параметризованных вектор θ в некотором пространстве Θ, где f: Z × Θ → X. f является детерминированным, но если z является случайным и θ фиксированным, то f (z ; θ) - случайная величина в пространстве X.

Во время обучения мы оптимизируем θ таким образом, чтобы мы могли выбирать z из P (z) и с высокой вероятностью , имея f (z; θ) как можно ближе к X в наборе данных. Для этого нам нужно найти такие параметры θ, что:

Здесь мы просто заменяем f (z; θ) распределением P (X | z; θ), чтобы сделать зависимость X от z явной с помощью закона полной вероятности. Другое предположение, которое мы делаем, - это предположить, что P (W | z; θ) следует гауссовскому распределению N (X | f (z ; θ), σ * I) (При этом мы считаем, что сгенерированные данные почти такие же, как X, но не точно X).

Определение скрытого пространства

Как объяснялось в начале, предполагается, что скрытое пространство моделирует пространство переменных, влияющих на некоторые специфические характеристики нашего распределения данных. Мы можем представить, что если рассматриваемый нами набор данных состоит из автомобилей и что наше распределение данных представляет собой пространство всех возможных автомобилей, некоторые компоненты нашего скрытого вектора будут влиять на цвет, ориентацию или количество дверей автомобиля.

Однако быстро очень сложно явно определить роль каждого скрытого компонента, особенно когда мы имеем дело с сотнями измерений. В дополнение к этому, некоторые компоненты могут зависеть от других, что еще больше усложняет проектирование этого скрытого пространства вручную. Другими словами, это сложное распределение P (z) действительно сложно определить.

Решение

Чтобы преодолеть эту проблему, хитрость заключается в использовании математического свойства вероятностных распределений и способности нейронных сетей изучать некоторые детерминированные функции при некоторых ограничениях с обратным распространением.

Математическое свойство, которое делает проблему более решаемой, заключается в следующем:

Любое распределение в d измерениях можно получить, взяв набор d переменных, которые нормально распределены, и сопоставив их с помощью достаточно сложной функции.

Как следствие, мы можем произвольно решить, что наши скрытые переменные являются гауссианами, а затем построить детерминированную функцию, которая отобразит наше скрытое гауссовское пространство в сложное распределение, из которого мы будем производить выборку для генерации наших данных.

Детерминированная функция, необходимая для отображения нашего простого скрытого распределения в более сложное, которое будет представлять наше сложное скрытое пространство, затем может быть построена с использованием нейронной сети с некоторыми параметрами, которые можно точно настроить во время обучения.

2. Научитесь генерировать данные из скрытого пространства.

Прежде чем перейти к интересной части этой статьи, давайте вспомним нашу конечную цель:

У нас есть d-мерное латентное пространство, которое нормально распределено, и мы хотим изучить функцию f (z; θ2), которая будет отображать наше скрытое распределение с нашим реальным распределением данных. Другими словами, мы хотим выбрать скрытые переменные, а затем использовать эту скрытую переменную в качестве входных данных нашего генератора, чтобы сгенерировать выборку данных, которая будет как можно ближе к реальным точкам данных.

Нам все еще нужно решить две вещи:

  • Как мы можем эффективно исследовать наше скрытое пространство, чтобы обнаружить z, который максимизирует вероятность P (X | z)? (нам нужно найти правильный z для данного X во время обучения)
  • Как мы обучаем весь этот процесс, используя обратное распространение? (нам нужно найти цель, которая оптимизирует f для отображения P (z) в P (X))

Нахождение правильной скрытой переменной z для нашей выборки данных X

На практике для большинства z значение P (X | z) будет почти нулевым и, следовательно, почти ничего не даст нашей оценке P ( ИКС). Ключевая идея вариационного автокодировщика состоит в том, чтобы попытаться выбрать значения z, которые, вероятно, привели к X, и вычислить P (X) только на их основе. Для этого нам нужна новая функция Q (z | X), которая может принимать значение X и давать нам распределение по значениям z, которые могут дать X. Надеюсь, пространство Значения z, которые вероятны при Q, будут намного меньше, чем пространство всех z, которые, вероятно, будут при предшествующем P (z).

Эта часть VAE будет кодировщиком, и мы будем предполагать, что Q будет изучен во время обучения нейронной сетью, сопоставляющей вход X с выходом Q (z | X), который будет распределением, из которого мы, скорее всего, найдем хороший z для генерации этого конкретного X.

Обучение модели с обратным распространением

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

Начнем с кодировщика, мы хотим, чтобы Q (z | X) было как можно ближе к P (X | z). Чтобы измерить, насколько близки эти два распределения, мы можем использовать дивергенцию Кульбака-Лейблера D между двумя распределениями:

С помощью математики мы можем переписать это равенство в более интересной форме.

Применяя правило Байеса к P (z | X), получаем:

Что эквивалентно:

Давайте посмотрим на эти формулы

  • Часть A: левый член не очень интересен для нашей настройки обратного распространения ошибки (мы не знаем простого выражения для P (X)), но log (P (X)) на самом деле то, что нам нужно. чтобы максимизировать заданное значение z, и здесь мы видим, что мы можем сделать это, минимизируя правую часть (делая Q (z | X) как можно ближе к P (z | X)). Об этом мы и говорили в начале.
  • Часть B: этот термин гораздо интереснее, поскольку мы знаем P (X | z) (это наша часть декодера - ›генератор) и Q (z | X) (это наш кодировщик). Здесь мы видим, что для того, чтобы максимизировать этот член, нам нужно максимизировать log (P (X | z)), что означает, что мы не хотим максимизировать логарифмическую вероятность нашей вероятности и минимизировать расхождение KL между Q (z | X) и P (z).

Чтобы упростить вычисление части B, нужно предположить, что Q (z | X) является гауссовским распределением N (z | mu (X, θ1), sigma (X, θ1)), где θ1 - это параметры, полученные нашей нейронной сетью из нашего набора данных.

С нашими формулами остается неясным один вопрос: как вычислить математическое ожидание во время обратного распространения ошибки?

Обработка оператора ожидания

Один из способов - выполнить несколько прямых проходов, чтобы иметь возможность вычислить математическое ожидание журнала (P (X | z)), но это неэффективно с вычислительной точки зрения. Надеюсь, поскольку мы находимся в стохастическом обучении, мы можем предположить, что выборка данных Xi, которую мы используем в течение эпохи, является репрезентативной для всего набора данных, и поэтому разумно считать, что журнал (P (Xi | zi)), который мы получаем из этого образца Xi, и зависимо сгенерированный zi представляет математическое ожидание по Q от log (P (X | z)).

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

3. Окончательная архитектура VAE

Мы можем узнать резюме окончательной архитектуры VAE. Как было объявлено во введении, сеть разделена на две части:

  • Кодировщик, который учится генерировать распределение в зависимости от входных выборок X, из которых мы можем выбрать скрытую переменную, которая с большой вероятностью сгенерирует X выборок. Эта часть должна быть оптимизирована, чтобы обеспечить гауссовость нашего Q (z | X).
  • Часть декодера учится генерировать выходные данные, которые принадлежат реальному распределению данных, учитывая скрытую переменную z в ​​качестве входных данных. Эта часть отображает выбранный z (первоначально из нормального распределения) в более сложное скрытое пространство (которое фактически представляет наши данные) и из этой сложной скрытой переменной z генерирует точку данных, которая максимально приближена к реальной точке данных из наше распространение.

4. Эксперименты с ВАЭ.

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

Глобальная архитектура в PyTorch

Обучение

На следующих графиках показаны результаты, которые мы получаем во время тренировки. Для этой демонстрации VAE были обучены на наборе данных MNIST [3]. Каждые 10 эпох мы наносим на график входной X и сгенерированные данные, которые дали VAE для этого заданного входа.

Скрытое пространство

Одна интересная особенность VAE заключается в том, что латентное пространство, изученное во время обучения, обладает некоторыми хорошими свойствами непрерывности. Мы можем визуализировать эти свойства, рассматривая двумерное скрытое пространство, чтобы иметь возможность легко визуализировать наши точки данных в 2D.

Глядя на перераспределение выборок набора данных MNIST в двумерном латентном пространстве, изученном во время обучения, мы видим, что похожие цифры сгруппированы вместе (3 зеленого цвета сгруппированы вместе и близки к 8, которые очень похожи).

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

Вывод

Вариационные автокодировщики - действительно удивительный инструмент, решающий некоторые действительно сложные проблемы генеративных моделей благодаря мощности нейронных сетей. По сравнению с предыдущими методами VAE решают две основные проблемы:

  • Как выбрать наиболее релевантные скрытые переменные в скрытом пространстве для получения заданного результата.
  • Как сопоставить распределение скрытого пространства с реальным распределением данных.

Однако у VAE есть и недостатки:

  • Сгенерированные изображения размыты, потому что среднеквадратическая ошибка приводит к сходимости генератора к усредненному оптимуму.

Генеративные неблагоприятные сети (GAN) решают последнюю проблему за счет использования дискриминатора вместо потери среднеквадратичной ошибки и создают гораздо более реалистичные изображения. Однако скрытое пространство GAN очень сложно контролировать, и оно не имеет (в классической постановке) свойств непрерывности, как VAE, что иногда необходимо для некоторых приложений.

Ссылка

[1] Doersch, C., 2016. Учебное пособие по вариационным автокодировщикам. Препринт arXiv arXiv: 1606.05908.

[2] Kingma, D.P. и Веллинг, М., 2019. Введение в вариационные автокодеры. Препринт arXiv arXiv: 1906.02691.

[3] Набор данных MNIST, http://yann.lecun.com/exdb/mnist/

Код