Procesar modelos con ONNX
Open Neural Network Exchange (ONNX) es un formato abierto creado para representar modelos de aprendizaje automático. Desde que se abrió en 2017, ONNX se ha convertido en un estándar para la IA, proporcionando bloques de construcción para el aprendizaje automático y los modelos de aprendizaje profundo. ONNX define un formato de archivo común para permitir a los desarrolladores de IA utilizar modelos con varios marcos, herramientas, tiempos de ejecución y compiladores, y ayuda a aumentar la velocidad de innovación en la comunidad de inteligencia artificial.
Milvus es una base de datos vectorial de código abierto muy flexible, fiable y rapidísima. Permite añadir, eliminar, actualizar y buscar vectores casi en tiempo real. Milvus cuenta con un amplio conjunto de API intuitivas y es compatible con múltiples bibliotecas de índices ampliamente adoptadas (por ejemplo, Faiss, NMSLIB y Annoy), lo que simplifica la selección de índices para un escenario determinado. Milvus es fácil de usar, y se ha utilizado en cientos de organizaciones e instituciones de todo el mundo, incluyendo búsqueda de imágenes, audio y vídeo, recomendación, chatbot, búsqueda de nuevos medicamentos, etc.
Este artículo le mostrará cómo utilizar múltiples modelos para la búsqueda de imágenes basándose en ONNX y Milvus. Toma los modelos VGG16 y ResNet50 como ejemplos, utiliza ONNX para ejecutar diferentes modelos de IA para generar vectores de características y, finalmente, realiza la recuperación de vectores de características en Milvus para devolver imágenes similares.
Procesar modelos con ONNX
El formato ONNX puede intercambiarse fácilmente entre modelos de IA. Por ejemplo, el modelo TensorFlow puede convertirse al formato ONNX y ejecutarse en el entorno Caffe. En este ejemplo, convertimos el modelo ResNet50 preentrenado en el marco Keras al formato ONNX, y luego llamamos al modelo VGG16 en formato ONNX para analizar 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: Cuando utilizamos la interfaz keras2onnx.convert_keras(model, model.name)
para convertir el modelo, nos devolverá el error AttributeError:'KerasTensor' object has no attribute'graph'
. Entonces podemos utilizar el comando Bash de Python para convertir de acuerdo con la solución en Stack Overflow.
Extraer vectores de características utilizando modelos
Después de convertir el modelo ResNet50 al formato ONNX, puede extraer el vector de características de la imagen directamente a través de la inferencia. Nota: Los vectores de características deben normalizarse después de la extracción.
# 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
Utilice el modelo VGG16 en formato ONNX para procesar los datos de la imagen:
# 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")
Almacenar datos vectoriales
Los datos no estructurados, como las imágenes, no pueden ser procesados directamente por un ordenador, pero pueden ser convertidos en vectores a través de un modelo de IA y luego analizados por un ordenador. La base de datos vectorial Milvus está diseñada para el análisis masivo de datos no estructurados. Puede almacenar datos vectoriales y realizar análisis casi en tiempo real. En primer lugar, cree una colección del modelo correspondiente en Milvus y, a continuación, inserte los vectores de imagen.
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)
Después de insertar los datos correctamente, Milvus devolverá el ID correspondiente al vector, y entonces podremos encontrar la imagen por ID. Dado que Milvus 1.1 utilizado en este caso no soporta el filtrado escalar (que Milvus 2.0 soporta ahora), se utiliza Redis para almacenar el ID del vector y la clave-valor de la ruta de la imagen.
import redis
def img_ids_to_redis(img_directory, res_ids):
for img, ids in zip(images, res_ids):
redis.set(ids, img)
Búsqueda de imágenes similares
Después de almacenar los datos, podemos recuperar el vector. Milvus soporta múltiples métodos de cálculo de distancias, incluyendo la distancia euclidiana, el producto interior y la distancia Hamming. La búsqueda de imágenes similares en este artículo adopta el cálculo de la distancia euclídea entre los vectores en Milvus, devuelve el ID del vector similar y, a continuación, encuentra la imagen correspondiente al ID en 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 como ejemplo los modelos VGG16 y ResNet50, este artículo muestra el procesamiento de múltiples modelos a través de ONNX y la combinación de múltiples modelos con Milvus para la recuperación de vectores similares para obtener imágenes similares. Los dos modelos anteriores se basan en el framework Keras, que puede extraer rápidamente vectores de características. Puede verse en el Cuaderno que, aunque los resultados de la búsqueda de Milvus de imágenes en el conjunto de datos COCO basados en estos dos modelos son similares, sus distancias euclidianas no son las mismas. También puede intentar comparar los resultados de búsqueda de los dos modelos utilizando otros conjuntos de datos.
Milvus es una base de datos vectorial de alto rendimiento y alta disponibilidad que puede utilizarse para procesar vectores de características generados a partir de datos masivos no estructurados. Para obtener más soluciones, puede consultar Milvus bootcamp.
Referencias
- https://github.com/onnx/onnx
- https://onnx.ai/
- https://milvus.io/cn/
- https://github.com/milvus-io/bootcamp
Sobre el autor
Shiyu Chen, ingeniero de datos en Zilliz, se licenció en Informática por la Universidad de Xidian. Desde que se unió a Zilliz, ha estado explorando soluciones para Milvus en varios campos, como el análisis de audio y vídeo, la recuperación de fórmulas de moléculas, etc., lo que ha enriquecido enormemente los escenarios de aplicación de la comunidad. Actualmente está explorando más soluciones interesantes. En su tiempo libre, le encantan los deportes y la lectura.
- Extraer vectores de características utilizando modelos
- Almacenar datos vectoriales
- Búsqueda de imágenes similares
- Referencias
On This Page
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word