乘积量化( Product Quantization )近似最近邻搜索 分享

看了CHIERYU的理解,受益匪浅。


Product Quantizer翻译过来是 乘积量化 ,从字面理解大概包括了两个过程特征的分组量化过程和类别的笛卡尔积过程。假设有一个数据集,那么K-means的做法就是给定类别数目K,目标函数是所有样本到类中心的距离和最小,迭代计算优化目标函数,得到K个类中心和每个样本所属的类别。目标函数不变, 乘积量化 的做法是: 
(1)数据集为K个类别,每个样本以一个vector的形式表示,维数为d,将vector的各个分量分成m组。 
(2)将所有vector的某组分量作为数据集,采用k-means算法得到 个类中心,运行m次k-means算法,则每组都有 个类中心,记这 个类中心为一个集合。 
(3)将上述得到的m个集合做笛卡尔积,就得到整个数据集的类中心了。






二、索引结构

索引的建立过程如下: 
乘积量化( Product Quantization )近似最近邻搜索 分享_第1张图片 
上图中主要涉及三个过程,coarse quantizer,product quantizer和append to inverted list。 
1.coarse quantizer。 
对数据库中的所有特征采用K-means聚类,得到粗糙量化的类中心,比如聚类成1024类,并记录每个类的样本数和各个样本所属的类别。这个类中心的个数就是inverted list的个数。把所有类中心保存到一张表中,叫coarse_cluster表,表中每项是d维。 
2.product quantizer 
计算y的余量,这里写图片描述,用y减去y的粗糙量化的结果得到r(y)。r(y)维数与y一样,然后对所有r(y)的特征分成m组,采用乘积量化,每组内仍然使用k-means聚类,这时结果是一个m维数的向量,这就是上篇文章中提到的内容。把所有的乘积量化结果保存到一个表中,叫pq_centroids表,表中每项是m维。 
3.append to inverted list 
前面的操作中记录下y在coarse_cluster表的索引i,在pq_centroids表中的索引j,那么插入inverted list时,把(id,j)插入到第i个倒排索引这里写图片描述中,id是y的标识符,比如文件名。list的长度就是属于第i类的样本y的数目。处理不等长list有些技巧。

三、基于IVFADC的搜索

检索过程如下: 
乘积量化( Product Quantization )近似最近邻搜索 分享_第2张图片
主要包括四个操作: 
1.粗糙量化 
对查询图像x的特征进行粗糙量化,即采用KNN方法将x分到某个类或某几个类,分到几个类的话叫做multiple assignment。过程同对数据集中的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。

 

我个人理解,乘积量化是很巧妙的一个算法,但是维度变高的时候还是很尴尬的。

你可能感兴趣的:(乘积量化( Product Quantization )近似最近邻搜索 分享)