乘積量化學習和實戰總結

2021-08-21 05:51:07 字數 2157 閱讀 5513

一、為什麼要用乘積量化

乘積量化就是一種編碼方法。當影象資料庫過於龐大時,直接儲存所有的資料並且做相似性度量檢索是不現實的。為了能夠減少儲存資源的開銷,並且提高檢索的效率,必須對原始資料做一些**操作。這其中包括提取影象的特徵向量和對提取出的特徵向量進行編碼。

因為我們可能並不需要影象中的所有資訊就可以判斷它是否是我們的目標影象。比如,我們想要知道一副圖中是否有貓,我們不用關心這只貓的顏色、姿態、位置等資訊,我們只需要在圖中找到貓的特徵就可以證明貓的存在。而這些人類視覺的特徵轉換成機器語言就是特徵向量。提取影象中的特徵向量有很多成熟的演算法,如sift、surf、orb、cnn的feature-map等。有很多現成的影象檢索演算法都是基於sift,所以博主建議如果有時間可以認真學習一下並且親自動手實現,而不只是呼叫現成的工具。傳統的影象檢索方法,如vlad、bof、fv等是針對小資料集的,所以它們基本上沒有針對大資料集的編碼操作,而為了能夠實現海量資料的檢索工作,避免列舉計算,乘積量化(product quantization)是乙個很理想的方法。雜湊演算法也是乙個很不錯的演算法,但是空間複雜度過高。

考慮乙個場景,從100萬張影象中提取出了20億的sift描述子用來建資料庫。如果沒用對這些資料進行編碼操作,首先這些向量的儲存就是乙個大問題,雖然已經比直接儲存影象小了很多,但資料量仍然很龐大,之後是查詢一條sift向量需要計算20億次!!!!!!這是無法用於實際生產的。乘積量化兼顧空間複雜度和時間複雜度,在兩者之間取得了很好的平衡,既可以保證不用儲存海量的資料,又保證了檢索的速度。

二、乘積量化原理及演算法步驟

考慮一種場景,用一條b=64 bit的資料表徵一條128維的sift描述子。

傳統量化演算法:

(1)在training-data上學習出codebook;

(2)assign 每一條sift到與它最相似的codeword;

其中,第(1)步是在訓練資料集影象提取的sift描述子上做k-means,codebook的大小是k*128。這個k值的選取很關鍵,參考**資料k=256,並且k和b是有關係的

b=log2k
b是以2為底,k的對數。這種量化方法的缺點是顯而易見的,當b=64 bit 時,k=2^64,這是乙個非常大的數字,幾乎是不可能跑的出來的。

乘積量化的思想是化整為零。

k=(k*)^m
我們不能直接做2^64的k-means,但是我們可以做k*=256的k-means,只需要把原始資料進行劃分。

d*=d/m
當d=128時,m=8,d*=16,這些資料**於**,是經過大量資料驗證的可用資料。

也就是說我們64bit 的b表示成了8個8bit的b的串聯,即b=b1*b2....*bm,也即是乘積量化。

我們只要分別對d的8個小塊做k*=256的k-means,然後把它們串聯起來,就得到了我們想要的b。

這只是解決了編碼的問題,但是沒有解決列舉檢索的問題。為了解決這個問題,**提出了invert-file 這種結構。既是在做乘積量化之前做乙個粗量化。即先對所有的sift做乙個劃分,依然是用k-means,不過k=1024,之後再用向量和它被分派到的centroid的殘差做乘積量化,再檢索時,對查詢向量做同樣的操作,就可以避免列舉檢索。

編碼演算法:

(1)量化y到它的code work  qc(y)(codebook 1024*128,訓練集上得到)

(2)計算y 和 qc(y)的殘差,r(y)=y-qc(y)

(3)  對r(y)做乘積量化,參考上述步驟,r(y)的codeword 是qp(r(y)),codebook 256*128,在r(y)上訓練得到

(4)把r(y)的code word加到對應的invert file中。

檢索演算法:

(1)量化x到它的code work  qc(x)(codebook 1024*128,訓練集上得到)

(2)計算x 和 qc(x)的殘差,r(x)=x-qc(x)

(3)在x屬於的code word中計算x與所有向量之間的距離,然後輸出最近鄰的k個。

如圖

整個演算法流程就完成了。這其中還有很多細節問題,不是三言兩語能夠說明白的,有興趣的同學可以和我交流。關於我做的東西會在之後的博文中展示。

這個很實用,可以參考這個自己寫一寫。

強化學習實戰1

利用gym建立如圖所示的迷宮 如下 注意這不是乙個完整的rl agent,因為現在只寫好了影象渲染引擎render agent是乙個類 import gym from gym.envs.classic control import rendering class grid gym.env def i...

強化學習實戰二

這篇部落格主要講解強化學習中兩種典型的問題 離散動作與連續動作,通過前面的學習我們知道離散動作問題可以用 q learning演算法 解決,而連續動作問題可以用 policy gradients演算法 解決。這篇部落格使用的專案環境 mountaincar v0 mountaincarcontinu...

離散化學習總結

離散化在演算法競賽中是乙個很常用且非常好用的乙個技巧,所以學習一下這個還是很有必要的。一 離散化 離散化指的是把大數化為小數,並且保持這幾個數的相對大小不變。比如 原數是1 101 102,離散化之後就是1 2 3。二 離散化的實現 假設我們的陣列是a,並且在開乙個輔助陣列b。賦初值時b i a i...