Комбинирование моделей искусственного интеллекта для поиска изображений с помощью ONNX и Milvus
Open Neural Network Exchange (ONNX) - это открытый формат, созданный для представления моделей машинного обучения. С момента своего появления в открытом доступе в 2017 году ONNX превратился в стандарт для ИИ, предоставляя строительные блоки для моделей машинного обучения и глубокого обучения. ONNX определяет общий формат файлов, позволяющий разработчикам ИИ использовать модели в различных фреймворках, инструментах, средах выполнения и компиляторах, и помогает увеличить скорость инноваций в сообществе искусственного интеллекта.
Milvus - это векторная база данных с открытым исходным кодом, которая отличается высокой гибкостью, надежностью и молниеносной скоростью. Она поддерживает добавление, удаление, обновление и поиск векторов практически в режиме реального времени. Milvus имеет обширный набор интуитивно понятных API и поддерживает множество широко распространенных библиотек индексов (например, Faiss, NMSLIB и Annoy), что упрощает выбор индекса для конкретного сценария. Milvus прост в использовании и применяется в сотнях организаций и учреждений по всему миру, включая поиск изображений, аудио и видео, рекомендации, чатботы, поиск новых лекарств и т. д.
В этой статье мы расскажем вам, как использовать несколько моделей для поиска изображений на основе ONNX и Milvus. В качестве примера взяты модели VGG16 и ResNet50, с помощью ONNX запущены различные модели искусственного интеллекта для создания векторов признаков, а затем в Milvus выполнен поиск по векторам признаков для возврата похожих изображений.
Обработка моделей с помощью ONNX
Формат ONNX может быть легко использован для обмена данными между моделями ИИ. Например, модель TensorFlow может быть преобразована в формат ONNX и запущена в среде Caffe. В этом примере мы конвертируем предварительно обученную модель ResNet50 во фреймворке Keras в формат ONNX, а затем вызываем модель VGG16 в формате ONNX для анализа различных моделей.
from keras.applications.resnet50 import ResNet50
import tensorflow as tf
# загружаем модель keras-resnet50 и сохраняем как флоудер
model_resnet50 = ResNet50(include_top=False, pooling='max', weights='imagenet')
tf.saved_model.save(model_resnet50, "keras_resnet50_model")
# конвертировать модель resnet50 в onnx
! python -m tf2onnx.convert --saved-model "keras_resnet50_model" --output "onnx_resnet50.onnx"
Примечание: Когда мы использовали интерфейс keras2onnx.convert_keras(model, model.name) для преобразования модели, он вернет ошибку AttributeError:'KerasTensor' object has no attribute'graph'. Тогда мы можем использовать команду Python's Bash для преобразования в соответствии с решением на Stack Overflow.
Извлечение векторов признаков с помощью моделей
После преобразования модели ResNet50 в формат ONNX можно извлечь вектор признаков изображения непосредственно через вывод. Примечание: Векторы признаков необходимо нормализовать после извлечения.
# получить векторы изображений с помощью модели onnx
def get_onnx_vectors(onnx_model, img_path):
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
sess = onnxruntime.InferenceSession(onnx_model)
x = x if isinstance(x, list) else [x]
feed = dict([(input.name, x[n]) for n, input in enumerate(sess.get_inputs())])
feat = sess.run(None, feed)[0]
norm_feat = feat[0] / LA.norm(feat[0])
norm_feat = [i.item() for i in norm_feat]
return norm_feat
Используйте модель VGG16 в формате ONNX для обработки данных изображений:
# генерируем векторы с помощью ResNet50 и модели VGG16 ONNX
2vec_resnet = get_onnx_vectors("onnx_resnet50.onnx", "./pic/example.jpg")
3vec_vgg = get_onnx_vectors("onnx_vgg16.onnx", "./pic/example.jpg")
Хранение векторных данных
Неструктурированные данные, такие как фотографии, не могут быть напрямую обработаны компьютером, но они могут быть преобразованы в векторы с помощью AI-модели и затем проанализированы компьютером. Векторная база данных Milvus предназначена для массового анализа неструктурированных данных. Она может хранить векторные данные и выполнять анализ практически в режиме реального времени. Сначала создайте коллекцию соответствующей модели в Milvus, а затем вставьте в нее векторы изображений.
из milvus import *
# создание коллекций в Milvus
milvus.create_collection(resnet_collection_param)
milvus.create_collection(vgg_collection_param)
# вставляем данные в Milvus и возвращаем идентификаторы
status, resnet_ids = milvus.insert(resnet_collection_name, resnet_vectors)
status, vgg_ids = milvus.insert(vgg_collection_name, vgg_vectors)
После успешной вставки данных Milvus вернет ID, соответствующий вектору, и мы сможем найти картинку по ID. Поскольку Milvus 1.1, используемый в данном случае, не поддерживает скалярную фильтрацию (которую теперь поддерживает Milvus 2.0), Redis используется для хранения ID вектора и ключа-значения пути к изображению.
импорт redis
def img_ids_to_redis(img_directory, res_ids):
for img, ids in zip(images, res_ids):
redis.set(ids, img)
Поиск похожих изображений
После хранения данных мы можем получить вектор. Milvus поддерживает несколько методов расчета расстояний, включая евклидово, внутреннее произведение и расстояние Хэмминга. Поиск сходства изображений в этой статье использует расчет евклидова расстояния между векторами в Milvus, возвращает идентификатор похожего вектора, а затем находит изображение, соответствующее этому идентификатору в Redis.
# поиск в Milvus и возврат похожих результатов с идентификаторами
def search_in_milvus(collection_name, search_vector):
status, results = milvus.search(collection_name, TOP_K, [search_vector])
print(status)
re_ids = [x.id for x in results[0]]
re_distance = [x.distance for x in results[0]]
return re_ids, re_distance
# получить изображения в соответствии с идентификаторами результатов
def get_sim_imgs(collection_name, search_vector):
ids, distance = search_in_milvus(collection_name, search_vector)
img = [red.get(i).decode("utf-8") for i in ids]
return ids, distance, img
На примере моделей VGG16 и ResNet50 в этой статье показана обработка нескольких моделей с помощью ONNX и объединение нескольких моделей с Milvus для поиска похожих векторов для получения похожих изображений. Две вышеупомянутые модели основаны на фреймворке Keras, который позволяет быстро извлекать векторы признаков. Из блокнота видно, что, хотя результаты поиска Milvus изображений в наборе данных COCO на основе этих двух моделей похожи, их евклидовы расстояния не одинаковы. Вы также можете попробовать сравнить результаты поиска по этим двум моделям, используя другие наборы данных.
Milvus - это высокопроизводительная и доступная база данных векторов, которую можно использовать для обработки векторов признаков, полученных из массивных неструктурированных данных. Для получения более подробных решений вы можете обратиться к Milvus bootcamp.
Ссылки
- https://github.com/onnx/onnx
- https://onnx.ai/
- https://milvus.io/cn/
- https://github.com/milvus-io/bootcamp
Об авторе
Шиюй Чен, инженер по обработке данных в Zilliz, окончила Сидяньский университет по специальности "Компьютерные науки". С момента прихода в Zilliz она занимается поиском решений для Milvus в различных областях, таких как анализ аудио и видео, поиск формул молекул и т. д., что значительно обогатило сценарии применения сообщества. В настоящее время она занимается поиском новых интересных решений. В свободное время она любит спорт и чтение.
Читать далее

Zilliz Cloud Launches in AWS Australia, Expanding Global Reach to Australia and Neighboring Markets
We're thrilled to announce that Zilliz Cloud is now available in the AWS Sydney, Australia region (ap-southeast-2).

Demystifying the Milvus Sizing Tool
Explore how to use the Sizing Tool to select the optimal configuration for your Milvus deployment.

Vector Databases vs. Graph Databases
Use a vector database for AI-powered similarity search; use a graph database for complex relationship-based queries and network analysis.
