Из моей последней эскапады в литературу по глубокому обучению я представляю вам эту статью Oord et. др. который представляет идею использования дискретных скрытых вложений для вариационных автокодировщиков. Предлагаемая модель получила название векторных квантованных вариационных автоэнкодеров (VQ-VAE). Мне очень понравилась идея и полученные результаты, но я нашел на удивление мало ресурсов для развития понимания. Это попытка помочь другим, кто может отважиться зайти в эту область после меня.

Как и многие другие люди, я выбрал генеративные модели с вариационными автоэнкодерами (VAE). В отличие от GAN, их легче обучать и рассуждать (не оскорбления, дорогие GAN). Забегая вперед, я предполагаю, что вы имеете некоторое представление о VAE. Если нет, я предлагаю прочитать этот пост, я нашел его одним из самых простых.

Основная идея

Так что же здесь такого особенного? Как вы помните, VAE состоят из 3 частей:

  1. Сеть кодировщика, которая параметризует апостериорную q (z | x) по латентным
  2. Априорное распределение p (z)
  3. Декодер с распределением p (x | z) по входным данным

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

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

  1. Кодеры моделируют категориальное распределение, выборка из которого вы получаете целые значения
  2. Эти целые значения используются для индексации словаря вложений.
  3. Затем индексированные значения передаются в декодер.

Зачем это делать?

Многие важные объекты реального мира дискретны. Например, в изображениях могут быть такие категории, как «Кошка», «Автомобиль» и т. Д., И может не иметь смысла интерполировать между этими категориями. Дискретные представления также легче моделировать, поскольку каждая категория имеет одно значение, тогда как если бы у нас было непрерывное скрытое пространство, нам нужно будет нормализовать эту функцию плотности и изучить зависимости между различными переменными, которые могут быть очень сложными.

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

Архитектура

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

n: размер партии

h: высота изображения

w: ширина изображения

c: количество каналов во входном изображении

d: количество каналов в скрытом состоянии

Теперь работу можно объяснить следующими шагами:

  1. Кодер принимает изображения x: (n, h, w, c) и выдает выходные данные z_e: (n, h, w, d)
  2. Слой векторного квантования принимает z_e и выбирает вложения из словаря на основе расстояния и выводит z_q (мы обсудим это позже, не беспокойтесь)
  3. Декодер потребляет z_q и выводит x ’, пытаясь воссоздать ввод x

Слой векторного квантования

Работа уровня VQ может быть объяснена шестью шагами, пронумерованными на рис.2:

  1. Изменить форму: все измерения, кроме последнего, объединяются в одно, так что у нас есть n * h * w векторов размерности d.
  2. Расчет расстояний: для каждого из n * h * w векторов мы вычисляем расстояние от каждого из k векторов словаря встраивания, чтобы получить матрицу формы (n * h * w, k)
  3. Argmin: для каждого из n * h * w векторов мы находим индекс ближайшего из k векторов из словаря.
  4. Индекс из словаря: индексирование ближайшего вектора из словаря для каждого из n * h * w векторов.
  5. Изменить форму: преобразовать обратно в форму (n, h, w, d)
  6. Копирование градиентов: если вы проследили до сих пор, то поймете, что обучить эту архитектуру с помощью обратного распространения невозможно, поскольку градиент не проходит через argmin. Следовательно, мы пытаемся приблизиться, копируя градиенты от z_q обратно к z_e. Таким образом, мы фактически не сводим к минимуму функцию потерь, но все же можем передать некоторую информацию обратно для обучения.

Функция потерь

Общая потеря фактически состоит из трех компонентов:

  1. Реконструкция потерь: оптимизирует декодер и кодировщик:
reconstruction_loss = -log( p(x|z_q) )

2. Потеря кодовой книги: из-за того, что градиенты обходят внедрение, мы используем алгоритм обучения словаря, который использует ошибку l 2 для перемещения векторов внедрения e к выходу кодировщика:

codebook_loss =  ‖ sg[z_e(x)]− e ‖^2
// sg represents stop gradient operator meaning no gradient 
// flows through whatever it's applied on

3. Потеря обязательств: поскольку объем встраиваемого пространства безразмерен, он может произвольно увеличиваться, если вложения e не обучаются так быстро, как параметры кодировщика, и поэтому мы добавляем потерю приверженности, чтобы убедиться, что кодировщик фиксирует встраивание

commitment_loss = β‖ z_e(x)− sg[e] ‖^2
// β is a hyperparameter that controls how much we want to weigh 
// commitment loss compared to other components

Внимание! Обратите внимание, что мы обучаем как встраивание словарей, так и сеть кодировщика и декодера.

Полученные результаты

В документе представлены современные результаты по изображениям, тексту, а также видео.

Вы можете найти результаты по аудио здесь: https://avdnoord.github.io/homepage/vqvae/

Код

Есть несколько реализаций, доступных в Tensorflow, Pytorch, а также в keras. Вы можете просмотреть их здесь.

Заключение

Из этой статьи можно извлечь две основные идеи:

  1. Как обучить дискретные скрытые вложения и их важность
  2. Как аппроксимировать градиенты в случае недифференцируемых функций

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

Примечание. Не стесняйтесь задавать любые сомнения или оставлять отзывы / предложения. Все используемые здесь диаграммы созданы автором. Не стесняйтесь использовать их вместе с благодарностью :-)

📝 Прочтите этот рассказ позже в Журнале.

👩‍💻 Просыпайтесь каждое воскресное утро и слушайте самые интересные истории недели в области технологий, которые ждут вас в вашем почтовом ящике. Прочтите информационный бюллетень« Примечательно в технологиях .