Nearest Neighbor Search

Product Quantizer2011年在IEEEE上发表的论文《Product Quantization for Nearest Neighbor Search》中提出来的.

•提出目的:在内存和效率之间求得一个平衡,既保证图像索引结构需要的内存足够,又使得检索质量和速度比较好。

•思想:把空间分解到低维子空间的笛卡尔乘积,然后分别独立量化每一个子空间。(训练模型可以并行进行)

pq算法空间分解
codebookcodeword
映射一个d维的向量到另一个向量:q(x) ∈ C = {ci | ci ∈ Rd, 0 ≤ i ≤ k − 1}.

集合C叫做码本,ci 叫做码字,k是码字的数量。

pq算法翻译过来叫做乘积量化,该算法是用来做图像/视屏检索,图像识别和分类,图像位姿评价以及很多计算机视觉中的问题。图像可以用一些列的特征点表示,比如SIFT特征点,GIST特征点等,这些特征点就是一系列的向量。pq算法就是寻找近似最近邻向量,比如在一个很多向量组成的数据集中,给定一个向量,找出这个给定的向量在这个数据集中一些近似的向量。这个算法很有意义,尤其在图像检索中有很大的意义。如果把一幅图像看做一个向量的话,就可以找出这幅图像在整个图像数据集中相似的图像。在向量组成的数据集中找出一个查询向量的近似向量,一个很简单的想法就是把这个向量和整个数据集中的每一个向量进行比较,看和哪些向量的差异最小,差异最小的那些向量就是这个查询向量的进行近似向量。而度量两个向量的差异,一个很简单的办法就是度量这两个向量差的范数,可以用L2范数进行度量,几何上的意义就是两个点之间的欧式距离。但是如果这个向量的维数很高(假设维度为d),而且要寻找相似向量的数据集很大的话(数据集中有M个向量),计算量将会是很庞大(两个向量相似性的度量需要进行d次减法,d次乘法,d次加法,复杂度为O(d*M))。这只是计算出了相似性的度量,然后还要对这些度量进行排序,选出前k个最小的度量,这个复杂度将是非常高。这里提出了pq算法,会大大减少计算复杂度。

具体算法过程是:

•1. 将D维向量划分为m份,于是子空间维度D∗=D/m;

•2. 对数据子空间聚类,centroids数为k∗,且所有子空间的centroids数一样;

•3. assignment时,codebook空间为C=C1×...×Cm,对每个子空间进行最近centroid;(assignment即是对base库中的每个向量的子向量找到最近的codeword)

•4. 最后每个高维向量编码成m维的centroids索引;

•5. query时,计算有两种方法分别是SDC,ADC

首先,把数据集中的向量看成一个一个点,这些点散布在一个二维的坐标中。乘积量化就是把这个一些列二维点组成空间分割成一个一个很小的块,每一个块中由一些向量组成。打个比方把人看做是一个向量,中国由很多省和自治区组成,而每个省和自治区中有很多人,这样就对整个空间进行了一个管理。而这个分类用的是k-means聚类算法,得到k个聚类中心,每一个聚类中心就是每一个小块里面向量的代表。但是聚类中心的个数直接影响了算法的精度和效率。如果块的个数太少了,比如一个极端的例子,只有一个聚类中心,那么所有的向量都聚到一个类别中,那么就会用一个向量来近似代替所有的向量,很明显,这样向量之间就缺少了个性,难以进行相似度的区分。如果聚类个数很多的话,比如一个极端的例子,每一个向量都是一个聚类中心,那么每个向量还是代表自己,这样向量之间就缺少了共性,算法就退化到了上面介绍的最简单的算法。所以k个数的选取很重要,既不能太小也不能太大。

这篇论文把空间分解到低维子空间的笛卡尔乘积,然后分别独立量化每一个子空间。如果把空间划分了m个子空间,用Ks表示一个聚类中心的个数,那么整个空间就使用了m*Ks个聚类中心,但由于每个子空间是正交的,可以表示出笛卡尔积的形式,这样就可以表达Ks的m次方个聚类中心。这样将大大增强算法的效率,也能够使用少的聚类中心实现高的精度。至于为什么可以表示成笛卡尔乘积的形式,可以看下面的图,增强理解。

SDC
Symmetric Distance Computation,x是待查询向量,y是base向量中的一个用量化结果来代替x,y,那么x,y之间的距离可以近似计算为:

ADC
Asymmetric Distance Computation,与SDC不同之处在:用y的量化结果来代替y,x保持不变。那么x,y之间的距离可以近似计算为:

SDC VS ADC

可以看到整体来说,量化距离和实际距离是呈正相关关系的,但是误差也是不可避免的。同时也可以看到,量化距离一般比实际距离的值要偏小一些,并且SDC算法的偏差相对ADC的偏差更大。

ADC与SDC相比,ADC具有更小的误差上界,,作者提倡使用ADC。

原因分析:用量化后的向量去替代原来的向量,有损失。

SDC和ADC都是基于查找表的,之所以比之前所得简单的方法要高效是因为它利用k-means聚类,得到了很多个码字,可以利用这个码字来代替整个块。而事先我们已近把数据库里的向量量化到了每一个码字,这样只要我们将所有码字之间的距离存放在一张表里,来了一个查询向量,只要对这个查询向量进行量化了对应的码字,然后查找表就可以近似得到它们之间的距离。

IVF
上面介绍的ADC,SDC都是在整个数据集里面搜索,IVF(inverted file structure)是一个非完全遍历搜索,借用了“分桶”的思路,先对所有原始数据做k-means,因为k值很低(实验中有10,000数据,256个centroids),所以称之为coarsek-means,然后在query时,multiple assignment到一些centroids,接着对残留项(residual)再做PQ。

数学上的表达:

流程:

算法步骤:

•1. 量化y为qc(y),1-NN;

•2. 计算残留r(y)=y−qc(y);

•3. 将r(y)进行PQ,产生低维code;

•4. 将所有dataset组织成invertedlist:coarse centroids数组->数据子集PQ码

IVFADC

IVFADC是结合了IVF分桶,和ADC计算相似性的想法。

步骤:

•1.粗糙量化

–对查询图像x的特征进行粗糙量化,即采用KNN方法将x分到某个类或某几个类,分到几个类的话叫做multipleassignment。过程同对数据集中的y分类差不多。

•2.计算余量

–计算x的余量r(x)。

•3.计算d(x,y)

–对r(x)分组,计算每组中r(x)的特征子集到pq_centroids的距离。根据ADC的技巧,计算x与y的距离可以用计算x与q(y)的距离,而q(y)就是pq_centroids表中的某项,因此已经得到了x到y的近似距离。

•3.最大堆排序

–堆中每个元素代表数据库中y与x的距离,堆顶元素的距离最大,只要是比堆顶元素小的元素,代替堆顶元素,调整堆,直到判断完所有的y。

(注意这里的最大堆排序:假设要返回前k个最小的距离,把最开始比较的k个距离建成一个最大堆,然后后面比较的距离和最上面的数进行比较,如果比最大堆上面的数大,这个距离就直接剔除,如果比最上面的距离小,就把最上面的距离剔除,把这个距离插入到最大堆,并进行调整,始终保持最大堆得结构,最后这个最大堆里的数就是前k个距离最小的距离。)

用数学语言来描述这个过程如下:


multiple assignment
•与y都分到了这个voronoi包,如果不采用multipleassignment方法,则只会在voronoi包中搜索与x接近的y,明显voronoi包2,voronoi包3中与x更近的y不会被检索到,采用multipleassignment的方法,在x的w个最近粗糙类中心中搜索y,那么准确率就提高了。但这要求遍历w个list,费内存和时间,是以牺牲空间和时间换准确率。

评价标准
采用recall@R,recall@R的定义如下:

The performance measure isrecall@R, that is, for varying values of R, the average rate of queries forwhich the 1-nearest neighbor is ranked in the top R positions.

因此,在求recall@R的时候只需要看gist_groundtruth.ivecs中每个query的第一个答案是否出现在其TopR中,如果在其中,计算器count加1,最后算count/1000就得到了recall@R。一句话,recall@R就是测试集的TopR结果中包含1-NN的比例。

Descriptors of Dataset


实验结果分析

SIFTdataset: recall@100 for the IVFADC approach as a function of the memory usagefor k∗=256 and varying values of m = {1,2,4,8,16}, k0 = {1024,8192} and w ={1,8,64}.

(注:这是我自己实现的,上面一个图是论文里面的。实验结果基本和论文里的结果一样)

 

(后面几个图都是论文中给出的,就是用来说明这个算法不仅执行速度高效,而且精度也很高)

自己实现了ADC,SDC,IVFADC,下载地址如下:

SDC下载地址:点击打开链接


ADC下载地址:点击打开链接


IVFADC下载地址:点击打开链接

数据集下载地址:点击打开链接

yael库下载和使用地址:点击打开链接

yael_kmeans windows 下可matlab中mex运行c代码:点击打开链接


--------------------- 
作者:三更灯火五更鸡 
来源:CSDN 
原文:https://blog.csdn.net/liuheng0111/article/details/52213724 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值