工程上的影象檢索技術概述
從影象特徵說起
以人臉識別場景為例,我們通過機器學習演算法可以對人臉圖片實現降維,即某張圖片的尺寸是64*64的RGB影象,那麼這個影象的維度就是64*64*3 = 12288維。直接將這個維度用於影象識別顯然是不合適的,這是影象的原始維度,不是影象的特徵。
提取影象特徵的過程是一個降維過程,常用的維度通常是512維,1024維等,也就是將一個圖片進行特徵提取,提取到的特徵向量的維度,說白了就是這個向量的元素數量。
通過提取圖片的特徵,我們就可以對比兩張圖片的相似度,一個典型的應用場景是人臉驗證,如果兩張人臉圖片的相似度小於閾值,那麼就判斷這兩張人臉圖片是一個人,否則是兩個人。
何為影象檢索
我們在前面提到過人臉驗證場景,這個過程大體是將兩張人臉圖片的特徵提取出來,然後對比兩張人臉圖片的特徵向量的相似度(也就是向量間的距離),這很明顯是一個1:1的過程,這個過程只是對比兩張圖片。那麼將這個場景再複雜一點,要想在具有N張圖片的資料庫中找到哪張圖片與我上傳的圖片是類似的圖片,這個場景就是一個1:N的場景,明顯錯誤率要比1:1的高很多。
舉一個實際的例子,xx識圖系統,我上傳某一張圖片,他會給我返回一張類似的圖片。
這個過程怎麼實現呢,最簡單的方法就是暴力掃描,如果圖片資料庫中有n張圖片,那麼這個線性掃描的時間複雜度就是O(n), 如果這個n很大,也就是海量資料的時候,用暴力的線性掃描是根本不可取的,試想淘寶拍照識別商品時,整個過程讓你等上若干個小時,你還會去等待嗎?不可能的。
因此,對於海量資料場景,高效的影象檢索技術尤其重要。
影象檢索的方法
影象檢索是一個細分的研究領域,這個研究領域有很多PhD在奮鬥,筆者在此簡單介紹一下常用的影象檢索方法。
通常用的影象檢索方法可以包括線性掃描、層次kd樹,層次kmeans,基於雜湊的影象檢索,以及基於圖的影象檢索等。
這裡面的很多演算法是很複雜的,不仔細研讀幾遍論文是很難理解透徹的,特別是基於雜湊的影象檢索和kmeans演算法的一些變種。
筆者在此簡單介紹一種理解簡單且相對常用的影象檢索方法,基於k-means演算法的一種影象檢索方法。
hierarchical kmeans演算法是在圖片特徵空間進行聚類,共聚成k類,這樣我們就將圖片資料分成了k個類別,假如聚類是均勻的,對於N個圖片,平均每個類別的資料就有 N/k 個,由於N是比較大的,因此每個類別的資料還是很大,那麼接下來再對這N/k個數據進行聚類,以此類推,就可以得到一個樹。
在影象檢索的時候,如果希望得到與某個圖片類似的圖片,就可以通過這個熟,將其相鄰的節點返回即可,這樣,就極大地減少了資料掃描的複雜度。
總結
上述這個演算法有個問題:
一個是資料是不是像我們上面說的被分得比較均勻,如果不均勻,有些結果會返回得比較快,有些結果會由於樹太高而造成返回結果相對較慢。
另外,對於大量資料來講,這個樹的規模肯定會更大,在k一定的情況下,樹也會更高,因此,在海量資料的時候,這個演算法就不太實用了。
因此,人們在這基礎上提出了改進的演算法,但是,都是基於K-means演算法來實現的。
對於上述我們介紹的這種hierarchical kmeans演算法,其實是一種相對demo的演算法,演算法比較容易實現,例如直接使用Spark就可以實現在海量資料中的影象檢索,構成數的每個節點上儲存的是一個影象的key值,我們可以在物件儲存(OBS)上通過這個key值來獲取影象的二進位制檔案。
工程上特徵向量的檢索尚沒有完備的直接開源產品,絕大多數都需要手動實現,大廠都有自己的實現方法。Spark是一種很好的實現計算引擎,可以通過其內建的kmeans演算法實現為影象等高維、非結構化資料建立索引,從而加快檢索速度。