图片向量相似检索服务(5)——基于milvus实现

概述

  • 为了让尝试“以图搜图”的相似图片检索的场景,基于ES向量索引计算和图片特征提取模型 VGG16 设计了一个以图搜图系统。
  • 开源地址:https://github.com/yaolipro/image-retrieval

检索场景

  • 推理流程:读取图片,算法生成特征向量
  • 特征入库:把特征向量存入Milvus中
  • 检索流程:线上实时向量检索
  • 具体流程如下图:

Milvus服务端安装

  • 安装指南:https://milvus.io/cn/docs/milvus_docker-cpu.md
  • 下载配置
  mkdir -p milvus/conf && cd milvus/conf
  wget https://raw.githubusercontent.com/milvus-io/milvus/0.10.6/core/conf/demo/server_config.yaml
  • 服务启动
  docker run -d --name milvus_cpu_0.11.0 \
  -p 19530:19530 \
  -p 19121:19121 \
  -v <ROOT_DIR>/milvus/db:/var/lib/milvus/db \
  -v <ROOT_DIR>/milvus/conf:/var/lib/milvus/conf \
  -v <ROOT_DIR>/milvus/logs:/var/lib/milvus/logs \
  -v <ROOT_DIR>/milvus/wal:/var/lib/milvus/wal \
  milvusdb/milvus:0.10.6-cpu-d022221-64ddc2

Milvus向量索引建库

  • 此处选用已落盘的h5py向量库进行建库
  • 检索类型为内积:MetricType.IP
  # 1. 读取索引
  h5f = h5py.File(index_dir, 'r')
  self.retrieval_db = h5f['dataset_1'][:]
  self.retrieval_name = h5f['dataset_2'][:]
  h5f.close()
  # 2. 入库Milvus
  if self.index_name in self.client.list_collections()[1]:
      self.client.drop_collection(collection_name=self.index_name)
  self.client.create_collection({'collection_name': self.index_name, 'dimension': 512, 'index_file_size': 1024, 'metric_type': MetricType.IP})
  self.id_dict = {}
  status, ids = self.client.insert(collection_name=self.index_name, records=[i.tolist() for i in self.retrieval_db])
  for i, val in enumerate(self.retrieval_name):
      self.id_dict[ids[i]] = str(val)
  self.client.create_index(self.index_name, IndexType.FLAT, {'nlist': 16384})
  # pprint(self.client.get_collection_info(self.index_name))
  print("************* Done milvus indexing, Indexed {} documents *************".format(len(self.retrieval_db)))

Milvus检索实现

  • 根据加载索引时的定义,此处检索采用点积距离计算方式,具体代码如下:
_, vectors = self.client.search(collection_name=self.index_name, query_records=[query_vector], top_k=search_size, params={'nprobe': 16})
  • 可切换至欧氏:MetricType.L2

操作简介

python index.py
--train_data:自定义训练图片文件夹路径,默认为`<ROOT_DIR>/data/train`
--index_file:自定义索引文件存储路径,默认为`<ROOT_DIR>/index/train.h5`
  • 操作二:使用相似检索
python retrieval.py --engine=milvus
--test_data:自定义测试图片详细地址,默认为`<ROOT_DIR>/data/test/001_accordion_image_0001.jpg`
--index_file:自定义索引文件存储路径,默认为`<ROOT_DIR>/index/train.h5`
--db_name:自定义ES或者Milvus索引库名,默认为`image_retrieval`
--engine:自定义检索引擎类型,默认为`numpy`,可选包括:numpy、faiss、es、milvus

总结

  • 基于库的管理方式便捷易懂
  • 使用姿势类似ES,但性能优于ES
  • 由于当前Milvus只支持向量检索,不支持标量相关,如果涉及标量过滤需要自建业务库
  • Milvus社区后续会支持分布式,可以更加方便的应对大索引场景

That’s all!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于 Milvus 的多模态检索系统可以实现对多种类型数据的检索,例如图像、文本、语音等。下面是一个简单的演示: 1. 首先,需要安装 Milvus 和相应的 Python SDK: ```shell pip install pymilvus==2.0.0rc5 pip install opencv-python==4.5.1.48 pip install Pillow==8.2.0 pip install grpcio==1.32.0 pip install grpcio-tools==1.32.0 ``` 2. 接下来,我们需要准备一些数据。这里以图像为例,将一些图像文件存储在本地文件夹中。 3. 然后,我们需要将这些图像向量化,并将它们插入到 Milvus 中。这里使用 ResNet50 模型提取图像特征,并使用 Milvus Python SDK 将特征向量插入到 Milvus 中。 ```python import os import cv2 import numpy as np from PIL import Image from milvus import Milvus, IndexType, MetricType, Status # 连接 Milvus milvus = Milvus(host='localhost', port='19530') # 创建 collection collection_name = 'image_collection' if collection_name in milvus.list_collections(): milvus.drop_collection(collection_name) milvus.create_collection(collection_name, {'fields': [ {'name': 'id', 'type': 'int64', 'is_primary': True}, {'name': 'embedding', 'type': 'float', 'params': {'dim': 2048}} ], 'segment_row_limit': 4096, 'auto_id': False}) # 加载 ResNet50 模型 model = cv2.dnn.readNetFromTorch('resnet50.t7') model.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV) model.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU) # 提取图像特征并插入到 Milvus 中 data_path = 'image_data' for i, file_name in enumerate(os.listdir(data_path)): file_path = os.path.join(data_path, file_name) img = cv2.imread(file_path) img = cv2.resize(img, (224, 224)) blob = cv2.dnn.blobFromImage(img, 1, (224, 224), (104, 117, 123)) model.setInput(blob) embedding = model.forward().flatten() status, ids = milvus.insert(collection_name=collection_name, records=[ {'id': i, 'embedding': embedding.tolist()} ]) print(f'Insert image {file_name} with id {ids[0]}') # 创建索引 milvus.create_index(collection_name, IndexType.IVF_FLAT, {'nlist': 128}) ``` 4. 现在,我们已经将图像向量化并插入到 Milvus 中了。接下来,我们可以使用 Milvus向量相似度搜索功能来实现多模态检索。这里以图像检索为例,给定一张查询图像,我们可以使用同样的方式提取其特征向量,并在 Milvus 中搜索与其相似的图像。 ```python # 加载查询图像 query_path = 'query_image.jpg' query_img = cv2.imread(query_path) query_img = cv2.resize(query_img, (224, 224)) query_blob = cv2.dnn.blobFromImage(query_img, 1, (224, 224), (104, 117, 123)) # 提取查询图像特征 model.setInput(query_blob) query_embedding = model.forward().flatten() # 在 Milvus 中搜索相似的图像 search_param = {'nprobe': 16} status, results = milvus.search(collection_name, query_embedding.tolist(), 10, search_params=search_param) print(f'Search results: {results}') ``` 以上就是一个简单的基于 Milvus 的多模态检索系统的演示。除了图像检索,我们也可以使用类似的方式实现文本、语音等多种类型数据的检索

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值