Узнайте, как переводить текст в изображение и обратно с помощью CLIP и векторных вложений.
Через несколько коротких лет жизни дети могут понять концепции простых слов и связать их с соответствующими изображениями. Они могут определить связь между формами и текстурами физического мира с абстрактными символами письменного языка.
Это то, что мы принимаем как должное. Очень немногие (если вообще есть) люди в мире помнят время, когда эти «базовые» навыки были им не по силам.
Компьютеры разные. Они могут рассчитать параметры, необходимые ракете для пересечения Солнечной системы. Но если вы попросите компьютер найти изображение «собаки в парке», вам лучше попросить у НАСА бесплатный билет на космическую станцию.
По крайней мере, так было до недавнего времени.
В этой статье мы рассмотрим CLIP OpenAI. «Мультимодальная» модель, способная понимать отношения и понятия как между текстом, так и изображениями. Как мы увидим, CLIP — это больше, чем причудливый салонный трюк. Он поразительно способен.
Контрастное обучение?
Контрастивная Языково-Ямагическая Ппереподготовка (CLIP) состоит из двух моделей, обучаемых параллельно. Модель Vision Transformer (ViT) или ResNet для встраивания изображений и модель преобразования для языковых встраиваний.
Во время обучения пары (изображение, текст) передаются в соответствующие модели, и обе выводят 512-мерное векторное вложение, представляющее соответствующее изображение/текст в векторном пространстве.
Компонент contrastive берет эти два вложения векторов и вычисляет потери модели как разницу (например, контрастность) между двумя векторами. Затем обе модели оптимизируются, чтобы свести к минимуму эту разницу, и поэтому узнают, как встраивать похожие пары (изображение, текст) в одинаковое векторное пространство.
После этого контрастного процесса предварительной подготовки у нас остается CLIP, мультимодальная модель, способная понимать как язык, так и изображения через общее векторное пространство.
Использование КЛИП
OpenAI разработала и выпустила библиотеку clip
, которую можно найти на GitHub здесь. Однако библиотека transformers
Hugging Face содержит другую реализацию CLIP (также созданную OpenAI), которая используется чаще.
Реализация Hugging Face не использует ResNet для кодирования изображений. Он использует альтернативную настройку модели ViT в паре с преобразователем текста. Мы узнаем, как использовать эту реализацию, собрав воедино простой сценарий поиска текст-изображение, который можно адаптировать для модальностей изображение-изображение, текст-текст и изображение-текст.
Загрузка данных и CLIP
Для начала мы установим библиотеки, необходимые для нашей демонстрации, загрузим набор данных и инициализируем CLIP.
pip install -U torch datasets transformers
Мы будем использовать набор данных «imagenette», коллекцию из примерно 10 000 изображений, размещенную на Hugging Face.
Это дает нам 9469 изображений, начиная от радио и заканчивая собаками. Все эти изображения хранятся в функции 'image'
как объекты изображения PIL.
Теперь мы инициализируем CLIP через библиотеку transformers
следующим образом:
Здесь происходит несколько вещей:
- Вся часть
device
заключается в настройке нашего экземпляра для использования самого быстрого доступного нам оборудования (MPS на чипах M1, в противном случае — CUDA). - Мы устанавливаем
model_id
. Так называется модель CLIP, найденная здесь. - Затем мы инициализируем
tokenizer
для предварительной обработки текста,processor
для предварительной обработки изображений и CLIPmodel
для создания векторных вложений.
Теперь мы готовы приступить к встраиванию текста и изображений.
Создание текстовых вложений
Модель преобразования текста обрабатывает кодирование нашего текста в осмысленные векторные вложения. Для этого мы сначала размечаем текст, чтобы перевести его из удобочитаемого текста в токены, читаемые преобразователем.
Затем передайте эти токены в модель, используя метод get_text_features
.
Здесь у нас есть 512-мерный вектор, представляющий семантическое значение фразы «собака на снегу». Это половина нашего поиска текста-изображения.
Создание вложений изображений
Следующий шаг — создание вложений изображений. Опять же, это очень просто. Мы заменяем tokenizer
на processor
, что дает нам измененный размер тензора изображения под названием pixel_values
.
Мы все еще можем визуализировать обработанное изображение. Его размер был изменен, а значения «активации» пикселей больше не находятся в типичном диапазоне RGB от 0 до 255, который может прочитать Matplotlib, поэтому цвета отображаются неправильно. Тем не менее, мы видим, что это то же самое радио Sony, которое мы видели раньше.
Затем мы обрабатываем эти входные данные с помощью CLIP, на этот раз используя метод get_image_features
.
И с этим мы создали векторные вложения для текста и изображения с помощью CLIP. С помощью этих вложений мы можем сравнить их сходство, используя такие показатели, как евклидово расстояние, косинусное сходство или сходство скалярного произведения.
Тем не менее, мы не можем много сравнивать с одним примером каждого, поэтому давайте продолжим и проверим это на большей выборке изображений.
Мы возьмем 100 случайных изображений из imagenette
данных. Для этого мы начинаем с случайного выбора 100 индексных позиций и используем их для построения списка изображений.
Теперь мы перебираем эти 100 изображений и создаем вложения изображений с помощью CLIP. Мы добавим их все в массив Numpy с именем image_arr
.
В нижней ячейке мы видим, что минимальное и максимальное значения вложенного изображения равны -7.99
и +3.15
соответственно. Мы будем использовать сходство скалярного произведения для сравнения наших векторов. Если мы хотим точно сравнить их с скалярным произведением, нам нужно их нормализовать. Делаем это так:
Теперь мы готовы сравнивать и искать наши векторы.
Поиск текста-изображения
Как уже упоминалось, мы будем использовать скалярное произведение для сравнения векторов. Встраивание текста будет действовать как «запрос», с помощью которого мы будем искать наиболее похожие вложения изображений.
Начнем с вычисления сходства скалярного произведения между нашим запросом и изображениями:
Это дает нам 100 баллов, например, оценку «один ко многим» для каждой пары вложений текста в изображения. Все, что мы знаем, это сортировать эти оценки по убыванию и возвращать соответствующие изображения с наивысшими оценками.
На позиции №1 у нас собака на снегу, отличный результат! Это весьма вероятно единственное изображение собаки в снегу из нашей выборки из 100 изображений. Именно так мы выполняем поиск текстового изображения с помощью CLIP.
CLIP — это удивительная модель, которую можно применять к доменам языка и изображения в любом порядке и в любом сочетании. Мы можем выполнять поиск текст-текст, изображение-изображение и изображение-текст, используя ту же методологию.
На самом деле, мы можем сделать все это одновременно, просто добавив вектор изображения и текст в одно хранилище, а затем запросив либо изображение, либо текст.
Наш подход хорош, если вы придерживаетесь меньшего количества элементов поиска. Однако это медленно или даже невозможно, когда мы начинаем просматривать больше записей. Для этого нам понадобится векторная база данных. Это позволяет нам масштабировать это до миллионов или даже миллиардов записей.
Если вам интересно узнать больше о мультимодальных моделях, НЛП или векторном поиске, загляните на мой канал YouTube, свяжитесь с Discord или пройдите один из моих бесплатных курсов (ссылки ниже).
Спасибо за прочтение!