圖像檢索中,對一幅圖像編碼后的向量的維度是很高。以VLAD為例,基於SIFT特征點,設視覺詞匯表的大小為256,那么一幅圖像編碼后的VLAD向量的長度為$128 \times 256 = 32768 $。通常要對編碼后的VLAD向量進行降維,降維后的向量長度應該根據圖像庫中圖像量的大小來,如果只是幾百張的小的圖像庫,那么可以降維到128甚至是64維,在這種情況下降維后的VLAD向量仍然有很好的區分度;但是如果圖片庫的數量是幾千,幾萬張,如果VLAD降維的維度太低,損失的信息過多,就不能有很好的區分度,維度過低檢索的精度就會低很多。為了保證檢索的精度,VLAD向量要有1024或者2048的維度。
以上數據是筆者經歷的項目的經驗值,並不一定適合所有的情況。
如果是在低維度的小數據集中,可以使用線性查找(Linear Search)的方法,但是在高緯度大數據集中,線性查找的效率很低,顯然是不可行的。如何的從大的高維數據集中找到與某個向量最相似的一個或多個向量,是圖像檢索中一個難點。
在這種高緯度大數據集中的檢索,通常需要使用最近鄰最相似查找(Approximate Nearest Neighbor,ANN)的方法。ANN的相似性檢索算法,大體可以分為三大類:
- 基於樹的方法,KD-樹為代表。對於低維度的數據,KD樹的查找性能還是比較高效的;但當空間維度較高時,該方法會退化為暴力枚舉,性能較差,這時一般會采用下面的哈希方法或者矢量量化方法。
- 哈希方法
- LSH Locality Sensitive Hashing 為代表,對於小數據集和中等數據集效果不錯
- 矢量量化
- vector quantization,在矢量量化編碼中,關鍵是碼本的建立和碼字搜索算法。比如常見的聚類算法,就是一種矢量量化方法。而在相似搜索中,向量量化方法又以PQ方法為代表
- 對於大規模數據集,矢量量化是個很好的選擇
LSH
LSH(Locality Sensitive Hashing)位置敏感哈希,局部敏感哈希
最近鄰最相似搜索算法的一種,有比較可靠的理論根據且在高維數據中表現比較好,很適合應用在圖像檢索中。
與一般的哈希算法不同的是其位置敏感性,也就是散列前類似的點(距離近的點),在散列后仍然能夠保證在一定程度的相似,且有一定的概率保證。
LSH和普通哈希的區別
基本思想
LSH不像樹形結構的方法可以得到精確的結果,LSH所得到的是一個近似的結果,因為在很多領域中並不需非常高的精確度。即使是近似解,但有時候這個近似程度幾乎和精准解一致。
LSH的主要思想是,高維空間的兩點若距離很近,那么設計一種哈希函數對這兩點進行哈希值計算,使得他們哈希值有很大的概率是一樣的。同時若兩點之間的距離較遠,他們哈希值相同的概率會很小。
LSH哈希函數要滿足的性質
一個哈希函數滿足以下性質時,被稱為\((R,cR,P_1,P_2)\)-sensive,對於高維空間的任意兩點\(x,y\)
- 如果\(d(x,y) \le R\),則\(h(x) = h(y)\)的概率不小於\(P_1\)
- 如果\(d(x,y) \ge cR\),則\(h(x) = h(y)\)的概率不大於\(P_2\)
其中\(d(x,y)\)是兩個點\(x,y\)之間的距離,\(h\)是哈希函數,\(h(x)\)和\(h(y)\)是對點\(x,y\)的哈希變換,並且需要滿足:
- \(c > 1\)
- \(P_1 > P_2\)
LSH的原理是挺簡單的,其核心有兩個:
- 兩個高維向量的相似性的度量
- \((R,cR,P_1,P_2)\)-sensive哈希函數的選擇
LSH的哈希函數的選擇取決於其選擇的相似性度量方法,當然並不是所有向量相似性度量的方法都能找到相應的LSH函數,比如LSH最初提出的時候時候基於歐式距離的度量方法就沒有找到合適的LSH函數。
Origin LSH
最初設計的LSH應該是想基於歐式距離(\(L_2\)),但是對於歐式距離當時沒有找到合適的LSH函數;但是在曼哈頓距離(\(L_1\))下找到了合適的LSH函數。所以,就有了一個假設,向量所在的原始空間中\(L_1\)和\(L_2\)度量的效果相差不大,也就是說用\(L_1\)來代替\(L_2\)。
所以就有兩個准則:
- 使用\(L_1\)也就是曼哈頓距離進行度量。 基於假設\(L_1\)和\(L_2\)的度量效果相差不大。
- 向量的各個分量,要被正整數化,方便進行01編碼。
為什么要進行01編碼呢,因為在\(L_1\)的度量下也不是很容易找到合適的LSH函數,而在Hamming距離下有合適的LSH函數。最初在提出LSH的時候,使用一種方法將向量從\(L_1\)准則下的歐幾里空間嵌入(Embedding)到Hamming空間。
Hamming距離下的LSH
Hamming距離指的是兩個相同長度的二進制數據中相同位置處比特位值不同的個數。 例如,8和5使用長度為4的二進制表示分別為: \(8=(1000),5 = (0101)\),那么8和5的Hamming距離就是:3。
假如有兩個二進制表示的向量\(x,y\),向量的每個分量的值不是0就是1,使用Hamming距離計算這兩個向量的距離。假設有一組哈希函數\(H\),其定義為:每一個哈希函數h隨機的選擇向量特定位置的bit值返回,\(H\)中包含了所有從\(\{0,1\}^d\)映射到\(\{0,1\}\)函數,其中\(h_i(x) = x_i\)。
從\(H\)中隨機的選擇哈希函數\(h_i\)應用到向量\(x\)上,則\(h_i(x) = x_i\),返回向量\(x\)特定位置的bit值。那么\(h(x) = h(y)\)的概率就為向量\(x,y\)中bit位相同的所占的比例,即有:
其中,\(d\)為向量二進制的長度。則對於任意的\(c>1\),都有\(P_1 > P_2\),滿足以上提到的LSH函數的條件。
假設兩個點\(x = (1000),y = (0101)\),則\(x,y\)的Hamming距離為3,則通過上述的哈希函數映射后具有相同哈希值的概率,$$P(h(x)=h(y)) = 1 - \frac{3}{4} = \frac{1}{4}$$
曼哈頓距離(\(L_1\))轉換為Hamming距離
Hamming距離只能應用於二進制表示的向量,這就有很大局限性。所以Origin LSH 就提出了一種方法稱為Embedding,將向量的表示從\(L_1\)准則下的歐幾里空間Embedding到Hamming空間,並且保證轉換前后兩個向量的距離是不變的。
Embedding算法:
- 找到數據集中所有向量的所有分量的最大值\(C\)。
- 對於向量\(x = (x_1,x_2,\cdots,x_n)\),\(n\)是向量的維度。將向量每個分量\(x_i\)轉換為長度為\(C\)的二進制序列,二進制序列為前\(x_i\)個1,剩余的為0。假設\(x_i = 5,C=10\),轉換后的二進制序列為\(1111100000\)。
- 這樣一個\(d\)維的向量就轉變為\(nC\)長度的二進制串。
Embedding操作是保持距離的,轉換后兩個向量的距離是不變的。轉變為Hamming距離后,就可以利用Hamming距離下的LSH函數了
LSH的哈希函數要滿足以下兩個條件,
- 如果\(d(x,y) \le R\),則\(h(x) = h(y)\)的概率不小於\(P_1\)
- 如果\(d(x,y) \ge cR\),則\(h(x) = h(y)\)的概率不大於\(P_2\)
設向量的二進制表示的長度為\(nC\),如果向量\(x,y\)的Hamming距離為\(d\),則通過上面哈希函數的變換后,
則有:
- 如果\(d(x,y) \le R\),則\(h(x) = h(y)\)的概率不小於\(P_1\),\(P_1 = \frac{nC-R}{nC} = 1 - \frac{R}{nC}\)
- 如果\(d(x,y) \ge cR\),則\(h(x) = h(y)\)的概率不大於\(P_2\),\(P_2 = \frac{nC-cR}{nC} = 1 - \frac{cR}{nC}\)
向量的Hamming距離和其映射后相等的概率之間的關系如下圖:
當兩個向量的Hamming距離為0,映射后其相等的概率為1;兩個向量的二進制完全不同,Hamming距離為\(nC\)則其映射后相同的概率為0。
LSH參數
再來回顧下LSH的思想:在原空間中很近(相似)的兩個點,經過LSH哈希函數的映射后,有很大概率它們的哈希是一樣的;而兩個離的很遠(不相似)的兩個點,映射后,它們的哈希值相等的概率很小。
從上面這句話可以看出LSH需要的四個參數:
- 原空間中兩向量的距離\(R\)
在原空間中,如果兩個向量的距離小於\(R\),表示這兩個向量相似,經過映射后,其哈希值有有很大的概率是相同的。 - 相似的向量映射后哈希值相等的概率\(P_1\)
- 常數\(c\)
在原空間中,如果兩個向量的距離大於\(cR\),表示這兩個向量不相似,經過映射后,其哈希值相等的概率很小 - 不相似的向量映射后哈希值的概率相等的概率\(P_2\)
也就是說,對於任意向量\(x,y\),如果在原空間中其距離\(d(x,y) \le R\),則認為其是相似的。經過LSH哈希函數映射后,其哈希值相等的概率很大(\(P_1\));而對於在原空間中距離\(d(x,y) \ge cR\),則認為其是不相似的,經過LSH哈希函數映射后u,其哈希值相等的概率很小(\(P_2\))。
對於Origin LSH 已Hamming距離來度量向量的相似性來說,概率
\(P_1,P_2\)可以通過上述公式求得,也就是說,只需要指定兩個參數
- 向量相似的距離\(R\)
- 常數\(c(c>1)\),向量大於距離\(cR\)則表示不相似
概率增大
LSH的核心思想是,通過哈希變換后,變換前相似的向量在變換后有很大的概率(\(P_1\))哈希值是相同的;不相似的呢,其哈希值只有很小的概率(\(P_2\))是相同的。這樣,兩個概率\(P_1,P_2\)就是影響LSH檢索的關鍵。理想的情況下,是相似的向量,其哈希值相同的概率是\(P_1=1\);不相似的向量,其哈希值相同的概率\(P_2 = 0\)。 理想情況畢竟是理想嘛,面對實際問題還是要現實一點的,對於\(P_1,P_2\)的關系:\(P_1\)盡可能的大,\(P_2\)較小,\(P_1,P_2\)有足夠大的間隔。
通過上面的分析知道,\(P_1,P_2\)可以通過設置較大的相似距離\(R\)和一個小的常數\(c\),來保證\(P_1,P_2\)有足夠大的間隔。在極端情況下,可以設置相似距離\(R\)等於二進制串的長度\(nC\),這樣只有兩個向量二進制串是完全相同情況下,\(P_1=1\)。 但這會導致相似檢索的精度變的不那么可靠,對數據的噪聲比較敏感。
所以對於指定了相似距離\(R\)以及常數\(c\)來說,可能其\(P_1,P_2\)之間的間隔不是足夠的大,可以使用增加哈希鍵長度\(K\)以及哈希表的個數\(L\)來增大\(P_1,P_2\)之間的差。
增加哈希表個數\(L\)和哈希鍵長\(K\)實際上是不同哈希函數的組合。
- 增加哈希鍵長\(K\)
設\(h_i\)是哈希函數簇\(H\)中的任意函數,對於任意向量\(p,q\)滿足$$P(h_i(p) = h_i(q)) = P_1$$
從\(H\)中隨機的挑選\(K\)個哈希函數將向量映射為\(K\)長度的串,\(g(p) = [h_1(p),h_2(p),\cdots,h_k(p)]\) 則有:
由於\(0 < P_1 < 1\),則\(P_1^K < P_1\),也就是說縮小了概率。
- 增加哈希表\(L\)
設現在有\(L\)個哈希表(也就是\(L\)個哈希函數簇\(H\)),每個哈希表都使用上面的方法產生一個組合的哈希函數\(g\),
這樣可以得到\(L\)個哈希函數\(g_1,g_2,\cdots,g_l\),將這幾個組合的哈希函數再組合到一起得到哈希函數\(G\)。
由於使用一個哈希表找到最近鄰的概率為\(P_1^K\),招不到最相似的概率是\(1 - P_1^K\)。那么使用\(L\)個哈希表找到最相似的概率
上面公式給出了,使用\(L\)個哈希表,\(K\)個哈希函數的情況下,查找到最近鄰的概率\(P = 1 - (1-P_1^k)^l\),下表給出了\(K = 4,L = 4\)的情況下,查找到最相似向量的概率
\(P_1\) | \(1 - (1-P_1^4)^4\) |
---|---|
0.9 | 0.9860 |
0.8 | 0.8785 |
0.7 | 0.6666 |
0.5 | 0.2275 |
0.4 | 0.0985 |
0.3 | 0.0320 |
0.2 | 0.0064 |
LSH 編碼實例
下面看一個實例,假設有數據集合中有6個點:
A=(1,1) B=(2,1) C=(1,2)
D=(2,2) E=(4,2) F=(4,3)
首先進行Embedding操作點表示為二進制串,上述坐標的最大值為4,所以\(C=4\),維度為2,則\(n = 2\),所以二進制串的長度為8.
v(A)=10001000
v(B)=11001000
v(C)=10001100
v(D)=11001100
v(E)=11111100
v(F)=11111110
采用\(K=2,L=3\)的哈希函數組合,\(G = [g_1,g_2,g_3]\),其中\(g_i = [h_1,h_2]\)。
假設隨機選擇的哈希函數組合如下:
- \(g_1\)分別取第2位,第4位,也就是\(h_1(p) = p_2,h_2(p) = p_4\)
- \(g_2\)分別取第1位,第6位,也就是\(h_1(p) = p_1,h_2(p) = p_6\)
- \(g_3\)分別取第3位,第8位,也就是\(h_1(p) = p_3,h_2(p) = p_8\)
利用上面的哈希函數將6個點映射到三個哈希表中,結果如下:
設查詢向量\(q = (4,4) = (11111111)\),可以計算出
將上面3個哈希表中映射到\([11]\)號的向量取出來為\((C,D,E,F)\),接下來將這四個向量分別與\(q\)計算距離,距離最近的向量,即為最相似的向量,也就是向量\(F = (4,3)\)。
上述例子引用自局部敏感哈希深度解析
LSH的檢索過程
從上面的例子中可以總結處LSH檢索過程。
- 離線建立索引
- 選擇滿足\((R,cR,P_1,P_2)\)-sensive的哈希函數
- 根據對查找結果的准確率(即相鄰的數據被查找到的概率)確定哈希表的個數\(L\),每個table內的hash functions的個數,也就哈希的鍵長\(K\),以及跟LSH hash function自身有關的參數
- 利用上面的哈希函數組,將集合中的所有數據映射到一個或多個哈希表中,完成索引的建立。
- 在線的查找
- 將查詢向量\(q\)通過哈希函數映射,得到相應哈希表中的編號
- 將所有哈希表中相應的編號的向量取出來,為了保證查找速度,通常只需要取出來前\(2L\)個。
- 對這\(2L\)個向量進行線性查找,返回與查詢向量最相似的向量。
總結
在做圖像檢索時,搜索資料發現使用KD樹做索引效果不是很好,由於使用的是OpenCV的庫,就像改為使用LSH的索引,但是OpenCV集成的LSH只支持整型的,而且對其中一些參數的設置不是很明白,搜集了些資料,形成了該篇文章。
搜集資料的過程才發現哈希函數的應用之廣泛,就LSH這個點來說,搜集資料形成的本篇文章也也只是冰山一角,奈何沒有太多的精力,目前僅止於了解。
相似性度量及LSH哈希函數
可以使用不同的方法來度量兩個點的相似性,針對不同的度量方法,在進行局部哈希時使用的哈希函數也是不同的。
兩個向量的相似性度量的方式很多,這里僅列舉幾個在計算機視覺中常用的幾個度量方法,當然並不是所有的度量方式都能夠找到相應的LSH哈希函數。例如,在LSH最初提出的時候,就沒有找到基於歐式距離的LSH函數。
Hamming距離的LSH哈希函數
這也是Origin LSH,本文描述使用的距離度量。
在對圖像進行匹配時,通常是將圖像的描述子與數據中的圖像描述子進行匹配實現的。在實時應用中,通常是使用二進制描述子,比如BIREF、BRISK、ORB等。對於二進制描述子使用的是Hamming距離。
對於二進制描述子,哈希函數就是直接選擇描述子的某一個比特位,通過若干個哈希函數選擇出來的位的級聯,就形成了一個哈希鍵了。通過對這個哈希鍵對數據庫中的描述子進行索引,即形成了一個哈希表,選擇若干個哈希表來增大找到近似最近鄰的概率。
Hamming距離指的是兩個具有相同長度的向量中對應位置處值不同的次數。
Hamming距離的LSH哈希上面已經有描述,這里不再重復。
向量的夾角余弦的LSH哈希函數
用兩個向量的夾角來衡量兩個向量是不是相似,向量的夾角越小,表示它們越相似。
向量夾角的計算公式
其中,\(\Vert \cdot \Vert\)表示向量的\(L_2-norm\).
例如,兩個向量\(x = (1,2,-1),y = (2,1,1)\),則有
\(\cos(\theta)\)的取值范圍是\([0,\pi]\),僅在兩個相同的方向相同時,其夾角的余弦值為0;當兩個向量的方向相反時,其 夾角的余弦值為\(\pi\)。
適應向量的夾角余弦度量,對應的LSH hash function為:\(H(V) = sign(V·R)\),\(R\)是一個隨機向量。\(V·R\)可以看做是將\(V\)向\(R\)上進行投影操作,其是\((d_1,d_2,(180-d_1)180,(180-d_2)/180)\)-sensitive的。
歐氏距離的LSH哈希
兩個向量相似性度量,歐氏距離應該是比較常用的方法,但是在LSH才提出的時候,在歐氏距離下並沒有找到合適的LSH函數。
關於更多E2LSH的信息可參考http://www.mit.edu/~andoni/LSH/