faiss處理大規模d維向量近鄰檢索的問題,faiss中所有向量以行矩陣的形式儲存和使用,例項中我們用xb表示所有待索引的向量集合 ,xq表示查詢向量集合,nb和nq分別表示xb、xq集合中向量數量。
構建待檢索向量和查詢向量
import numpy as np
d = 64
# 向量維度
nb = 100000
# 待索引向量size
nq = 10000
# 查詢向量size
np.random.seed(1234)
# 隨機種子確定
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.
建立索引並新增向量
faiss通過index物件進行向量的封裝與預處理,faiss提供了很多種索引型別,我們首先test暴力搜尋精準l2距離搜尋,對應的索引物件為indexflatl2。
所有向量在建立前需要明確向量的維度d,大多數的索引還需要訓練階段來分析向量的分布。但是,對於l2暴力搜尋來說沒有訓練的必要。
index物件訓練好之後,對於index有兩個操作供呼叫,分別為add和search。add方法用於向index中新增xb向量,search方法用於在add向量後的索引中檢索xq的若干近鄰。index還有兩個狀態變數is_trained(bool型別,用於指示index是否已被訓練)和ntotal(指示索引的數量)。此外,index還有ids新增的方法。
import faiss
index = faiss.indexflatl2(d)
# 建立索引
print(index.is_trained)
# 輸出true
index.add(xb)
# 索引中新增向量
print(index.ntotal)
# 輸出100000
近鄰搜尋
通過index檢索xq中的資料,faiss支援批量資料檢索,通過search方法返回的檢索結果包括兩個矩陣,分別為近鄰向量的索引序號和xq中元素與近鄰的距離大小。
k = 4
# 返回每個查詢向量的近鄰個數
d, i = index.search(xb[:5], k)
# 檢索check
print(i)
print(d)
d, i = index.search(xq, k)
#xq檢索結果
print(i[:5])
# 前五個檢索結果展示
print(i[-5:])
# 最後五個檢索結果展示
檢索結果
check檢索結果
[[ 0 393 363 78]
[ 1 555 277 364]
[ 2 304 101 13]
[ 3 173 18 182]
[ 4 288 370 531]]
[[ 0. 7.17517328 7.2076292 7.25116253]
[ 0. 6.32356453 6.6845808 6.79994535]
[ 0. 5.79640865 6.39173603 7.28151226]
[ 0. 7.27790546 7.52798653 7.66284657]
[ 0. 6.76380348 7.29512024 7.36881447]]
xq檢索結果
[[ 381 207 210 477]
[ 526 911 142 72]
[ 838 527 1290 425]
[ 196 184 164 359]
[ 526 377 120 425]]
[[ 9900 10500 9309 9831]
[11055 10895 10812 11321]
[11353 11103 10164 9787]
[10571 10664 10632 9638]
[ 9628 9554 10036 9582]]
上面所示,indexflatl2是暴力檢索的索引,為了加速檢索speed,可以使用faiss的indexivfflat索引物件。indexivfflat的使用需要進行訓練階段,並需要指定其他索引作為量化器,與檢索相關的引數
為nlist和nprobe。indexivfflat索引先利用粗量化器將檢索向量劃分到voronoi單元中並建立倒排索引,檢索階段將根據輸入向量和probe引數定位到對應的voronoi cell中進行近鄰搜素。
indexivfflat檢索
nlist = 100
k = 4
quantizer = faiss.indexflatl2(d)
# 量化器索引
index = faiss.indexivfflat(quantizer, d, nlist, faiss.metric_l2)
# 指定用l2距離進行搜尋,若不指定預設為內積
assert not index.is_trained
index.train(xb)
# 索引訓練
assert index.is_trained
index.add(xb)
# 向量新增
d, i = index.search(xq, k)
# 檢索
print(i[-5:])
# 最後五個檢索結果
index.nprobe = 10
# 多探針檢索
d, i = index.search(xq, k)
print(i[-5:])
#最後五個檢索結果
檢索結果顯示
1probe
[[ 9900 10500 9831 10808]
[11055 10812 11321 10260]
[11353 10164 10719 11013]
[10571 10203 10793 10952]
[ 9582 10304 9622 9229]]
10probe
[[ 9900 10500 9309 9831]
[11055 10895 10812 11321]
[11353 11103 10164 9787]
[10571 10664 10632 9638]
[ 9628 9554 10036 9582]]
讀者可自行觀察測試各引數對檢索結果的影響。
本篇**可以在faiss中的 tutorial/ 目錄下查詢。
reference
FA模組資料流
資產主表 select from fa additions v fa where fa.asset id 10014 資產賬簿 select from fa books v where date ineffective is null and book type code mewbg fa new ...
linux合併fa檔案 linux 混雜裝置模型
在linux系統中,存在一類字元裝置,他們共享乙個主裝置號 10 但此裝置號不同,我們稱這類裝置為混雜裝置 miscdeivce 檢視 proc device中可以看到乙個名為misc的主裝置號為10.所有的混雜裝置形成乙個鍊錶,對裝置訪問時核心根據次裝置號找到對應的miscdevice裝置。lin...
方法失效 失效分析FA方法介紹
失效分析 fa 是一門發展中的新興學科,近年開始從軍工向普通企業普及。它一般根據失效模式和現象,通過分析和驗證,模擬重現失效的現象,找出失效的原因,挖掘出失效的機理的活動。在提高產品質量,技術開發 改進,產品修復及仲裁失效事故等方面具有很強的實際意義。其方法分為有損分析,無損分析,物理分析,化學分析...