开放神经网络交换(Open Neural Network Exchange,简称 ONNX)是一个开放的生态系统,它提供了基于人工智能模型的一种开源格式。自 2017 年开源以来,ONNX 在短短几年时间内发展为表示人工智能模型的实际标准,提供了一个统一的交互格式,用于优化深度学习和传统的机器学习。ONNX 定义了一组与环境和平台无关的标准格式,实现不同框架之间的互操作性,并简化从研究到生产的路径,有助于提高人工智能社区的创新速度。
Milvus 是一款开源的向量数据库,支持针对特征向量的增删改操作和近实时查询。Milvus 集成了业界成熟的向量检索技术,包括 Faiss、NMSLIB、Annoy 等,同时提供了一整套简单直观的 API,支持针对不同场景选择不同的索引。得益于其简单易用的特性,Milvus 获得了大量用户的青睐,被广泛应用于 AI 场景,包括图像/音视频搜索、文本搜索、推荐、交互式问答、新药搜索等领域。
本文将介绍如何基于 ONNX 和 Milvus 实现多模型以图搜图系统。本文以 VGG16 和 ResNet50 模型为例,使用 ONNX 运行不同的 AI 模型对图片数据进行推理生成特征向量,最后在 Milvus 中进行特征向量检索,返回相似的图片。我们在 GitHub 上开源了该项目的 Jupyter Notebook 代码文件(https://github.com/milvus-io/...),接下来将介绍其具体实现。
使用 ONNX 处理模型
ONNX 格式可以轻松实现人工智能模型之间的交换,例如 TensorFlow 模型转换为 ONNX 格式后即可在 Caffe 环境下运行。本文示例中,我们将 Keras 框架下预训练好的 ResNet50 模型转换为 ONNX 格式,再调用另一个 ONNX 格式的 VGG16 模型,从而实现不同模型的处理分析。
注:在模型转换过程中,使用官方的接口 keras2onnx.convert_keras(model, model.name) 时返回错误AttributeError: 'KerasTensor' object has no attribute 'graph'。后按照 Stack Overflow 的解决方案,使用 Python 的 Bash 命令执行后成功转换模型。
模型推理提取特征向量
预训练好的 ResNet50 模型经过以上处理转化为 ONNX 格式后,可以通过 inference 接口即可直接提取图片的特征向量。
注:提取特征向量后需要对向量数据进行归一化。
使用经过同样处理的 ONNX 格式 VGG16 模型处理图片数据:
特征向量存储
诸如图片等非结构化数据无法被计算机直接识别,但可通过 AI 模型转换为特征向量,从而用于计算机处理分析。Milvus 向量数据库旨在解决海量非结构化数据分析的问题,可以存储向量数据并执行近实时的分析。
首先,在 Milvus 中创建对应模型的 collection ,然后再插入图片向量数据。
数据插入成功后 Milvus 会返回向量对应 ID,之后需根据 ID 找出对应图片。由于本文案例使用的 Milvus 1.1 版本不支持存储其他标量信息(目前 Milvus 2.0 版本已经支持),因此采用 Redis 存储向量 ID 和图片路径的 key-value 值。
相似图片检索
数据存储完成后,就可以在 Milvus 中检索向量了。Milvus 支持多种常见的距离计算方式,包括欧式距离、内积距离和汉明距离等。本文的图片分析通过 Milvus 来计算向量之间的欧式距离,返回相似的向量 ID,然后在 Redis 中找出 ID 对应的图片,从而实现相似图片检索的功能。
以 VGG16 和 ResNet50 模型为例,本文详述了通过 ONNX 处理多个模型并结合 Milvus 进行相似向量检索得出相似图片的过程。以上两个模型都基于 Keras 框架,可以快速推理提取特征向量。从 Notebook 中可以看出,Milvus 基于这两个模型在 COCO 数据集上搜索图片的结果虽然相似,但欧氏距离却不尽相同。你也可以尝试使用其他数据集比对两者的搜索结果。
Milvus 是一款高性能、高可用的向量数据库,可用于处理海量非结构化数据生成的特征向量,更多案例参考 Milvus bootcamp(https://github.com/milvus-io/...)。
参考资料:
✏️ 作者:陈室余,Zilliz 数据工程师。自加入 Zilliz 以来,致力于为 Milvus 开源项目探索解决方案,从 Docker 部署到应用 Milvus 在更多 AI 项目,帮助诸多用户实现应用场景落地。毕业于西安电子科技大学计算机学系。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。