Недавно я получил ДУБ-1 (камера с ИИ-чипом на борту) и понятия не имел, что с ним делать. Я также недавно прочитал статью 2017 года, посвященную адаптивной нормализации экземпляров (AdaIN), и мне она понравилась.

Вот где приходит этот проект. Учитывая входное изображение (скажем, картину), я хочу преобразовать видеопоток из OAK в стиль этого изображения. По сути, я не делаю ничего нового, но думаю, что в любом случае это будет весело.

В этом первом посте будут рассмотрены некоторые основы, а также техника, которую я буду использовать; Если вы уже занимаетесь глубоким обучением, я бы просто прочитал исходную статью. Во втором посте я расскажу о повторном внедрении модели и обучении, а в последнем посте я перенесу все на OAK-1.

Подробнее о ДУБ-1

Вот он… Он стоит около 99 долларов и включает в себя видео 4K и встроенный чип нейронной сети.

Основы CNN

Я не буду здесь исчерпывающе рассматривать сверточные нейронные сети (CNN), но я рассмотрю достаточно основ, чтобы остальная часть этого проекта имела смысл.

Большинство изображений состоит из 3 каналов; красный, зеленый и синий.

Сверточный слой - это функция, которая принимает стек 2D-массивов (например, изображение RGB) и преобразует его в другой стек 2D-массивов. Таким образом, слой может принимать изображение RGB размером 64x64 (64x64x3) и выдавать четыре выхода 32x32 (32x32x4). Каждый из четырех выходных данных называется картой характеристик.

Если мы сложим несколько сверточных слоев вместе, мы получим сверточную нейронную сеть (CNN). Первые слои делают простые вещи, например обнаруживают линии, а последующие слои обнаруживают более сложные узоры, такие как различные виды капель.

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

Кодеры и декодеры

Большинство CNN добавляют все больше и больше функциональных карт, пока не дадут какой-нибудь ответ на наш вопрос. Вот пример:

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

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

Статистика карты функций

Мы почти там…

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

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

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

Обратите внимание, что статистика характерных карт фотографии не соответствует статистике характерных карт картины. Это говорит нам о том, что изображения имеют разные стили.

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

Теперь мы можем умножить на стандартное отклонение соответствующей карты признаков в кодировке фотографии и добавить среднее значение соответствующей карты признаков в кодировке фотографии.

По сути, мы изменили кодировку фотографии, чтобы каждая карта объектов имела ту же статистику, что и соответствующая карта объектов в кодировке рисунка. Этот шаг называется адаптивной нормализацией экземпляра или AdaIn. «Адаптивная» часть исходит из того факта, что мы можем сделать это для любого рисунка, а часть «нормализации экземпляра» исходит из того факта, что мы можем сделать это только с одним входным изображением и изображением стиля.

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

Обучение сети

Следующий вопрос: как именно мы все это делаем? Для кодировщика мы можем просто использовать модель, которую кто-то обучил для классификации изображений (как это делают авторы AdaIn), и не изменять то, что она делает (ее веса). Но декодер необходимо обучить восстанавливать изображение в другом стиле.

Мы хотим, чтобы декодер делал две вещи. Сначала декодер должен вывести изображение, соответствующее целевому стилю. Для этого мы сравниваем статистику карты объектов:

Мы можем измерить, насколько плохо декодер делает это численно, с помощью следующей функции:

Интуитивно это вычисляет, насколько далеко выходной стиль от стиля изображения стиля; если целевой стиль очень гладкий, изображение на выходе тоже должно быть.

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

Численно это:

Интуитивно это вычисляет, насколько далеко выходные карты объектов находятся от карт объектов входных данных. Другими словами, машина по-прежнему должна выглядеть как машина.

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

Это приводит нас к следующей функции потерь:

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

Вся система при обучении выглядит следующим образом:

Подведем итоги: вот как все выглядит, когда мы на самом деле используем систему:

На этом пока все! Я уже довольно далеко продвинулся в написании моделей, так что ждите следующего обновления.

Это сообщение является зеркалом моего веб-сайта.

Образец стиля изображения, украденного отсюда.