数据准备
import numpy as np
d = 512 #维数
n_data = 2000
np.random.seed(0)
data = []
mu = 3
sigma = 0.1
for i in range(n_data):
data.append(np.random.normal(mu, sigma, d))
data = np.array(data).astype('float32')
#query
query = []
n_query = 10
np.random.seed(12)
query = []
for i in range(n_query):
query.append(np.random.normal(mu, sigma, d))
query = np.array(query).astype('float32')
#导入faiss
import sys
sys.path.append('/home/maliqi/faiss/python/')
import faiss
乘积量化作为cell-probe方法的粗量化器
乘积量化也可以作为粗量化器。其中有两个参数,聚类中心数c,维度划分m,这样每个划分都有c个倒排表,一种有c^m个倒排表。实际使用中,一般直接让m=2。
MultiIndexQuantizer也经常与IndexFlat对比,以便选取合适的参数。
nbits_mi = 5 # c
M_mi = 2 # m
coarse_quantizer_mi = faiss.MultiIndexQuantizer(d, M_mi, nbits_mi) #不需要add任何数据
ncentroids_mi = 2 ** (M_mi * nbits_mi)
index = faiss.IndexIVFFlat(coarse_quantizer_mi, d, ncentroids_mi)
index.quantizer_trains_alone = True #表示这是粗量化器的flag
index.train(data)
index.add(data)
index.nprobe = 50
dis, ind = index.search(query, 10)
print(ind)
结果为:
[[1269 1028 1895 120 1267 178 178 1061 1972 1029]
[1398 289 70 1023 1177 940 969 969 1568 700]
[ 345 389 1904 1992 1992 1612 1623 1632 539 366]
[ 112 1412 1624 879 394 1506 1398 1326 91 440]
[ 94 1459 1517 1723 1255 66 238 238 1755 472]
[ 574 574 1523 91 456 296 444 1384 103 1230]
[1391 876 91 1914 78 969 732 999 277 1158]
[1662 1654 722 1070 121 1496 631 631 1442 1738]
[ 154 99 31 1237 289 661 426 1008 1727 744]
[ 375 1826 610 750 750 1430 459 1339 471 441]]
Pre-filtering PQ codes with polysemous codes
todo