AI基于近邻图的向量搜索案例(二)

news2024/11/25 22:59:16

Graph部分

Graph部分,通过先构建KNN图,再根据RNG Rule移除不符合要求的边,得到RNG。

KNN图的构建

KNN图是指对于样本数据中的每一个点,将其自身与K个近邻点连接而形成的图。

由于样本数据规模非常大,我们采用了一定的算法构建近似的KNN图,具体算法[1]如下:

  1. 随机划分一组子空间。在这里我们可以采用不同的划分方式,SPTAG采用了TPTree[2]的方式划分,即通过构建一定深度的TPTree,取其中一个叶子结点的作为子空间。
  2. 对该子空间内的点,利用Brute-Force方式,构建KNN子图。
  3. 重复以上步骤N次。N越大,得到的KNN图越接近真实的KNN图。

由于每次随机划分一组子空间,会包含部分新的近邻点,而与之前划分的空间重叠的近邻点,可以将两组子空间构建的KNN子图连接成更大的KNN图。因此,划分次数越多,KNN子图越大,直到得到真实的KNN图为止。

例如,

  1. 第一次划分出一组子空间,样本中包含了两个p点的真实最近邻p4和p6,利用Brute-Force对该子空间构建KNN图后,P点会与这两个点连接,得到kNN子图。

  2. 在第二次划分子空间的时候,样本中包含了两个新的真实最近邻p3和p5,对该子空间构建KNN后,会使p点与p3和p5相连,此时的kNN图已经包含了4个p的真实最近邻。

  3. 继续重复多次划分并对划分的子空间构建KNN图后,会使p点与大部分的真实最近邻连通,从而构建比较接近真实KNN图的近似KNN图。

注:

  • [1] 算法来源:Scalable k-NN graph construction for visual descriptors.王静, 王敬东, 曾刚, 涂卓文, 甘瑞, 李世鹏. CVPR 2012.

  • [2] 上述的TPTree可以认为是KDTree的变种,在论文《Trinary-Projection Trees for Approximate Nearest Neighbor Search》中被提出。其与KDTree主要区别在于采用了不同的划分函数,相比KDTree能对空间更灵活地划分,如下图:

KNG的构建

基于KNN图,我们需要根据RNG Rule删除不符合要求的边。这样做的目的是避免陷入局部最优。

RNG Rule:删除三角形中的最长的边。

对于KNN图,若点a, b, q相互连接,我们要分别计算3点的距离,删除最长的边。例如,图中需删除qb边,因为我们可以通过a从q访问到b。

SPTAG的使用

安装

确保安装以下依赖:

  • 斯威格>= 3.0
  • cmake >=3.12.0
  • 升压 == 1.67.0

Window安装可以参考文档:Windows Installation。

构建

  1. 克隆仓库mcirosoft/SPTAG。

    <span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>git clone https://github.com/microsoft/SPTAG
    </code></span></span></span>
  2. 进入克隆的仓库的目录,执行以下命令:

    <span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code> mkdir build
     cd build
     cmake -A x64 ..
    </code></span></span></span>

    注:如果提示“CMAKE Could not find Boost 1.67”,可以使用以下命令指定Boost目录。

    <span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code> cmake -DBOOST_ROOT=[your boost root] -DBOOST_INCLUDEDIR=[your boost include directory] -DBOOST_LIBRARYDIR=[your boost library directory] ..
    </code></span></span></span>

    其中,

    • BOOST_INCLUDEDIR:C:\INSTALL_DIR\boost_1_67_0\
    • BOOST_LIBRARYDIR:C:\INSTALL_DIR\boost_1_67_0\lib64-msvc-12.0
    • BOOST_ROOT:C:\INSTALL_DIR\boost_1_67_0\boost
  3. 进入刚刚新建的目录,在Visual Studio中打开,编译运行。buildSPTAGLib.sln

  4. 编译完成后,会在目录下生成我们需要的内容,将这个目录添加到环境变量中。build/releasePYTHONPATH

  5. 打开Python,执行,若无报错则已完成SPTAG的构建。import SPTAG

使用

完成了SPTAG的构建后,我们可以在Python中使用,下面是SPTAG的Python接口。详细使用内容请参考:SPTAG Quick Start。

Python接口

  1. 初始化索引

    <span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>SPTAG.AnnIndex(algo, type, dimension)
        algo: 索引算法的类型,可选'BKT', 'KDT'
        type: 向量数据类型,如'Float','Int8', 'Int16'
        dimension: 输入向量的维度
    </code></span></span></span>
  2. 设置构建参数

    <span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code> SPTAG.AnnIndex.SetBuildParam(key,value)
         key: 参数名
         value:参数值
    </code></span></span></span>
  3. 构建索引

    <span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code> SPTAG.AnnIndex.Build(vectors, sample_num)
         vectors: 输入向量数据集
         sample_num: 输入向量的数量
    </code></span></span></span>
  4. 保存索引

    <span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code> SPTAG.AnnIndex.Save(index)
         index: 输出保存的索引名,加载索引时需指定
    </code></span></span></span>
  5. 加载索引

    <span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code> SPTAG.AnnIndex.Load(index)
         index: 待加载的索引名 
    </code></span></span></span>
  6. 搜索

    <span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code> SPTAG.AnnIndex.Search(query, k)
         query: 查询向量
         k: 指定返回前k个最近邻
    </code></span></span></span>
  7. 添加至索引

    <span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code> SPTAG.AnnIndex.Add(vectors, sample_num)
         vectors: 待添加向量数据集
         sample_num: 待添加向量的数量
    </code></span></span></span>
  8. 从索引中删除

    <span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code> SPTAG.AnnIndex.Delete(vectors, sample_num)
         vectors: 待删除向量数据集
         sample_num: 待删除向量的数量
    </code></span></span></span>

使用示例

下面我们提供了两个SPTAG的使用示例。

随机数据示例

我们先随机生成包含100条2维的随机向量数据集

<span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:#1f2328"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>import numpy as np

d = 2  # Dimension
nb = 100  # Dataset size

np.random.seed(1234)
randomData = np.random.random((nb,d)).astype('float32')
</code></span></span></span></span>

利用生成的数据构建索引testIndex

<span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:#1f2328"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>import SPTAG

# Build index
algorithm = 'KDT' # 'BKT' or 'KDT'
distmethod = 'L2' # 'L2' or 'Cosine'

i=SPTAG.AnnIndex(algorithm,'Float',randomData.shape[1])
i.SetBuildParam("NumberOfThreads",'4')
i.SetBuildParam("DistCalcMethod",distmethod)

if i.Build(randomData,randomData.shape[0]):
    i.Save("testIndex")
</code></span></span></span></span>

任意指定查询向量,在此我们指定查询向量xq为[0.2, 0.4]。加载索引,搜索并指定返回前4个与xq的最近邻。testIndex

<span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><span style="color:#1f2328"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code># Search

k=4 # Number of results to return
xq = np.array([0.2 , 0.4 ]).astype('float32') # The query vector

i = SPTAG.AnnIndex.Load('testIndex') # load index

result = i.Search(xq,k)

print(result[0]) # ids
print(result[1]) # distances
</code></span></span></span></span>
图片向量搜索示例

图片向量搜索的原理如下图:

首先,利用VGG16模型将图片数据集转换成向量,再利用SPTAG构建索引。

当给定查询图片时,我们利用同样的算法将图片转换成查询向量,使用查询向量在索引中搜索K个最近邻向量,搜索得到的结果中的metadata存储了向量对应的图片路径,通过该路径可以找出对应的图片。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1400155.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI+量化02_金融市场的基础概念

文章目录 问答之纯小白 vs GPT4Q1. 请用尽可能简短的语句或例子&#xff0c;给小白讲解宏观经济Q2. 给小白讲解资本边际效率 思维导图 目标: 掌握量化金融知识、使用Python进行量化开发 背景&#xff1a;纯小白 参考资料&#xff1a;https://github.com/datawhalechina/whale-q…

Haxe-UnrealEngine5

Haxe-UnrealEngine5 结论 UE C header > External/**.hx.hx > .h/.cpp&#xff0c;和 UE C 一起编译使用 hxcpp 来调试 .hx good&#xff1a; 理论上不仅限反射代码走 UE C&#xff0c;无需维护 backend&#xff0c;比如 Lua Binding理论上接近 UE C 的性能 bad&…

Python-基础篇-数据结构-列表、元组、字典、集合

文章目录 思维导图❓ 大抵是何物数据结构切片 &#x1f4ac;具体是何物列表&#x1f4bb; list&#x1f4bb; [ ]自我介绍精神面貌使用说明生理体征增删查改 方法汇总 元组&#x1f4bb; tuple&#x1f4bb; ( )自我介绍使用说明精神面貌生理体征增删查改 字典&#x1f4bb; di…

【网络安全】【密码学】【北京航空航天大学】实验五、古典密码(中)【C语言实现】

实验五、古典密码&#xff08;中&#xff09; 实验目的和原理简介参见博客&#xff1a;古典密码&#xff08;上&#xff09; 一、实验内容 1、弗纳姆密码&#xff08;Vernam Cipher&#xff09; &#xff08;1&#xff09;、算法原理 加密原理&#xff1a; 加密过程可以用…

【网站项目】329网月科技公司门户网站

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

一个简单的ETCD GUI工具

使用ETCD没有好用的GUI工具&#xff0c;随手用c#写了一个&#xff0c; 做得好玩的一个ETCD GUI工具&#xff0c;后面加上CLI 工具&#xff0c;类似于 redis Cli工具一样&#xff0c;简化在 Linux下面的操作&#xff0c;不知道有没有必要&#xff0c; git 地址如下&#xff0c;…

KDJ指标的算法、原理和特性

KDJ的完整中文名称是随机摆动指标&#xff0c;是短线交易者最常用的指标之一。作为应用最广泛的指标之一&#xff0c;KDJ的用法网上随处可见&#xff0c;但大部分介绍都只会告诉你超买超卖&#xff0c;金叉死叉&#xff0c;详细点的讲讲背离和钝化&#xff0c;至于为什么这么用…

竞赛保研 机器视觉opencv答题卡识别系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 答题卡识别系统 - opencv python 图像识别 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分…

Erp读书笔记20240121

ERP&#xff08;Enterprise Resource Planning&#xff0c;企业资源计划&#xff09;是一种集成的企业管理软件系统&#xff0c;它可以帮助企业实现内部和外部资源的整合和管理。 ERP 系统具有纵观全局的特点&#xff0c;它可以涵盖企业的各个部门和业务流程&#xff0c;实现信…

力扣每日一练(24-1-20)

大脑里的第一想法是排列组合&#xff0c;直接给出超级准确的最优解。 但不适用&#xff0c;hhh 只要连续的n个元素大于或者等于target就可以了 题目比自己想象的要好解决 解法是使用滑动窗口算法。这个算法的基本思想是维护一个窗口&#xff0c;使得窗口内的元素总和大于等于目…

初识MQ-同步异步

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、同步通讯二、异步通讯2.1.异步调用方案2.2.异步的优缺点 三、什么时MQ3.1 mq和broker3.2几种mq的优缺点对比 总结 前言 一、同步通讯 同步调用问题&#…

Windows系统字体尺寸学习

调用GetTextMetrics来获得字体尺寸信息, 函数返回设备描述表中当前选定的字体信息&#xff1b; 返回值到TEXTMETRIC类型的结构中&#xff1b; 返回字段值的单位取决于当前设备描述表映射方式&#xff1b;默认映射方式是MM_TEXT&#xff0c;值的单位是像素&#xff1b; 前7个字…

『C++成长记』模板

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;C &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、泛型编程 二、函数模板 &#x1f4d2;2.1函数模板概念 &#x1f4d2;2.2函数…

第 122 场 LeetCode 双周赛题解

A 将数组分成最小总代价的子数组 I 枚举&#xff1a;枚举后两个子数组的起始下标 class Solution { public:int minimumCost(vector<int> &nums) {int n nums.size();int res INT32_MAX;for (int i 1; i < n; i)for (int j i 1; j < n; j)res min(res, n…

AI日报:扎克伯格瞄准AGI通用人工智能

文章目录 Meta瞄准通用人工智能领域Meta的目标Meta的产品 FAIR移动和装载H100扎克伯格对人工智能竞争对手的真实动机持怀疑态度Meta抛弃了元宇宙吗&#xff1f; Meta瞄准通用人工智能领域 Meta首席执行官马克扎克伯格&#xff08;Mark Zuckerberg&#xff09;在一份可能改变全…

数字式温度计的设计

根据前期的设计要求&#xff0c;我们需要设计一个数字式温度测量计&#xff0c;能够实现将温度信号实时转换成实际方便查看的形式输出。 目录 题目要求 设计思路 电路模块 温度传感器电路 A/D转换电路 数码管显示电路 仿真显示 题目要求 以下为题目的设计参考电路&…

天龙八部场景编辑器(源码+软件+教程)

天龙八部场景编辑器&#xff0c;里面包括《源码》&#xff0c;《软件》&#xff0c;《教程》&#xff0c;喜欢研究天龙八部的可以下载看看。 天龙八部场景编辑器&#xff08;源码软件教程&#xff09; 下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1GWXErav0…

论文阅读_CogTree_推理的认知树

英文名称: From Complex to Simple: Unraveling the Cognitive Tree for Reasoning with Small Language Models中文名称: 从复杂到简单&#xff1a;揭示小型语言模型推理的认知树链接: http://arxiv.org/abs/2311.06754v1代码: https://github.com/alibaba/EasyNLP作者: Junbi…

PLC物联网网关BL104实现PLC协议转MQTT、OPC UA、Modbus TCP

随着物联网技术的迅猛发展&#xff0c;人们深刻认识到在智能化生产和生活中&#xff0c;实时、可靠、安全的数据传输至关重要。在此背景下&#xff0c;高性能的物联网数据传输解决方案——协议转换网关应运而生&#xff0c;广泛应用于工业自动化和数字化工厂应用环境中。 无缝衔…

【leetcode题解C++】160.相交链表 and 142.环形链表II

​160.相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 示例 1&#xff1…