zoukankan      html  css  js  c++  java
  • Faiss教程:基础

    Faiss对一些基础算法提供了非常高效的实现:k-means、PCA、PQ编解码。

    聚类

    假设2维tensor x:

    ncentroids = 1024
    niter = 20
    verbose = True
    d = x.shape[1]
    kmeans = faiss.Kmeans(d, ncentroids, niter, verbose)
    kmeans.train(x)
    

    中心点放在kmeans.centroids中,目标函数的值放在kmeans.obj中。返回查询数据最近的中心点:

    D, I = kmeans.index.search(x, 1)
    

    返回某个测试数据集中离各个中心点最近的15个点。

    index = faiss.IndexFlatL2 (d)
    index.add (x)
    D, I = index.search (kmeans.centroids, 15)
    

    通过调整索引可以放到GPU上运行。

    PCA降维

    从40维降低到10维度

    # random training data 
    mt = np.random.rand(1000, 40).astype('float32')
    mat = faiss.PCAMatrix (40, 10)
    mat.train(mt)
    assert mat.is_trained
    tr = mat.apply_py(mt)
    # print this to show that the magnitude of tr's columns is decreasing
    print (tr ** 2).sum(0)
    

    ProductQuantizer(PQ)

    d = 32  # data dimension
    cs = 4  # code size (bytes)
    
    # train set 
    nt = 10000
    xt = np.random.rand(nt, d).astype('float32')
    
    # dataset to encode (could be same as train)
    n = 20000
    x = np.random.rand(n, d).astype('float32')
    
    pq = faiss.ProductQuantizer(d, cs, 8)
    pq.train(xt)
    
    # encode 
    codes = pq.compute_codes(x)
    
    # decode
    x2 = pq.decode(codes)
    
    # compute reconstruction error
    avg_relative_error = ((x - x2)**2).sum() / (x ** 2).sum()
    

    标量量化器(每一维度量化)

    d = 32  # data dimension
    
    # train set 
    nt = 10000
    xt = np.random.rand(nt, d).astype('float32')
    
    # dataset to encode (could be same as train)
    n = 20000
    x = np.random.rand(n, d).astype('float32')
    
    # QT_8bit allocates 8 bits per dimension (QT_4bit also works)
    sq = faiss.ScalarQuantizer(d, faiss.ScalarQuantizer.QT_8bit)
    sq.train(xt)
    
    # encode 
    codes = sq.compute_codes(x)
    
    # decode
    x2 = sq.decode(codes)
    
    # compute reconstruction error
    avg_relative_error = ((x - x2)**2).sum() / (x ** 2).sum()
    

    选择索引的策略

    推荐使用index_factory,通过参数创建索引。

    • Flat
      提供数据集的基准结果,不压缩向量,也不支持添加id;如果需要 add_with_ids,使用“IDMap,Flat”参数。
      无需训练,支持GPU.

    Faiss的索引都是放在RAM中的,所以也就要考虑到内存的占用。

    • HNSWx
      足够的内存,小的数据集。每个向量的links数目x范围[4,64],通过efSearch参数折中速度和精度,每个向量的内存占用为d4+x2*4个字节。
      不支持add_with_ids(如需要添加IDMap),无需训练,不支持从索引中移除向量,不支持GPU

    • xxx,Flat
      xxx表示提前为数据做了聚类,如IVFFlat,通过nprobe这种速度和精度,支持GPU(聚类方法也支持的情况下)。

    • PCARx,...,SQ8
      存储整改向量占用资源太多,可以PCA降到x维度;SQ每项用一个字节表示。这样每个向量只占用x个字节的存储空间。不支持GPU。

    • OPQx_y,...,PQx
      PQx中x是字节数,通常<=64,如果更大采用SQ更为高效。OPQ是对数据做了线性变换更利于数据压缩,y表示:x的倍数、y<=d且y<4*x(推荐)。x表示OPQ中的分割参数,y才是最终切分结果。支持GPU。

    从数据集大小的角度(数据量、训练数据大小):

    • 少于1百万,使用...,IVFx,...
      数据集大小为N,x为[4sqrt(N),16sqrt(N)]。使用K-menas进行聚类,我们需要[30x,256x]个向量进行训练(当然越多越好)。支持GPU。

    • 1百万 < N < 1千万,使用...,IMI2x10,...
      IMI在训练数据集中通过kmeans得到210个中心点。但它是对向量的前后两半分别进行的聚类,也就是得到的2102=220个中心描述。我们需要64*2^10个训练样本。不支持GPU。

    • 1千万 < N < 1个亿,使用...,IMI2x12,...
      同上,只是增加了聚类数。

    • 1亿 < N < 10亿,使用...,IMI2x14,...
      同上。

  • 相关阅读:
    mysql 数据列按照逗号转成行
    powder designer 转数据库
    oracle 写入txt
    ORACLE 11g dblink 配置升级
    oracle 11g dblink配置
    spring ,mybatis多数据源
    基于shamir门限的秘密分存
    SM4加解密
    PHP对数据库的简单操作
    php实现计算器
  • 原文地址:https://www.cnblogs.com/houkai/p/9316136.html
Copyright © 2011-2022 走看看