Elasticsearch向量检索需要的数据集以及768维向量生成

news/2025/1/8 16:20:49/

Elasticsearch8.17.0在mac上的安装

Kibana8.17.0在mac上的安装

Elasticsearch检索方案之一:使用from+size实现分页

快速掌握Elasticsearch检索之二:滚动查询(scrool)获取全量数据(golang)

Elasticsearch检索之三:官方推荐方案search_after检索实现(golang)

1、面临的首要问题

对于elasticsearch的向量检索的学习,我打算做一个图片检索的方案,图片检索在自动驾驶、ai识图、搜索都有广泛的应用,因此就借着学习elasticsearch的机会,设计一个mvp版本的图像搜索方案,以供有需要的各位小伙伴参考。

在学习向量检索之前,数据是基石,从哪里找上几千张图片,而且还有有一定的代表性,又如何将这些图片转化成向量,都是首先要解决的问题。

2、寻找数据集

12月中旬去阿里参加了elastic的线下meetup,当时阿里同学分享了一个向量测试的性能数据,我对这个数据印象非常深刻,于是在问答环节,请教了这个性能数据测试使用了多大的数据量,索引大小多少等问题,当时说到了一个数据集:ANN_GIST1M 960维,我们可以从这里下载到它:

http://corpus-texmex.irisa.fr/

下载解压后:

这些文件数据,需要使用matlab读取,咱也不太懂,还是找找图片的吧,再用模型跑一下就能出向量。

之后搜索了一些公开的图片数据集,找到了一个小猫、小狗数据集,这个挺有意思,小猫1000张图片,小狗1000张图片,除了训练集还有200张评测集,就用它了,我将数据集上传到了github上,点击查看icon-default.png?t=O83Ahttps://github.com/liupengh3c/career/tree/main/cats_and_dogs_v2需要的同学可以自取。

 这样数据集的问题就解决了,接下来解决抽取图像特征的问题。

3、寻找开源模型,抽取图像特征

本想着网上找个免费的api,输入图片,返回图片768维的特征向量,最后没有找到,只好求助于团队内算法同学,他给推荐了一个openai的开源模型:

https://hf-mirror.com/openai/clip-vit-large-patch14/tree/main

这里所有的文件都需要下载下来:

并汇总放到一个文件夹下,之后编写python代码,用此模型抽取图片特征:

import torch
from PIL import Image
from transformers import CLIPProcessor, CLIPModel
import numpy as np
# 加载预训练的CLIP模型和处理器
model = CLIPModel.from_pretrained("/Users/liupeng/Downloads/clip-vit-large-patch14")
processor = CLIPProcessor.from_pretrained("/Users/liupeng/Downloads/clip-vit-large-patch14")
# 加载图像并进行预处理
image = Image.open("/Users/liupeng/Downloads/dog.11001.jpg")  # 替换为你的图像路径
inputs = processor(images=image, return_tensors="pt")
# 提取图像特征
with torch.no_grad():image_features = model.get_image_features(**inputs)
print("shape:",image_features.shape)
# 对图像特征进行 L2 归一化
# 使用 .norm() 计算 L2 范数并进行归一化
image_features_normalized = image_features / image_features.norm(p=2, dim=-1, keepdim=True)
numpy_array = image_features_normalized.numpy()
# 打印归一化后的特征和特征的模长(应该为 1)
print("归一化后的图像特征:", numpy_array[0])
print("归一化后的模长:", image_features_normalized.norm(p=2, dim=-1))  # 应该接近 1

上面代码实现了单张图片特征提取,后面根据需求再完善。

4、向量索引设计

向量检索,最大的机器瓶颈就是内存,因此我们在设计索引时,应该最大限度的保证内存的占用最低,即使牺牲掉部分精度。

而检索算法:KNN(最近邻检索),它的原理是:计算待查询向量与数据库中所有向量之间的距离,然后按照距离从小到大排序,选择距离最近的 K 个向量作为查询结果。KNN 算法的优点是可以保证精确的结果,但是效率较低,不是elastic的默认检索算法,大家可以参考这篇文章:

ElasticSearch向量检索技术方案介绍,

为了提升向量检索的效率、降低机器内存占用,elastic采用HNSW算法支持向量检索,HNSW是一种近似紧邻检索,牺牲了一定的精度,但是大大提升了检索的效率。

对于向量索引,我们只设计3个字段:

name:本张图片小动物名称,猫or狗
IFV:本章图片向量
path:图片路径或地址

其中检索算法采用hnsw,并使用int8量化,以减少内存占用,这样会牺牲一定的精度,同时磁盘占用量会增加25%左右,向量距离计算逻辑为欧氏距离: 

PUT /vector_search_202412
{"mappings": {"properties": {"name": {"type": "keyword","ignore_above": 256},"path": {"type": "keyword","ignore_above": 256},"IFV": {"type": "dense_vector","index": true,"dims": 768,"similarity": "l2_norm","index_options": {"type": "int8_hnsw"}}}}
}

5、全部数据集抽取特征并入库

首先调整我们抽取特征脚本,增加遍历文件夹所有图片+写入es部分:

import torch
from PIL import Image
from transformers import CLIPProcessor, CLIPModel
import numpy as np
import os
from elasticsearch import Elasticsearch, helpers
# Elasticsearch服务器地址和端口
host = 'https://localhost:9200'
# 用户名和密码
username = 'elastic'
password = 'xpE4DQGWE9bCkoj7WXYE'# 创建Elasticsearch客户端实例,并提供用户名和密码
es = Elasticsearch(hosts=[host], http_auth=(username, password), verify_certs=False,ca_certs="/Users/liupeng/Documents/study/elasticsearch-8.17.0/config/certs/http_ca.crt")
# 检查连接是否成功
if not es.ping():print("无法连接到Elasticsearch")exit()
else:print("成功连接到Elasticsearch")
# 现在你可以使用es变量来与Elasticsearch进行交互了
# 加载预训练的CLIP模型和处理器
model = CLIPModel.from_pretrained("/Users/liupeng/Documents/career/clip-vit-large-patch14")
processor = CLIPProcessor.from_pretrained("/Users/liupeng/Documents/career/clip-vit-large-patch14")
# 加载图像并进行预处理
# folder = "/Users/liupeng/Documents/career/cats_and_dogs_v2/train/cats"
folder = "/Users/liupeng/Documents/career/cats_and_dogs_v2/train/dogs"
for root, dirs, files in os.walk(folder):index_id = 1000for file in files:index_id += 1print(os.path.join(root, file))image = Image.open(os.path.join(root, file))  inputs = processor(images=image, return_tensors="pt")# 提取图像特征with torch.no_grad():image_features = model.get_image_features(**inputs)print("shape:",image_features.shape)# 对图像特征进行 L2 归一化# 使用 .norm() 计算 L2 范数并进行归一化image_features_normalized = image_features / image_features.norm(p=2, dim=-1, keepdim=True)numpy_array = image_features_normalized.numpy()# 打印归一化后的特征和特征的模长(应该为 1)# print("归一化后的图像特征:", numpy_array[0])# print("归一化后的模长:", image_features_normalized.norm(p=2, dim=-1))  # 应该接近 1documents = [{"name": "cat_"+str(index_id), "IFV": numpy_array[0].tolist(),"path":file},]helpers.bulk(es, [{"_index": "vector_search_202412","_id": index_id,"_source": doc}for doc in documents])

上面代码,由于数据集中小猫和小狗是两个不同的文件夹,所以需要跑2次,小猫和小狗各一次。

同时代码都已上传到github上: 

https://github.com/liupengh3c/career/blob/main/features/main.py

推理过程很耗费资源,mac的风扇呼呼的转呀。

占用的空间大小35M:

 到这里向量数据就全部入库完成了。

新的一年。就让我们对过去所有开心的事做个总结,对不开心的所有事也做个了结,微笑着迎接属于我们所有人的2025年,祝我可爱的小伙伴们新年快乐。 

天亮了,去跑个20.25km迎接新一年的到来~~~~~~~~~~~~~


http://www.ppmy.cn/news/1561047.html

相关文章

开源Material Design WPF UI 控件库简单上手

背景:学过怎么弄,但是又忘记了,现在复习一下这个控件库的使用 1.先到NuGet中将下载到项目中: 2.到github MaterialDesignInXamlToolkit中点击Getting started,将App.xaml改成样例那样

Go Ebiten游戏库入门教程

Ebiten介绍 Ebiten是一款基于Go言语的轻量级开源游戏库,适合快速开发和原型构建2D游戏。它支持多平台,包括Windows、macOS、Linux、iOS和Android。这使它成为小型游戏开发者和试验性项目的优秀选择。 游戏循环精简明了,包括Update (逻辑更新…

Python学习路线

以下是一个Python详细学习路线: 一、入门阶段(第1 - 2个月) 环境搭建与基础语法 安装与配置: 从Python官方网站(Download Python | Python.org)下载适合自己操作系统的Python版本并进行安装。 配置环境变…

计算机毕业设计Python动漫推荐系统 漫画推荐系统 动漫视频推荐系统 机器学习 bilibili动漫爬虫 数据可视化 数据分析 大数据毕业设计

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

WebApi使用 (.Net Framework版)

1 创建 使用.Net做web后端,推荐使用.Net Core,微软在此基础上做了很多适配,包括内置Swagger,可以直接启动等等。而.Net Framework版,需要手动配置很多内容。 如果需要调用的项目是基于.Net Framework,那么…

如何做到IP查询检测?

来自DNS Davis团队开创了 来自DNS的新方法,即在资源记录中添加位置字段以提升地理位置查询精度,这本是充满希望的创新之举。然而,现实中却困难重重,管理员对资源记录的修改和更新积极性不高,导致这一构想在起步阶段就…

VSCode报错Module ‘“xx.vue“‘ has no default export.Vetur(1192)

在开发vue3项目引入自定义组件的时候,代码中总是会出现如下图中的错误: 错误提示中可以看到关键字Vetur Vetur是一个vscode插件,用于为.vue单文件组件提供代码高亮以及语法支持,但他只适用于对vue2语法的高亮提示,对…

前后端规约

文章目录 引言I 【强制】前后端交互的 API请求内容响应体响应码II 【推荐】MVC响应体III【参考】IV 其他引言 服务器内部重定向必须使用 forward;外部重定向地址必须使用 URL 统一代理模块生成,否则会因线上采用 HTTPS 协议而导致浏览器提示“不安全”,并且还会带来 URL 维护…