Product quantization for nearest neighbor search

Hervé Jégou, Matthijs Douze and Cordelia Schmid, PAMI2011, INRIA LEAR组,被引用次数:170
阅读时间:2015-04-10~11

文章为近似最近邻搜索提供了一种新方法:将高维数据量化划分为一些独立的低维子空间的Cartesian乘积,称之为PQ法。文章先形式化地描述了最近邻问题,并解释了对一个高维向量进行PQ,在内存使用量和Assignment复杂度上都比k-means优秀。然而在query时不能忍受遍历所有dataset的方式,提出coarse k-means划分成子集,再进行PQ法。最后作者将这种方法与HE、FLANN进行了比较,击败HE,和FLANN各有千秋。

一、PQ法

  1. D 维向量划分为 m 份,于是子空间维度 D=D/m
  2. 对数据子空间聚类,centroids数为 k ,且所有子空间的centroids数一样;
  3. assignment时,codebook空间为 C=C1×...×Cm ,对每个子空间进行最近centroid;
  4. 最后每个高维向量编码成 m 维的centroids索引;
  5. query时,计算
    d˜(x,y)=d(x,q(y))=jd(uj(x),qj(uj(y)))2
    其中 j 表示为各子空间, uj(x) 表示对 D 维向量 x 的低维映射, q(x) 表示 x 对应的centroid;

文章提出了两种PQ后的距离度量方法,一种是上述提到的是Asymmetric Distance Computation(ADC),还有一种为Symmetric Distance Computation(SDC)

dˆ(x,y)=d(q(x),q(y))=jd(qj(x),qj(y))2
几何表示为
Product quantization for nearest neighbor search_第1张图片
文章对这两种度量方法进行了讨论,ADC与SDC相比,ADC具有更小的误差上界,并且estimator of the squared distance(没看懂),作者提倡使用ADC。

Search时相似度的计算

distab为256*8表示query各子维度与各子centroids的距离,其中256为子维度centroids的数量
cbase为8*1000000表示database各子维度的q(y)
for i 每个database
    for j 每个子维度
        dis(i) += distab(cbase(j, i), j)

上述伪代码未考虑对稀疏向量的优化,如在图像检索,BOF形成的向量就很稀疏,采用上述方式则非常不值。可采用常规的inverted list优化,将上述两层循环调整,for每个子维度的循环放在最外层,load database时子维度每个centroid建立已inverted list,则第二层循环for inverted_list( centroid )能特别高效。

二、非完全遍历搜索

这里借用了“分桶”的思路,先对所有原始数据做k-means,因为k值很低(实验中有10,000数据,256个centroids),所以称之为coarse k-means,然后在query时,multiple assignment到一些centroids,接着对残留(residual)再做PQ,流程如下图。
Product quantization for nearest neighbor search_第2张图片
建立索引,对 y 进行如下处理:

  1. 量化 y qc(y) ,1-NN;
  2. 计算残留 r(y)=yqc(y)
  3. r(y) 进行PQ,产生低维code;
  4. 将所有dataset组织成inverted list:coarse centroids数组->数据子集PQ码

搜索过程,K个最近,query x:

  1. 量化 x ,n-NN;
  2. 计算映射n个centroids后的各个残留;
  3. 计算残留与对应“桶”中各向量的PQ距离;
  4. 利用堆排序,选取最小K个;

三、疑问

Product quantization for nearest neighbor search_第3张图片
算法复杂度表,find the k smalles distances利用堆排复杂度应该nlogk,对这里的表达很迷茫。

参考

  • 近似最近邻问题相关算法总结
  • Searching with quantization package,文章对应的matlab code,使用了Yael library,该库不能在windows下编译。如果想在windows下玩,可以用vlfeat库进行部分函数替换。

你可能感兴趣的:(paper)