🚀 Попробуйте Zilliz Cloud, полностью управляемый Milvus, бесплатно — ощутите 10-кратное увеличение производительности! Попробовать сейчас>

milvus-logo
LFAI
  • Home
  • Blog
  • Обработка моделей с помощью ONNX

Обработка моделей с помощью ONNX

  • Engineering
September 26, 2021

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

# load keras-resnet50 model and save as a floder
model_resnet50 = ResNet50(include_top=False, pooling='max', weights='imagenet')
tf.saved_model.save(model_resnet50, "keras_resnet50_model")

# convert resnet50 model to 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'. Тогда мы можем использовать команду Bash в Python для конвертации в соответствии с решением на Stack Overflow.

Извлечение векторов признаков с помощью моделей

После преобразования модели ResNet50 в формат ONNX можно извлечь вектор признаков изображения непосредственно через вывод. Примечание: Векторы признаков необходимо нормализовать после извлечения.

# get the image vectors with onnx model
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:

# generate vectors with ResNet50 and VGG16 ONNX model
2vec_resnet = get_onnx_vectors("onnx_resnet50.onnx", "./pic/example.jpg")
3vec_vgg = get_onnx_vectors("onnx_vgg16.onnx", "./pic/example.jpg")

Хранение векторных данных

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

from milvus import *

# create collections in Milvus
milvus.create_collection(resnet_collection_param)
milvus.create_collection(vgg_collection_param)

# insert data to Milvus and return ids
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.

import 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.

# search in Milvus and return the similarly results with ids
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
    
# get the images according the result ids
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.

Ссылки

  1. https://github.com/onnx/onnx
  2. https://onnx.ai/
  3. https://milvus.io/cn/
  4. https://github.com/milvus-io/bootcamp

Об авторе

Шиюй Чен, инженер по обработке данных в Zilliz, окончила Сидяньский университет по специальности "Компьютерные науки". С момента прихода в Zilliz она занималась поиском решений для Milvus в различных областях, таких как анализ аудио и видео, поиск формул молекул и т. д., что значительно обогатило сценарии применения сообщества. В настоящее время она занимается поиском новых интересных решений. В свободное время она любит спорт и чтение.

Like the article? Spread the word

Продолжить чтение