人臉驗證算法Joint Bayesian詳解及實現(Python版)
Tags: JointBayesian DeepLearning Python
本博客僅爲作者記錄筆記之用,不免有很多細節不對之處。
還望各位看官能夠見諒,歡迎批評指正。
博客雖水,然亦博主之苦勞也。
如需轉載,請附上本文鏈接,不甚感激!
Bayesian Face Revisited: A Joint Formulation
============================
研究人臉識別方向快一年多了,雖沒有什麼大的成果,不過總歸還算有些許小收穫。
在下不才,未能像師兄張雨石 那般洋洋灑灑寫下DeepID人臉識別算法之三代 之類的深度好文。只好另闢蹊徑,走走少有人走的路,哈哈!(注:本文乃大水文,大神請勿逗留)。
我們知道,人臉識別有兩個大方向:
- Face Verification,判斷兩張人臉是否爲同一個人。
- Face Identification,從一個人臉庫中找到給定的這張人臉對應的身份。
本文要重點介紹的Joint Bayesian 就是用來實現第一個(face verification)功能的。本文主要是針對Bayesian Face Revisited: A Joint Formulation 這篇文章的筆記。這篇論文僅通過高維LBP跟Joint Bayesian這兩個方法結合,就把LFW 數據集上的人臉驗證準確率輕鬆刷到了92.4%. 香港中文大學團隊的DeepID2將七個聯合貝葉斯模型使用SVM進行融合,最終達到了99.15%的結果。
一個Naive的想法
如果這個任務交給你,你最開始會怎麼想?如何判斷兩張圖片是否爲同一個人?
- 提取這兩張圖片的特徵,然後得出兩張圖片的差異? -
- 通過差異來判斷,差異爲何種情況時爲同一個人,否則爲不同人?
我們假裝專業一點,用x1,x2 分別表示兩張圖片,Hi表示這兩張圖片爲intra-personal(同一個人),用 He表示extra-personal(不同人)。用 △ 表示 x1-x2 (兩者差異)。
假裝我們能夠寫下如下公式(反正我肯定寫不出來):
這裏S(△)就是關於差異△的函數,如果:
- S(△) >=Thresold: 爲同一個人;
- S(△) < Thresold: 非同一個人;
如果你瞭解一點 MAP(Maximum a Posterior, 最大後驗假設),那麼上面的複雜的式子就可以轉化成近似求一個對數似然比(結果差別不大,但是運算速度大幅提高,最重要的是式子簡單很多有沒有。。。):
問題轉換爲如下,如果:
- 如果P(△|Hi)很大,P(△|He)很小,ratio值很大,則判斷爲同一個人;
- 如果P(△|Hi)很小,P(△|He)很大,ratio值很小,則判斷爲不同人;
- 但是,若兩者同時很小,或同時很大,這會造成一個分類錯誤,結果無法斷定。這種情況如下圖所示:
從上圖中可以看到,2-D的數據通過差分x-y映射到1-D上。O附近的點交錯在一起, 使得在O附近的Class-1 和Class-2 無法區分開來。這就是我們這個Naive想法的缺陷了。
A Naive Bayesian
如果上面的想法能夠再Naive一點,再理想化一點,我們假設(x1, x2)服從高斯分佈,那麼就有:
- P(x1, x2|Hi) = N(0, ∑I),
- p(x1, x2|He) = N(0, ∑E)
再用R來求驗證x1, x2的相似性。其中 ∑I 和 ∑E 分別是同一個人和不同人的協方差矩陣。
這就是Naive Bayesian方法了,這樣得到的結果會比傳統的貝葉斯臉要好。
上面的這種方法是從統計數據中直接訓練得到協方差矩陣∑I,∑E。有兩個因素可能會限制效果:
- 我們假設人臉特徵爲d維的特徵,而我們需要從更高的維度空間(2d)中計算出協方差矩陣,由於訓練缺乏足夠多的獨立的訓練數據,所以我們得到的可能是一種不可靠的統計結果。
- 由於數據集中訓練樣本不完全獨立,因此∑E有可能不是(blockwise)塊對角線矩陣。而上面的公式中要求x1,x2必須相互獨立。
A joint formulation
看到下面這張圖片,你有沒有什麼靈感?提示:左圖爲不同人的臉部特徵分佈情況,右圖爲同一個人的臉部特徵分佈情況:
從上圖可以得出,一個人臉由兩部分組成:identity 和 intra-personal variation。 identity 用來區分不同人,intra-personal variation 是同一個人在不同姿態下的差異。我們用 μ 來表示identity,用 ε 表示intra-personal
variation(包括:光線,姿態,表情等變化),那麼人臉x就可以用如下公式定義了:
上式中,這兩個潛在變量 μ 和 ε 分佈服從兩個高斯分佈:N(0, Sμ) 和 N(0, Sε)。簡要來說,上面的表達式包括附加的一些假設可以作爲一個人臉的先驗知識。
Joint formulation with prior
有了上面的先驗知識,就可以得到一個均值爲0的高斯聯合分佈{x1,x2}。若 μ 和 ε 是相互獨立的,那麼我們就可以得到兩張人臉特徵的協方差如下:
1. 在 Hi的假設前提下
此時,μ1 和 μ2 是相同的,並且ε1 和 ε2 是獨立的。
因此P(x1, x2|Hi)分佈的協方差矩陣就可以按照如下計算:
2. 在 He的假設前提下
此時,μ 和ε 都是獨立的。
因此P(x1, x2|He)分佈的協方差矩陣就可以按照如下計算:
有了上面的兩種情況下的聯合概率,相應的對數似然比 r(x1,x2) 就可以在簡單的代數變換之後得到(其實博主一點都不覺得簡單,但是我們還是要假裝很輕鬆的樣子。。。。):
注意:這式子(4)中,爲了簡單處理,常數項被省略。在這個對數似然比矩陣中,還有三個有趣的特性,讀者有興趣的可以再讀一讀原文附件的一些材料:
—-> 1. 矩陣 A 和 G 都是非負半正定矩陣
—-> 2. 如果 A = G, 那麼這個對數似然比就降爲馬氏距離
—-> 3. 特徵在經過任何的滿秩的線性變化之後,這個對數似然比矩陣都是不變的
Model Learning
上面的一大堆可能你並沒有看懂推導過程的式子,主要在告訴我們一件事情:
如果兩個潛在變量 μ (identity) 和 ε (intra-personal variance) 分佈服從兩個高斯分佈:N(0, Sμ) 和 N(0, Sε), 那麼,對數似然比r(x1,x2)就可以通過兩個協方差矩陣 Sμ 和 Sε 計算得到。
所以,現在的任務就是訓練模型來求這兩個未知的 Sμ 和 Sε .
我們可以很簡單地利用經典的 LDA (線性判別分析) 來求出這兩個類內跟類間的協方差矩陣,實際上,使用這個LDA方法,你還是能夠得到一個比較不錯的結果了。但是,爲了得到更高精度的準確率,我們的模型採用的是一個類 EM 算法來求解。這裏就按照EM算法的兩步走來介紹:
E-step (期望步驟)
假設每個人有m 張圖片,那麼x=[x1;…x;m], 相應的潛在變量就是 h=[μ ;ε1;…;εm],h 與 x 的關係如下:
總結一下,首先通過已知的協方差矩陣Sμ 和 Sε 求解對應的F和G,然後由F,G,去求解對應的 μ 和 ε .
M-step (最大化步驟)
在這個步驟中,我們的目標是更新參數值Θ={Sμ, Sε}:
這裏的 μ 和 ε 是E-step 階段的結果。
不斷重複E-step 跟M-step過程,直到Sμ, Sε收斂。
Initialization (初始化)
在代碼實現中,μ 和 ε 是通過隨機的正定矩陣初始化得到。例如,你可以從隨機的一些數據中得到協方差矩陣當做初始值。
Verify(對數似然比的計算)
對數似然比ratio 的計算公式如下:
得到這個ratio之後,如果 ratio >= 閾值,則認爲是同一個人;否則不是同一個人。
算法實現(Python版)
已經在網上看到有人實現了matlab版本的joint bayesian,不過因爲我們實驗室一直是python的天下,所以簡單的照着matlab版本,用numpy實現了一把。
我把代碼都放到了github上,而且裏面有完整的使用說明和實驗報告。
所以這裏就不貼代碼了。這裏就簡單貼一個算法的大致流程圖:
(圖片引用自: http://blog.csdn.net/hqbupt/article/details/37758627)
對代碼有興趣的請移步我的 Github.
代碼只是實驗用,寫的並不好,勉強能運行,歡迎拍磚!
參考文獻
[1]. D.Chen, X.Cao, L.Wang, F.Wen, and J.Sun. Bayesian face revisited: A joint formulation.In Proc. ECCV, 2012.
[2]. http://blog.csdn.net/csyhhb/article/details/46300001
[3]. http://www.zhihu.com/question/28086678
[4]. http://blog.csdn.net/hqbupt/article/details/37758627