從手工提取特徵到深度學習的三種圖像檢索方法

雷鋒網 AI 科技評論按:本文為專欄作者兔子老大為 AI 科技評論撰寫的獨家稿件,未經許可不得轉載。

前言

圖片檢索是計算機視覺,數字圖像處理等領域常見的話題,在我學習相關知識的過程中,圖像檢索算是我第一個學習的 demo,該過程都記錄在 利用python進行識別相似圖片(一) 和 利用python進行識別相似圖片(二) 兩篇文章,分別記錄了直方圖匹配,phash/average hash/dhash 三種基於哈希的方法。

圖片檢索的的大體框架大致可以分成兩步,抽取某種特徵,計算相似度。其中像上述提及的幾種方法,都是對應抽取特徵這一步,而計算相似度,則常使用歐式距離/漢明距離/Triplet 等方法。顯然的,上述方法都屬於人工設計的方法來進行抽取特徵,很自然的就想到使用當今很火熱的深度學習來代替人工的設計的方法,所以這篇文章主要介紹的就是基於深度學習的圖片檢索。

本文主要介紹的文章有以下幾篇:

  • Deep Learning of Binary Hash Codes for Fast Image Retrieval -- CVPR WORKSHOP 2015

  • DEEP SUPERVISED HASHING FOR FAST IMAGE RETRIEVAL -- CVPR 2016

  • Feature Learning based Deep Supervised Hashing with Pairwise Labels -- IJCAI 2016

提及到使用深度學習提取圖像特徵,業界一般認為現有的圖像模型中,前面的卷積層負責提取相關特徵,最後的全連接層或者 globel pooling 負責分類,因此一般的做法是直接取前幾層卷積的輸出,然後再計算相似度。

但這樣涉及到一個問題,首先一個是數據精度問題,因為直接取特徵輸出多是浮點數,且維度高,這會導致儲存這些圖像的特徵值會耗費大量空間,第二個因為緯度高,所以用歐式距離這種方式計算相似度,可能會觸發維度災難,令使用歐式距離代表相似度這種方法失效。

其中一種解決方法是使用 Triplet 函數構造一個能夠學習如何計算相似度的神經網絡。雖然 Triplet 這個方法並不在本文介紹範圍,但為了讀者可以橫向對比相關方法,這裡粗略的介紹以下基於 Triplet 的做法。

Triplet 的做法很簡單,人工構建一個三元集合,該三元集合包括(圖片 A,與 A 相似的圖片 B,與 A 不相似的圖片 C),期望該神經網絡接受兩個圖片輸入,若為相似,則輸出一個較高的分數,若不相似則輸出一個較低的分數。

Triplet Loss 的構造如上式所示,其中 f(xi) 為原圖在神經網絡輸出的分數,f(xj) 相似圖在神經網絡輸出的分數,f(xk) 為不相似圖片的輸出分數,在這條表達式中,我們期待相似圖片的分數之間,盡量接近,而不相似圖片的分數盡量遠離。在不考慮α時有個問題,顯然,

時,L=0,

這樣就沒有達到我們希望相似圖片和不相似圖片的分數在空間上存在一定的間隔這個目標,而 α 的設定,就是這個間隔。

顯然,α 設定太小,神經網絡不太容易區分相似圖片,而設定太大,則相當於對神經網絡提出更高的要求,神經網絡的收斂會更加不穩定。

Triplet 適合圖片檢索時每個類別的樣本不大的情況下,比如人臉檢測。但有研究指出,Triplet 集合的構建會影響訓練的效果,也就是該如何人工的定義相似和不相似,所以也有相關工作在構建 Triplet 上展開,但本文主要說的是另一種方法,即基於哈希的三種方法。

Deep Learning of Binary Hash Codes for Fast Image Retrieval -- CVPR WORKSHOP 2015

之所以先選擇這篇文章先作討論,是因為這篇文章的工作的思想和上文提及的方法,和下文要提到的文章思想過度的比較自然,方便讀者理解。

上文提及,最為簡單的方式是使用神經網絡特徵層的輸出用於計算空間距離來判斷相似度,但這樣會導致浮點型數據儲存消耗和維度災難。針對這兩個問題,這篇文章提出的方法較為直接。

浮點數據怎麼辦?將他離散成二值型數據,也就是一串 0 和 1 的哈希,這樣只需要幾個 byte 就能儲存一個數據了。

維度高怎麼辦?把他壓縮成低維唄。

所以我才說這篇文章的思路是十分直接和易於理解的,十分適合放在第一篇用於過渡。

下面說說文章的具體做法:

 

既然我們希望特徵的輸出可以離散化成 0 和 1,那就希望特徵的分佈是關於某個值對稱的,然後只要根據該值作為閾值二值化即可,就這樣一步步推導,自然想到使用 tanh 或 sigmoid 函數,因為其輸出是關於 0 對稱或關於 0.5 對稱。該論文使用的 sigmoid 代替了預訓練網絡的倒數第二層的 ReLU 函數,且把輸出的維度壓縮至 12~48 之間,然後進行微調。

在微調的過程中,有幾點:一般我們的微調方法是指將前面卷積的權重凍結,然後訓練後面分類器的的權重。但在這裡,一個是因為維度的減少,第二個是 sigmoid 做中間層的激活函數可能會造成梯度消失,神經網絡的能力其實有了一定程度的衰減。因此做微調的時候,作者只是把 sigmoid 層的參數採用隨機化,其餘參數,包括分類器的大部分參數都保留下來,然後在訓練期間,sigmoid 使用 1e-3 的學習率,其餘層使用 1e-4 的學習率進行學習。對於 cifar10 來說,使用數據強化后,能達到 89% 左右的 Accuracy,圖片檢索的 map 能夠達到 85%,可以說性能上十分可觀。

論文鏈接:http://www.iis.sinica.edu.tw/~kevinlin311.tw/cvprw15.pdf

參考實現:https://github.com/flyingpot/pytorch_deephash

DEEP SUPERVISED HASHING FOR FAST IMAGE RETRIEVAL -- CVPR 2016

上文提及我們離散化時希望輸出的特徵的關於某個值對稱,所以有文章用了 sigmoid 作為特徵層的輸出的激活函數,但直接引用 sigmoid 函數會導致一些問題,那有沒有辦法緩解這些問題?有,那就是使用正則的方法將輸出約束到某一個範圍內。

這篇 CVPR 2016 的論文做法就是如此,並沒有像上述文章那樣使用分類網絡中間層來進行哈希,而是使用神經網絡直接學習哈希編碼,並用正則化方法將編碼進行約束。

具體來說,就是讓神經網絡的輸出通過正則的手法約束到 {-1,1} 之內(後續使用 0 作為閾值進行離散化),然後讓網絡的輸出達到以下的要求,相似的時候向量距離應該較近,反之則遠,下面通過其目標函數的表現形式來介紹具體過程

目標函數:

其中 b1,b2 是神經網絡輸出的向量,y 是一個標誌,相似時記為 0,不相似時記作 1,其中超參數有兩個,m 時用於控制 b1 和 b2 的最優間隔,和 α 是正則項的權重,可見當輸入的是相似圖片時,y=0,要使 L 最小,需要最小化兩個向量的距離和正則項。而當圖片不相似時,y=1,最少化 L 需要使得兩個向量的距離分佈在 m 的附近,以及最小化正則項。

最後的正則項使得輸出的特徵向量分佈在 {-1,1}。

而下圖是展示的是 m 和 α 對輸出分佈的影響。

對於 CIFAR-10 來說,最終 map 只能 0.54~0.61,比上文提到的第一個方法要低,但實質這個方法要更靈活。

論文鏈接:https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Liu_Deep_Supervised_Hashing_CVPR_2016_paper.pdf

參考實現:https://github.com/yg33717/DSH_tensorflow

Feature Learning based Deep Supervised Hashing with Pairwise Labels——IJCAI 2016

如圖所示,這篇文章和上文提及的第二種方法大致相似。不採用分類網絡的中間層作為特徵,而是直接採取一個神經網絡進行哈希函數的學習,並用正則方法將輸出的特徵的序列約束到一定範圍內。

下面通過目標函數的形式來說明具體過程:

其中 b 為輸出向量,Sij 是 label,相似為 1,否則為 0,ξij=bi*bjT,而 W,v 分別是最後一層的權重和偏置,而ϕ(x;ξ) 即是倒數第二層輸出。

算法的更新步驟如下:

 

該方法在 CIFAR-10 數據集上取得 0.71~0.80 的 map 值。

論文鏈接:https://cs.nju.edu.cn/lwj/paper/IJCAI16_DPSH.pdf

參考實現:https://github.com/jiangqy/DPSH-pytorch

總結

本文分享了之前使用手工設計規則的方法來提取圖片特徵用于衡量相似度,隨後介紹了深度學習在圖片搜索的過程,並給出三篇文章介紹了圖片檢索任務的大體框架和思路流程。


想在手機閱讀更多程式設計資訊?下載【香港矽谷】Android應用
分享到Facebook
技術平台: Nasthon Systems