🚀 Experimente o Zilliz Cloud, o Milvus totalmente gerenciado, gratuitamente—experimente um desempenho 10x mais rápido! Experimente Agora>>

milvus-logo
LFAI

Processar modelos com ONNX

  • Engineering
September 26, 2021

O Open Neural Network Exchange (ONNX) é um formato aberto criado para representar modelos de aprendizagem automática. Desde que foi aberto em 2017, o ONNX tornou-se um padrão para IA, fornecendo blocos de construção para modelos de aprendizagem automática e aprendizagem profunda. O ONNX define um formato de ficheiro comum para permitir que os programadores de IA utilizem modelos com várias estruturas, ferramentas, tempos de execução e compiladores, e ajuda a aumentar a velocidade de inovação na comunidade de inteligência artificial.

Milvus é uma base de dados vetorial de código aberto que é altamente flexível, fiável e extremamente rápida. Suporta a adição, eliminação, atualização e pesquisa de vectores quase em tempo real. Milvus tem um conjunto abrangente de APIs intuitivas e suporte para várias bibliotecas de índices amplamente adoptadas (por exemplo, Faiss, NMSLIB e Annoy), simplificando a seleção de índices para um determinado cenário. O Milvus é simples de usar e tem sido utilizado em centenas de organizações e instituições em todo o mundo, incluindo pesquisa de imagem, áudio e vídeo, recomendação, chatbot, pesquisa de novos medicamentos, etc.

Este artigo irá apresentar-lhe como utilizar vários modelos para a pesquisa de imagens com base no ONNX e no Milvus. Toma os modelos VGG16 e ResNet50 como exemplos, utiliza o ONNX para executar diferentes modelos de IA para gerar vectores de caraterísticas e, por fim, executa a recuperação de vectores de caraterísticas em Milvus para devolver imagens semelhantes.

Processar modelos com ONNX

O formato ONNX pode ser facilmente trocado entre modelos de IA. Por exemplo, o modelo TensorFlow pode ser convertido para o formato ONNX e executado no ambiente Caffe. Neste exemplo, convertemos o modelo ResNet50 pré-treinado no âmbito da estrutura Keras para o formato ONNX e, em seguida, chamamos o modelo VGG16 no formato ONNX para analisar diferentes modelos.

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"

Nota: Quando utilizámos a interface keras2onnx.convert_keras(model, model.name) para converter o modelo, esta devolverá o erro AttributeError:'KerasTensor' object has no attribute'graph'. Em seguida, podemos usar o comando Bash do Python para converter de acordo com a solução no Stack Overflow.

Extrair vectores de caraterísticas utilizando modelos

Depois de converter o modelo ResNet50 para o formato ONNX, pode extrair o vetor de caraterísticas da imagem diretamente através da inferência. Nota: Os vectores de caraterísticas têm de ser normalizados após a extração.

# 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

Utilize o modelo VGG16 em formato ONNX para processar dados de imagem:

# 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")

Armazenar dados vectoriais

Os dados não estruturados, como as imagens, não podem ser processados diretamente por um computador, mas podem ser convertidos em vectores através de um modelo de IA e depois analisados por um computador. A base de dados vetorial Milvus foi concebida para potenciar a análise maciça de dados não estruturados. Pode armazenar dados vectoriais e efetuar análises quase em tempo real. Em primeiro lugar, crie uma coleção do modelo correspondente em Milvus e, em seguida, insira os vectores de imagem.

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)

Depois de inserir os dados com sucesso, o Milvus devolverá o ID correspondente ao vetor e, em seguida, podemos encontrar a imagem pelo ID. Uma vez que o Milvus 1.1 utilizado neste caso não suporta filtragem escalar (que o Milvus 2.0 suporta agora), o Redis é utilizado para armazenar o ID do vetor e o valor-chave do caminho da imagem.

import redis
def img_ids_to_redis(img_directory, res_ids):
  for img, ids in zip(images, res_ids):
    redis.set(ids, img)

Pesquisa de imagens semelhantes

Depois de armazenar os dados, podemos recuperar o vetor. O Milvus suporta vários métodos de cálculo de distâncias, incluindo a distância Euclidiana, o produto interno e a distância de Hamming. A pesquisa de semelhança de imagens neste artigo adopta o cálculo da distância euclidiana entre os vectores no Milvus, devolve o ID do vetor semelhante e, em seguida, encontra a imagem correspondente ao ID no 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

Tomando os modelos VGG16 e ResNet50 como exemplos, este artigo mostra o processamento de vários modelos através do ONNX e a combinação de vários modelos com o Milvus para a recuperação de vectores semelhantes, de modo a obter imagens semelhantes. Os dois modelos acima referidos baseiam-se na estrutura Keras, que pode extrair rapidamente vectores de caraterísticas. Pode ver-se no Notebook que, embora os resultados da pesquisa de imagens do Milvus no conjunto de dados COCO com base nestes dois modelos sejam semelhantes, as suas distâncias euclidianas não são as mesmas. Também pode tentar comparar os resultados da pesquisa dos dois modelos utilizando outros conjuntos de dados.

Milvus é uma base de dados vetorial de alto desempenho e altamente disponível que pode ser utilizada para processar vectores de caraterísticas gerados a partir de dados massivos não estruturados. Para obter mais soluções, pode consultar o bootcamp do Milvus.

Referências

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

Sobre o autor

Shiyu Chen, engenheira de dados na Zilliz, licenciou-se em Ciências Informáticas na Universidade de Xidian. Desde que se juntou à Zilliz, tem vindo a explorar soluções para o Milvus em vários domínios, como a análise de áudio e vídeo, a recuperação de fórmulas de moléculas, etc., o que enriqueceu bastante os cenários de aplicação da comunidade. Atualmente, está a explorar mais soluções interessantes. No seu tempo livre, gosta de desporto e de ler.

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started

Like the article? Spread the word

Continue Lendo