Faiss的第二个示例 IVFFlat

Faiss的第二个示例 IVFFlat

flyfish

import mkl
mkl.get_max_threads()
import numpy as np

d = 64                           # dimension
nb = 100000                      # database size
nq = 10000                       # nb of queries
np.random.seed(1234)             # make reproducible
xb = np.random.random((nb, d)).astype('float32')
xb[:, 0] += np.arange(nb) / 1000.
xq = np.random.random((nq, d)).astype('float32')
xq[:, 0] += np.arange(nq) / 1000.

import faiss

nlist = 100
k = 4
quantizer = faiss.IndexFlatL2(d)  # the other index
index = faiss.IndexIVFFlat(quantizer, d, nlist, faiss.METRIC_L2)
# here we specify METRIC_L2, by default it performs inner-product search

assert not index.is_trained
index.train(xb)
assert index.is_trained

index.add(xb)                  # add may be a bit slower as well
D, I = index.search(xq, k)     # actual search
print(I[-5:])                  # neighbors of the 5 last queries
index.nprobe = 10              # default nprobe is 1, try a few more
D, I = index.search(xq, k)
print(I[-5:])                  # neighbors of the 5 last queries

输出结果是

[[ 9900  9309  9810 10048]
 [11055 10895 10812 11321]
 [11353 10164  9787 10719]
 [10571 10664 10632 10203]
 [ 9628  9554  9582 10304]]
[[ 9900 10500  9309  9831]
 [11055 10895 10812 11321]
 [11353 11103 10164  9787]
 [10571 10664 10632  9638]
 [ 9628  9554 10036  9582]]

为了加快搜索速度,可以将数据集分段。我们在d维空间中定义Voronoi单元,并且每个数据库向量都落入其中一个单元中。在搜索时,仅包含在查询x所在的单元格中的数据库向量y,并且将几个相邻的数据库向量与查询向量进行比较。

这是通过IndexIVFFlat索引完成的。这种类型的索引需要训练阶段,该训练阶段可以对与数据库向量具有相同分布的任何向量集合执行。在本例中,我们只使用数据库向量本身。

IndexIVFFlat还需要另一个索引,即量化器,它将向量分配给Voronoi单元格。每个单元由一个质心定义,找到一个向量所在的Voronoi单元就是在质心集合中找到该向量的最近邻居。这是另一个索引的任务,通常是IndexFlatL2。

搜索方法有两个参数:nlist和nProbe,nList是单元的数量,nProbe是为执行搜索而访问的单元的数量(在nList之外)。由于量化,搜索时间大致随着探针数量加上某个常数而线性增加。

IndexIVFFlat 的Method是 Inverted file with exact post-verification 。它的index_factory是 “IVFx,Flat”
带有倒排索引的文件我们称为倒排索引文件,简称倒排文件(inverted file)。
倒排索引的解释,引用知乎: 英文原名Inverted index,大概因为 Invert 有颠倒的意思,就被翻译成了倒排。但是倒排这个名称很容易让人理解为从A-Z颠倒成Z-A。个人认为翻译成转置索引可能比较合适。一个未经处理的数据库中,一般是以文档ID作为索引,以文档内容作为记录。而Inverted index 指的是将单词或记录作为索引,将文档ID作为记录,这样便可以方便地通过单词或记录查找到其所在的文档。
假设我们有两个文档,每个文档的 content 域包含如下内容:

Doc_1:The quick brown fox jumped over the lazy dog
Doc_2:Quick brown foxes leap over lazy dogs in summer

为了创建倒排索引,我们首先将每个文档的 content 域拆分成单独的 词(我们称它为 词条 或 tokens ),创建一个包含所有不重复词条的排序列表,然后列出每个词条出现在哪个文档。结果如下所示:
Faiss的第二个示例 IVFFlat_第1张图片

如果想了解Voronoi这个单词是怎么回事,请看论文
《Product Quantization for Nearest Neighbor Search》

Voronoi Cell的一种可视化
Faiss的第二个示例 IVFFlat_第2张图片

A single Voronoi cell (in red) with its neighboring sites (in grey) and corresponding Delaunay edges (in blue). A straight path through the cell is shown (in green) with its intersection points with the cell boundary at entry and exit.
Source publication
单个Voronoi Cell(红色)及其相邻位置(灰色)和相应的Delaunay边缘(蓝色)。 显示了一条穿过该cell的直线路径(绿色),该路径的交点与入口和出口处的cell边界相交。

你可能感兴趣的:(深度学习)