faiss的基本使用方法

官方的使用demo中,我跑了下demo結果一樣,但是這個表示的結果是什麼意思呢?

faiss.IndexFlatL2(d)

官方解釋是暴力搜索L2距離方法,add後即建立索引了,無需index.train(xb),我對比了,有沒有這一步的結果是一樣的

得到的D是距離,I是索引,

>>> k=4
>>> D,I=index.search(xb[:5],k)
>>> I
array([[  0, 393, 363,  78],
       [  1, 555, 277, 364],
       [  2, 304, 101,  13],
       [  3, 173,  18, 182],
       [  4, 288, 370, 531]])
>>> D
array([[0.       , 7.1751733, 7.207629 , 7.2511625],
       [0.       , 6.3235645, 6.684581 , 6.7999454],
       [0.       , 5.7964087, 6.391736 , 7.2815123],
       [0.       , 7.2779055, 7.5279865, 7.6628466],
       [0.       , 6.7638035, 7.2951202, 7.3688145]], dtype=float32)

這是合理性檢測,因爲

xb[:, 0] += np.arange(nb) / 1000.

這一步將每條數據的第一個元素全都加上了該元素的index,由於產生的數據是np.random.random即[0.0, 1.0)

那麼在top1必然是該條數據本身,而距離本身就是倒排,從小到大的距離,也就是相似度從大到小。

下面看另外一個函數faiss.IndexFlatIP,餘弦相似度還是餘弦距離啊??這個sklearn可以作爲對比。

【餘弦距離=1-餘弦相似度,餘弦距離越小越好,此時餘弦相似度越大】

1-創建index和加載數據集時間用的短,query時用的時間長,在沒有用快速方法時,在1千萬數據集中查1萬個top4需要100s,這個時間太長了。d=64

2-驗證中發現faiss.IndexFlatL2計算的是歐式距離的平方,將官方例子中得到的I挨個驗證如下:k=6

L2 distances
 [[0.        7.1751733 7.207629  7.2511625 7.321895  7.351989 ]
 [0.        6.3235645 6.684581  6.7999454 6.8844795 6.919898 ]
 [0.        5.7964087 6.391736  7.2815123 7.640502  7.7231803]
 [0.        7.2779055 7.5279865 7.6628466 7.7859573 7.790914 ]
 [0.        6.7638035 7.2951202 7.3688145 7.3900466 7.46482  ]]
index
 [[  0 393 363  78 924 364]
 [  1 555 277 364 617 175]
 [  2 304 101  13 801 134]
 [  3 173  18 182 484  64]
 [  4 288 370 531 178 381]]
0.0,7.175172963007071,7.207629517529313,7.251163094237256,7.32189456020302,7.351988795840555,
0.0,6.323564681684957,6.684580949409394,6.7999456742750795,6.884479284324755,6.919898182110273,
0.0,5.796407676635283,6.391735719267899,7.281511928833652,7.640502286348237,7.723179155793559,
0.0,7.277905725671246,7.527987963394992,7.662846322185942,7.785958432863538,7.790914131558168,
0.0,6.763803673639131,7.295120098456721,7.368814161903231,7.3900459631258855,7.464819925508493,

3-faiss.IndexFlatIP求出來的D根本不是餘弦方面的東西,既不是餘弦距離也不是餘弦相似度,你看看數值就知道了,完全超出了這倆數的最大範圍2。(只是將上面的函數替換【L2——>IP】)

cosin distances ????
 [[1937.2388  1936.8904  1936.407   1936.4034  1936.3837  1936.2039 ]
 [3854.9084  3853.9912  3853.5012  3853.4224  3853.3848  3853.3577 ]
 [ 775.8727   775.72815  775.4991   775.3009   775.2481   775.1989 ]
 [1764.4421  1764.3489  1764.1312  1764.116   1764.0082  1763.9166 ]
 [1894.5415  1894.508   1893.7448  1893.7166  1893.6948  1893.63   ]]
index
 [[9996145 9999103 9998705 9999520 9996659 9999163]
 [9999930 9999529 9999160 9999743 9996855 9999219]
 [9986256 9990562 9997819 9999103 9990206 9993650]
 [9994808 9998483 9999930 9999520 9999895 9998792]
 [9999930 9994808 9995033 9999520 9996145 9996287]]

這是什麼鬼??完全與L2得到的結果不同,難道說IP需要分nlist或者nprobe??官方加速例子中有train

所以我覺得這並不是餘弦方面的東西,等待官方回覆吧

4-不同的結果,使用加速後得到的結果不同?這是怎麼回事啊?

我猜想官方肯定會說需要設置一些參數,有些確實不同,

官方回覆說,只有第一種方法得到的是準確的方法,其他方法均是近似方法。但第一種方法慢,想快又準,你在開玩笑,肯定是折中問題,trade-off,速度越快,Recall越小,這是顯然的。

5-計算時間的比較,仍舊從1千萬查詢1萬,但用top100,我估計需要設置的參數可能有很大影響

速度快慢可能和計算Recall有關

一是創建index時間,二是查詢時間,仍舊用4中的可能不適合的腳本對比,後面再用1G的腳本

訓練數據後創建index,再查找,所用的查找時間短,第一種方法是暴力搜索,沒有訓練數據,直接查找肯定慢。

但如果訓練時間長也不符合線上實時應用。第2/3種方法均是訓練時間長(10分鐘內),這也是不行的

目前發現第4/6種速度較快[最後一個創建index2.56s,查詢不到1s-0.8s,多GPU就是厲害],

第5種結果有點奇怪。index出現-1的情況,如下所示:查詢時間雖然短,0.01s,但是結果有點可怕

 [ 767 1228  230 1196  706 1365  256 1488  562  940  718  346  658   43
  1431 1232  761  837 1108  593 1674  633 1363  152  477 1139  171 1198
   938  672  190 1328  472  525  885  855  977  704  694   86 1150  321
   486 1128  659 1019  881  354  850  742  412 1203  957 1179  496  905
   229 1119  464 1798 1118  402 1186  360 1200  629  985 1519 1483   -1
    -1   -1   -1   -1   -1   -1   -1   -1   -1   -1   -1   -1   -1   -1
    -1   -1   -1   -1   -1   -1   -1   -1   -1   -1   -1   -1   -1   -1
    -1   -1]]

官方說Consider 增加 nprobe (or 減少 nlist).但是這樣真的好嗎?我還要嘗試??是不是其他幾種方法也可能出現這個情況啊

這次只是偶然沒有出現,這就蛋疼了啊,有沒有自適應或者一勞永逸的方法??按照這個數據量的話我推薦第6種,速度最快,且又相對正確。

【這個方法如果沒有這種情況的話,速度是最快的,0.05s左右,創建index時間8s】

6-1G數據量的腳本,待後續吧

 

7-如果創建和查詢時間都是10ms左右則無需保存index,然而大多數情況下不是的,而且保存的話不需要引入數據重新訓練了

因而這裏介紹怎麼保存index,如何加載index,可能會與nmslib比較像

但是我大意了,並不是這樣的啊,見我的issue,待續

 

For Video Recommendation in Deep learning QQ Group 277356808

For Speech, Image, Video in deep learning QQ Group 868373192

I'm here waiting for you.
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章