Guidelines
数据集大约有1M的向量,所以使用穷举索引会非常慢,好的选择是使用IdexIVFFlat索引,它会返回精确距离,但是偶尔会丢掉一个相近的向量,只是因为它不是穷举算法。
下面使用不同的索引在1M的数据集上做索引。主要关注如下的平衡:
- 速度,测试机器使用"Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz",开启20个线程。报告显示的批量模型,单位是ms。(所有query向量是同时处理的)
- 准确率。使用“1-NN recall @R”的评测方法,R取值为1,10或者100。这是实际最相似的向量出现在前R召回结果中比值。
注意:这个是最优化的设置,如果使用单线程会慢十倍,如果是逐个发起请求会慢2-3倍(可以参考下面sift_1M的耗时)。
测试的索引类型引用了index_factory函数创建索引时使用索引Key。所有的索引,单次请求返回100个相似结果。
CNN activation maps
从1M图片中抽取4096维度的描述符,请求图片采用通用处理方法。4096D的描述事先会通过PCA降维变成256D(PCA变换的消耗没有被计入结果中),结果如下:
图横轴为准确率,越靠右侧准确率越高,纵轴是单个请求耗时,越靠下方耗时越短, 由此可知IVF适合准确率要求高的环境,IMI适合准确率低,到耗时要求的环境。
注意:IVF16384的结果会比IVF4096稍好,但是在train和add阶段的耗时明显多了很多。
如果需要留意内存消耗,可以使用IndexIVFPQ压缩向量。
IVF4096,Flat没有任何压缩,用来和其它Index作对比。
例如“OPQ32_128,IVF4096,PQ32”每个向量使用字节数为: code + id = 32+8=40个字节。1M的数据集会被压缩到40M,但是会有预计算表,几何数组等的内存开销。
我们还使用在Imagenet上训练的resnet-34描述符,并在Flickr100M前1M个图像上进行特征提取,我们删除了两个顶部的layer以获得512维度的激活向量。 得到类似的结论:
这个很有意思,PCA128后丢失信息很多,IMI2x10后,丢失信息不多。
SIFT 1M
这是研究论文中常用的基准。 它由从图像块中提取的SIFT描述符(128D)组成。
由上图得到的结论和CNN数据集是类似的。
下面论述一下性能和线程数、批量操作的关系:
- nt1: 单线程批量操作,
- nobatch/nobatch_nt1: 单线程且一个一个提交
- parallelqueries:多线程,一个一个的提交
图纵轴OPS为每秒请求数,越高越好,横轴是10度量(或交叉度量)的10折精度,原文为:“the x-axis is the 10-precision at 10 measure (or intersection measure)”
显示单线程运行时,会慢5倍到12倍。每次提交一个请求时,多线程是没用的。