В моем предыдущем посте я дразнил, что прыгнул в кроличью нору, чтобы попытаться улучшить свой конвейер сходства лиц Fate Grand Order, где я использовал детекторы объектов Tensorflow, экстракторы функций Pytorch и приблизительную библиотеку ближайших соседей Spotify (досадно ). Общая идея, с которой я работал, заключалась в том, что я хотел закодировать информацию о чертах лица персонажей (чтобы найти похожие символы), а также фоновую информацию (чтобы возвращать изображения с похожими цветами / ощущениями).

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

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

Выход модели версии 1

Результат нормальный, но 2 из 4 похожих изображений имеют разные символы.

Затем краткий обзор конвейера на основе хедшотов версии 2, где я использовал специализированный детектор объектов Tensorflow для вырезания заголовков персонажей на изображениях и использовал их для построения раздражающих индексов и поиска похожих изображений.

Версия 2 модель выстрела в голову

Этот конвейер казался довольно успешным и возвращает изображение одного и того же персонажа на всех изображениях, но я хотел посмотреть, смогу ли я почувствовать себя ближе к оригиналу. Вот почему я попытался объединить выходные векторы Resnet 101 и скормить им досаду, чтобы создать новую версию модели 3.

Версия 3: объедините первые два

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

Версия 3 объединяет выстрел в голову и базовое изображение

Таким образом, эта 3-я версия конвейера - не совсем то, на что я надеялся… хотя у этих персонажей действительно похожие лица, 2 из 4 выходных данных имеют символы, отличные от символа на базовом изображении.

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

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

На этот раз я понял, что перечитал раздражающую страницу репозитория git и увидел эту заметку.

Работает лучше, если у вас не слишком много измерений (например, ‹100), но кажется, что он работает на удивление хорошо даже до 1000 измерений.

Как для базового изображения, так и для версий этого конвейера вектор признаков был стандартным 1000 функций из Resnet 101. Который находится на этой верхней границе, и объединение двух векторов вместе подталкивает его к вектору длины 2000, который находится далеко за пределами рекомендуемое количество размеров.

Версия 4: Тупой вниз?

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

Помня об этом, я фактически понизил версию средства извлечения функций Resnet с 101 до Resnet 34 для версии 4 этого конвейера. Это связано с тем, что слои перед последним 1000 полностью подключенным слоем в Resnet 101 имеют размер 2048, в то время как Resnet 34 - только 512. Я думал, что, используя этот меньший слой, я мог бы объединить два слоя по 512, чтобы получить окончательный вектор. длины 1024, а не 2000. Была надежда, что это уменьшит количество измерений настолько, чтобы позволить раздражению функционировать нормально.

Я считаю, что это изменение улучшило качество моих результатов.

Версия 4 Resnet 34

Таким образом, при использовании тех же примеров изображений, которые я показывал ранее, эта модель Resnet 34 выглядит лучше, чем исходная модель «выстрел в голову + базовое изображение», использующая более крупный Resnet 101. Два из четырех изображений соответствуют персонажу. Третье изображение - просто злая версия оригинального персонажа, поэтому я думаю, что это имеет значение. Окончательное изображение, однако, кажется совершенно несвязанным… так что есть еще кое-что.

Вот еще один пример, показывающий результаты этой модели Resnet 34 по сравнению с предыдущими тремя версиями. Комментирую выводы в подписях к изображениям.

Базовое изображение версии 1

Версия 2 хедшоты

Версия 3 объединяет хедшоты и базовое изображение

Версия 4 Resnet 34

Таким образом, несмотря на то, что Resnet 34 является улучшением по сравнению с версией этого конвейера Resnet 101, он все еще не работает хорошо ... Я все еще верю, что могу улучшить его, вопрос только в том, как?

Версия 5: с 1024 размеров до 52

Подумав, как получить еще меньшее окончательное представление функции, чем результат 512 Resnet 34, и на какое-то время нарисовав пробел ... я почувствовал себя идиотом, потому что для другого поста, который я готовил, я тренировал многозадачную модель на основе Pytorch на этот же набор данных для выполнения классификации с несколькими метками по 5 категориям с 26 различными целевыми переменными.

Эта сеть представляет собой Pytorch Resnet 50, где я модифицировал последние слои для обработки 5 задач, которые я пытаюсь оптимизировать одновременно. У меня есть этот пост в режиме черновика, но я был слишком ленив, чтобы закончить его ... но в данном случае эта сеть очень удобна, потому что она дала мне доступ к точно настроенной сети, которая научилась различать изображения Fate Grand Order. Преимущество здесь заключается в том, что вместо использования 512 или 1000 выходных узлов эта конкретная сеть хорошо разбирается в этой проблемной области и имеет только 26 выходных узлов, что означает, что я могу представить лица и базовое изображение с вектором из 52 измерений, а не 1024 или 2000. Это более плотное представление этих изображений должно позволить раздражающему лучше различать изображения.

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

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

Версия 5 доработанная многозадачная модель

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

Заключительные мысли

Эти два сообщения стали хорошим напоминанием о важности уменьшения размерности ваших данных для получения лучших результатов.

Каждое из изображений начинается с 150 528 пикселей (ширина 224 x 224 x 3, высота, цвет rgb), а затем с помощью стандартной предварительно обученной сети Imagenet может быть сжато только до 1000 объектов. Я думаю, что это круто даже само по себе.

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

Чтобы еще больше уменьшить размерность моих представлений изображений, я использовал Resnet 34 меньшего размера и увидел некоторые улучшения, но модель выводила нечетные похожие изображения. Поскольку это не сработало, я решил, что могу попытаться сделать еще более плотное представление данных, и, наконец, я смог использовать сеть, которую я точно настроил в аналогичном проблемном пространстве, чтобы уменьшить исходное исходное представление с 150 528 пикселей до 26.

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

Не стесняйтесь проверить репозиторий github для образцов кода.

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