• 【4】facebook大数据搜索库faiss使用——Faiss索引介绍


    基础索引如下所示:

    • 精确索引(IndexFlatL2): 主要参数d;占用字节4d;是否穷尽式搜索:是;
    • 内积精确检索(IndexFlatIP):d;4d;是;
    • 级联式图搜索(IndexHNSWFlat):d,M; 4d+8M; 否;
    • 倒置文件与精确后检验(IndexIVFFlat):quantizer,d,nlists,metric; 4d;否
    • 局部感应哈希(iNDEXlsh): d,nbits; nbits/8; 是
    • 标量量化(IndexScalarQuantizer):d; d; 是
    • PQ(IndexPQ): d, M, nbits; M(nbits=8); 是
    • 倒排文件+标量量化(IndexIVFScalarQuantizer):quantizer, d, nlists, qtype; d或d/2; 否
    • IVFADC粗量化+PQ+残差(IndexIVFPQ):quantizer,d, nlists, M, nbits; M+4或M+8;否
    • IVFADC+R即为IVFADC+基于code的rerank(IndexIVFPQR):quantizer,d, nlists, M, nbits, M_refine, nbits_refine; M+M_refine+4或M+M_refine+8; 否

    单元捕获方法

    常用的一种加速检索过程,但以一定找到最近邻为代价的方法是是使用例如k-means的分割技术,对应的算法有时称之为 单元捕获方法
    我们使用一种基于多捕获的分割方法:

    • 特征空间分割为ncells单元。
    • 数据集向量根据哈希函数赋值到其中的一个单元,存储在ncells个倒置列表的倒置文件系统中(在k-means中,查询向量会赋值到离它最近的中心点)。
    • 查询时,选择nprobe个倒置列表;
    • 查询向量和每个列表中的每个库向量比较。

    通过上述方法,只有部分数据库向量与查询向量比较:初步估计,这个比例大约是nprobe/ncells,但是需要注意的是,这个估计通常是偏低的,因为各个倒置列表并不是等长的。当给定查询向量的最近邻所在单元未被选中时,就会查询失败。
    Faiss C++对应的index是IndexIVFFlat。构造函数将index作为参数,用于倒置列表的赋值,查询操作在这个index中进行,返回倒置列表中向量ID。

    使用带有Flat Index单元捕获方法作为粗分类量化器

    通常,我们使用Flat Index作为粗分类量化器。IndexIVF的训练方法给这些flat index添加中心点。nprobe在查询时确定(对于衡量速度和精确度很有用)。
    注意:n表示索引的点数,选择这个中心点数的常用方法:赋值到中心点的花费 和 当解析倒置列表时需要计算的距离次数。中心点的数目大致为:ncentroids=C*sqrt(n).
    注意 IndexIVFKmeansIndexIVFSphericalKmeans不是对象,而是返回IndexIVFFlat对象的函数。
    警告:分割方法容易遭遇维度诅咒,对于及其高维的数据,要得到好的召回率需要很大数目的probe值。

    和LSH的关系

    最有名的单元捕获方法就是E2LSH,但是这个方法和它的演变方法有两个缺点:

    1. 需要很多哈希函数获得较好的结果,导致占用内存很多;
    2. 哈希函数不适用于输入数据,容易导致次优选择。

    二值code

    在C++,一个LSH index声明:

    IndexLSH* index = new faiss::IndexLSH(d, nbits);
    

    其中d是输入向量维度,nbits是每个存储向量的比特位数目。
    而python的(改进的)LSH index构建和检索如下:

    n_bits = 2*d
    lsh = faiss.IndexLSH(d, n_bits)
    lsh.tracin(x_train)
    lsh.add(x_vase)
    D, I = lsh.search(x_query, k)
    

    注意: 该算法使用的不是vanilla-LSH,而是更好的选择。

    基于量化的方法

    在C++,基于量化的index由关键字PQ定义。其中n_bits必须等于8,12或者16.维度d必须是m的倍数。

    倒置文件系统与PQ

    倒置文件系统+PQ可能对于大规模检索最有用。通常如下使用:

    coarse_quantizer = faiss.IndexFlatL2(d)
    index = faiss.IndexIVFPQ(coarse_quantizer, d, ncentroids, code_size, 8)
    index.nprobe = 5
    

    可以查看IndexIVFFlat那章设置ncentroids,code_size通常是24~264。和IndexPQ一样,d是m的倍数。

  • 相关阅读:
    leetcode108 Convert Sorted Array to Binary Search Tree
    leetcode98 Validate Binary Search Tree
    leetcode103 Binary Tree Zigzag Level Order Traversal
    leetcode116 Populating Next Right Pointers in Each Node
    Python全栈之路Day15
    Python全栈之路Day11
    集群监控
    Python全栈之路Day10
    自动部署反向代理、web、nfs
    5.Scss的插值
  • 原文地址:https://www.cnblogs.com/imagezy/p/8342940.html
Copyright © 2020-2023  润新知