Подробно рассмотрим алгоритм генеративного машинного обучения, называемый вариационным автоэнкодером. Следите за реализацией PyTorch в следующем посте!

Эта статья была впервые опубликована 3 ноября 2020 г. в официальном блоге Scaleway и размещена здесь для вашего удобства.

До появления ГАНов были ВАЭ. (И до того, как появились VAE, были AE. Даже не начинайте меня говорить о VAE-GAN; давайте сначала расшифруем все эти аббревиатуры, прежде чем они выйдут из-под контроля!)

  • AE: Автоэнкодер (1991)
  • VAE: Вариационный автоэнкодер (2013)
  • GAN: Генеративная состязательная сеть (2014)

Теперь давайте рассмотрим их по очереди.

Автоэнкодер

Как описать лицо?

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

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

Даже если бы в вашем распоряжении была фотография выше, ваше описание, вероятно, не начиналось бы со слов «Ну, если бы я создал ее портрет размером 1024 на 1024 пикселя, значение пикселя в левом нижнем углу было бы…». на самом деле не нужны числовые значения 1024 x 1024 для характеристики чьего-либо лица - не говоря уже о том, что этот тип словесного изображения не является естественным для нас, людей. Вместо этого вы могли бы сказать, что у нее были рыжеватые волнистые волосы, круглое лицо, нос среднего размера и зеленые глаза. Затем судебно-медицинский эксперт использует свои знания о том, как выглядит человеческое лицо, плюс ваше описание, чтобы создать набросок женщины-грабителя. Результирующий цифровой эскиз действительно будет состоять из пикселей, но это не то представление, которое вы и художник использовали в процессе.

Что такое лицо нейронной сети?

Искусственная нейронная сеть, обученная портретам людей, развивает собственные представления о том, что представляет собой человеческое лицо. Для компьютера в целом фотография выше представляет собой не что иное, как целые числа 1024 x 1024 (x 3 из-за трех цветовых каналов на пиксель). Однако обученная искусственная нейронная сеть может описать это, используя вместо этого определенные характеристики - что очень похоже на то, как мы это делаем. Эти характеристики будут закодированы численно и, следовательно, могут быть объединены вместе, чтобы сформировать одномерный массив чисел, то есть вектор. Размерность вектора будет варьироваться в зависимости от решаемой задачи, но, как правило, она будет намного ниже, чем размеры исходного ввода: для наших портретов 1024x1024 мы, вероятно, можем обойтись несколькими сотнями (скажем, 512) для большинства практических целей. Эти 512 характеристик могут (и, по всей вероятности, будут) отличаться от того, что мы могли себе представить: например, присвоение определенной переменной расстоянию между глазами человека, другой переменной для кодирования тона кожи человека и т. д. Но они будут иметь такой же смысл для обученной сети, как слова «волнистые рыжеватые волосы» для нас.

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

Эти две части часто, но не обязательно, симметричны по своей архитектуре. Кодировщик - это сверточная сеть, которая обучена распознавать особенности входных изображений: чем глубже слой, тем абстрактнее объекты. То, что нам нужно, - это результат слоя узкого места, который является описанием входа нейронной сетью. Это низкоразмерное представление иногда называют скрытым представлением (в НЛП вы также можете найти его как вектор контекста для фразы).

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

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

Для чего мы используем автоэнкодеры?

Автоэнкодеры имеют множество приложений в области компьютерного зрения и за ее пределами. Наиболее очевидным из них является механизм сжатия данных, который они предоставляют: данные могут быть сжаты через сеть кодировщика и восстановлены из их скрытой формы через декодер. Кроме того, поскольку целью автокодировщика является изучение наиболее «полезных» функций данных, он также может служить для удаления шума из входных данных. Чтобы облегчить обучение для этой задачи, мы можем добавить синтетический шум к входам, которые подаются в кодировщик, и сравнить декодированные выходные данные с исходными изображениями без шума. (Тот же подход может быть применен, например, к проблеме раскрашивания изображения - хотя на этом этапе было бы нецелесообразно называть вашу модель автоэнкодером.)

Автоэнкодер - это широко используемый алгоритм машинного обучения без учителя. Говоря об обучении без учителя, еще один популярный подход без учителя - это кластеризация. Как следует из названия, кластеризация сводится к назначению точек данных, которые разделяют определенные характеристики (т. Е. Расположены близко друг к другу в пространстве функций), в группы. Однако чем выше число измерений указанного пространства признаков, тем сложнее выполнить кластеризацию. Здесь автоэнкодер может пригодиться в качестве метода уменьшения размерности: сначала данные используются для обучения автоэнкодера, затем автоэнкодер используется для кодирования данных в скрытое пространство меньшей (er) размерности и, наконец, алгоритм кластеризации. выполняется на закодированных точках данных.

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

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

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

В «ванильном» автоэнкодере из предыдущего раздела декодер генерирует восстановленные изображения из скрытых векторов, в которые он кодирует обучающие изображения. В принципе, мы можем рассматривать декодер как отдельную нейронную сеть, которая просто принимает векторы определенной размерности в качестве входных данных (например, в приведенном выше примере автокодировщика лиц мы договорились установить эту размерность равной 512). Что произойдет, если вместо кодирования существующего изображения как скрытого вектора мы выберем случайный 512-мерный вектор и пропустим его через декодер? Ну вообще ничего особенного. Скорее всего, вы получите довольно шумный вывод, который не будет похож на домен, с данными которого вы работали. Можем ли мы сделать лучше? Спросим ВАЭ.

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

На рисунке ниже, взятом из Интуитивное понимание вариационных автоэнкодеров, вы найдете пример приложения автоэнкодер + кластеризация, которое мы обсуждали выше. Здесь изображения рукописных цифр MNIST были закодированы в двухмерном пространстве, что позволяет нам отображать их как точки на плоскости. Естественно, есть много встраиваний, которые подойдут для этой работы, и два таких примера показаны ниже:

В обоих случаях точки разного цвета (т. Е. Изображения, соответствующие разным классам) имеют явную тенденцию к формированию кластеров. Однако учтите следующее. Были ли у вас проблемы с различением 1 и 7? Мы все были в этом, особенно когда речь идет о североамериканской 7 (без тире в центре) и европейской 1 (с маленьким беретом наверху). Можно было бы подумать, что интерполяция между этими двумя цифрами была бы тривиальной, но это не относится к универсальному автоэнкодеру. Посмотрите на график слева на рисунке выше: фиолетовые точки («семерки») и желто-желтые («единицы») разделены пустым пространством. Поэтому, если вы выберете точку между ними и подадите ее в качестве входных данных для вашего декодера, модель не будет знать, что с ней делать! Однако вы можете заставить скрытое пространство, в котором живут ваши двумерные вложения MNIST, иметь гораздо более упорядоченную структуру, такую ​​как та, что справа. Здесь вы можете выбрать практически произвольную точку в разноцветной «капле» MNIST, и декодер сгенерирует что-то вроде MNIST: либо цифру, которую можно четко распознать как таковую, либо, по крайней мере, изображение с характеристиками, подобными цифрам. Для произвольного ввода выходное изображение не будет получено из обучающего набора, скорее оно будет сгенерировано с нуля (ну, технически из двумерного вектора ввода, но вы понимаете, что я имею в виду) .

Такая структура скрытого пространства достигается за счет комбинации кодирования обучающих выборок как распределений, а не векторов, и введения того, что называется дивергенцией Кульбака-Лейблера, в дополнение к стандартному члену автокодера в функции потерь. (Дивергенция Кульбака-Лейблера - это то, что заставляет распределение латентных представлений напоминать гауссово.) Оставив в стороне математику, давайте посмотрим, что на самом деле происходит во время обучения VAE:

  1. Сначала обучающая выборка кодируется как распределение по скрытому пространству. То есть вместо одного вектора r1 (r для представления) мы получаем два вектора: μ1 и σ1. (где μ и σ соответствуют среднему значению и стандартному отклонению для распределения). Выражаясь менее математически, вместо отображения в точку в l-мерном скрытом пространстве, входные данные отображаются в нечеткую l-мерную сферу.
  2. Затем вектор (который мы могли бы также назвать r1) выбирается из распределения, к которому мы пришли на предыдущем шаге. Другими словами, из полученной нечеткой сферы выбирается конкретная точка.
  3. С этого момента мы действуем так же, как и с обычным невариационным автокодером: пропускаем r1 через декодер, генерируем выходное изображение и вычисляем ошибку реконструкции (пиксельная разница между входным изображением и сгенерированный вывод). После этого мы можем распространять вычисленные градиенты по сети и соответствующим образом обновлять ее параметры.

Каждый из трех вышеперечисленных шагов довольно прост, но есть одна тонкость, которую легко упустить. На втором этапе мы выбираем вектор из распределения, в которое были закодированы наши входные данные. Это, конечно, то, что мы можем сделать, в torch даже есть метод, который мы можем использовать для этой операции. torch.normal принимает среднее значение и стандартное отклонение и возвращает тензор в форме среднего, полученный из соответствующего распределения. Однако есть одна проблема: как запустить обратное распространение через такой узел? Обратное распространение через операцию выборки не определено. Чтобы обойти эту проблему, мы собираемся использовать следующий трюк репараметризации: установите r1 равным μ1 + σ1 * ε, где стохастическая часть происходит от ε, вектора, взятого из нормального распределения со средним значением 0 и дисперсией. 1, eps = torch.randn_like(mean). Теперь, когда мы разделили операцию выборки на стохастическую часть (где фактически происходит выборка) и детерминированную (имея в виду векторы μ1 и σ1), мы можем запустить обратное распространение через последнее и покончить с этим.

Вы знали…

Smart Labeling от Scaleway - это платформа для аннотации управляемых данных, которая поможет вам пометить данные, которые вам нужны для проектов компьютерного зрения (2021 г.) и NLP (2022 г.)! Благодаря автоматической предварительной маркировке и функциям активного обучения в нашей дорожной карте ваш набор данных будет готов в кратчайшие сроки. Зарегистрируйтесь, чтобы получать уведомления, когда Smart Labeling станет доступным!