吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

Triplet 損失(Triplet 損失)

要想通過學習神經網絡的參數來得到優質的人臉圖片編碼,方法之一就是定義

三元組損失函數然後應用梯度下降

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

我們看下這是什麼意思,為了應用三元組損失函數,你需要比較成對的圖像,比如這個圖片,為了學習網絡的參數,你需要同時看幾幅圖片,比如這對圖片(編號1和編號2),你想要它們的編碼相似,因為這是同一個人。然而假如是這對圖片(編號3和編號4),你會想要它們的編碼差異大一些,因為這是不同的人。

用三元組損失的術語來說,你要做的通常是看一個 Anchor 圖片,你想讓Anchor圖片和Positive圖片(Positive意味著是同一個人)的距離很接近。然而,當Anchor圖片與Negative圖片(Negative意味著是非同一個人)對比時,你會想讓他們的距離離得更遠一點。

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

這就是為什麼叫做三元組損失,它代表你通常會同時看三張圖片,你需要看Anchor圖片、Positive圖片,還有Negative圖片,我要把Anchor圖片、Positive圖片和Negative圖片簡寫成A、P、N。

把這些寫成公式的話,你想要的是網絡的參數或者編碼能夠滿足以下特性,也就是說你想要||f(A)-f(P)||^2,你希望這個數值很小,準確地說,你想讓它小於等f(A)和f(N)之間的距離,或者說是它們的範數的平方(即:||f(A)-f(P)||^2≤||f(A)-f(N)||^2)。(||f(A)-f(P)||^2)當然這就是d(A,P),(||f(A)-f(N)||^2)這是d(A,N),你可以把d看作是距離(distance)函數,這也是為什麼我們把它命名為d。

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

現在如果我把方程右邊項移到左邊,最終就得到:||f(A)-f(P)||^2≤||f(A)-f(N)||^2

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

現在我要對這個表達式做一些小的改變,有一種情況滿足這個表達式,但是沒有用處,就是把所有的東西都學成0,如果f總是輸出0,即0-0≤0,這就是0減去0還等於0,如果所有圖像的f都是一個零向量,那麼總能滿足這個方程。

所以為了確保網絡對於所有的編碼不會總是輸出0,也為了確保它不會把所有的編碼都設成互相相等的。另一種方法能讓網絡得到這種沒用的輸出,就是如果每個圖片的編碼和其他圖片一樣,這種情況,你還是得到0-0。

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

為了阻止網絡出現這種情況,我們需要修改這個目標,也就是,這個不能是剛好小於等於0,應該是比0還要小,所以這個應該小於一個 -a 值(即||f(A)-f(P)||^2-||f(A)-f(N)||^2≤-a),這裡的a是另一個超參數,這個就可以阻止網絡輸出無用的結果。

按照慣例,我們習慣寫+a(即||f(A)-f(P)||^2-||f(A)-f(N)||^2+a≤0),而不是把-a寫在後面,它也叫做

間隔(margin),這個術語你會很熟悉,如果你看過關於支持向量機 (SVM) 的文獻,沒看過也不用擔心。我們可以把上面這個方程(||f(A)-f(P)| |^2-||f(A)-f(N)||^2)也修改一下,加上這個間隔參數。

舉個例子,假如間隔設置成0.2,如果在這個例子中,d(A,P)=0.5,如果 Anchor和 Negative圖片的d,即d(A,N)只大一點,比如說0.51,條件就不能滿足。

雖然0.51也是大於0.5的,但還是不夠好,我們想要d(A,N)比d(A,P)大很多,你會想讓這個值(d(A,N))至少是0.7或者更高,或者為了使這個間隔,或者間距至少達到0.2,你可以把這項調大或者這個調小,這樣這個間隔a,超參數a 至少是0.2,在d(A,P)和d(A,N)之間至少相差0.2,這就是間隔參數a的作用。

它拉大了Anchor和Positive 圖片對和Anchor與Negative 圖片對之間的差距

取下面的這個方框圈起來的方程式,在下個幻燈片裡,我們會更公式化表示,然後定義三元組損失函數。

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

三元組損失函數的定義基於三張圖片假如三張圖片A、P、N,即anchor樣本、positive樣本和negative樣本,其中positive圖片和anchor圖片是同一個人,但是negative圖片和anchor不是同一個人。

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

接下來我們定義損失函數,這個例子的損失函數,它的定義基於三元圖片組,我先從前一張幻燈片複製過來一些式子,就是||f(A)-f(P)||^2-||f(A)-f(N)||^2+a≤0。所以為了定義這個損失函數,我們取這個和0的最大值:

L(A,P,N)=max(||f(A)-f(P)||^2-||f(A)-f(N)||^2+a,0)

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

這個max函數的作用就是,只要這個||f(A)-f(P)||^2-||f(A)-f(N)||^2+a≤0,那麼損失函數就是0。只要你能使畫綠色下劃線部分小於等於0,只要你能達到這個目標,那麼這個例子的損失就是0。

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

另一方面如果這個||f(A)-f(P)||^2-||f(A)-f(N)||^2+a≤0,然後你取它們的最大值,最終你會得到綠色下劃線部分(即||f(A)-f(P)||^2-||f(A)-f(N)||^2+a)是最大值,這樣你會得到一個正的損失值。

通過最小化這個損失函數達到的效果就是使這部分||f(A)-f(P)||^2-||f(A)-f(N)||^2+a成為0,或者小於等於0。只要這個損失函數小於等於0,網絡不會關心它負值有多大。

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

這是一個三元組定義的損失

整個網絡的代價函數應該是訓練集中這些單個三元組損失的總和。假如你有一個10000個圖片的訓練集,裡面是1000個不同的人的照片,你要做的就是取這10000個圖片,然後生成這樣的三元組,然後訓練你的學習算法,對這種代價函數用梯度下降,這個代價函數就是定義在你數據集裡的這樣的三元組圖片上。

注意,為了定義三元組的數據集你需要成對的A和P,即同一個人的成對的圖片,為了訓練你的系統你確實需要一個數據集,裡面有同一個人的多個照片。

這是為什麼在這個例子中,我說假設你有1000個不同的人的10000張照片,也許是這1000個人平均每個人10張照片,組成了你整個數據集。

如果你只有每個人一張照片,那麼根本沒法訓練這個系統。當然,訓練完這個系統之後,你可以應用到你的一次學習問題上,對於你的人臉識別系統,可能你只有想要識別的某個人的一張照片。但對於訓練集,你需要確保有同一個人的多個圖片,至少是你訓練集裡的一部分人,這樣就有成對的Anchor和Positive圖片了。

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

現在我們來看,你如何選擇這些三元組來形成訓練集

一個問題是如果你從訓練集中,隨機地選擇A、P和N,遵守A和P是同一個人,而A和N是不同的人這一原則

有個問題就是,如果隨機的選擇它們,那麼這個約束條件(d(A,P)+a≤d(A,N))很容易達到,因為隨機選擇的圖片,A和N比A和P差別很大的概率很大。

我希望你還記得這個符號d(A,P)就是前幾個幻燈片裡寫的||f(A)-f(P)||^2,d(A,N)就是||f(A)-f(N)||^2,d(A,P)+a≤d(A,N)即||f(A)-f(P)||^2+a≤||f(A)-f(N)||^2。

但是如果A和N是隨機選擇的不同的人,有很大的可能性||f(A)-f(N)||^2會比左邊這項||f(A)-f(P)||^2大,而且差距遠大於a,這樣網絡並不能從中學到什麼。

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

所以為了構建一個數據集,你要做的就是儘可能選擇難訓練的三元組A、P和N。具體而言,你想要所有的三元組都滿足這個條件(d(A,P)+a≤d(A,N)),難訓練的三元組就是,你的A、P和N的選擇使得d(A,P)很接近d(A,N),即d(A,P)≈d(A,N),這樣 你的學習算法會竭盡全力使右邊這個式子變大d(A,N),或者使左邊這個式子(d(A,P))變小,這樣左右兩邊至少有一個a的間隔。

並且選擇這樣的三元組還可以增加你的學習算法的計算效率,如果隨機的選擇這些三元組,其中有太多會很簡單,梯度算法不會有什麼效果,因為網絡總是很輕鬆就能得到正確的結果,只有選擇難的三元組梯度下降法才能發揮作用,使得這兩邊離得儘可能遠。

如果你對此感興趣的話,這篇論文中有更多細節,作者是Florian Schroff, Dmitry Kalenichenko, James Philbin,他們建立了這個叫做FaceNet的系統,這裡許多的觀點都是來自於他們的工作。

	Florian Schroff, Dmitry Kalenichenko, James Philbin (2015). FaceNet: A Unified Embedding for Face Recognition and Clustering

順便說一下,這有一個有趣的事實,關於在深度學習領域,算法是如何命名的。

如果你研究一個特定的領域,假如說“某某”領域,通常會將系統命名為“某某”網絡或者深度“某某”,我們一直討論人臉識別,所以這篇論文叫做FaceNet(人臉網絡),上個筆記裡你看到過DeepFace(深度人臉)。

“某某”網絡或者深度“某某”,是深度學習領域流行的命名算法的方式,你可以看一下這篇論文,如果你想要了解更多的關於通過選擇最有用的三元組訓練來加速算法的細節,這是一個很棒的論文。

總結一下,訓練這個三元組損失你需要取你的訓練集,然後把它做成很多三元組

三元組(編號1),有一個Anchor圖片和Positive圖片,這兩個(Anchor和Positive)是同一個人,還有一張另一個人的Negative圖片

另一組(編號2),其中Anchor和Positive圖片是同一個人,但是Anchor和Negative不是同一個人,等等。

吳恩達深度學習筆記(104)-人臉檢測之Triplet 損失

定義了這些包括A、P和N圖片的數據集之後,你還需要做的就是用梯度下降最小化我們之前定義的代價函數J,這樣做的效果就是反向傳播到網絡中的所有參數來學習到一種編碼,使得如果兩個圖片是同一個人,那麼它們的d就會很小,如果兩個圖片不是同一個人,它們的d就會很大。

這就是三元組損失,並且如何用它來訓練網絡輸出一個好的編碼用於人臉識別。

現在的人臉識別系統,尤其是大規模的商業人臉識別系統都是在很大的數據集上訓練,超過百萬圖片的數據集並不罕見,一些公司用千萬級的圖片,還有一些用上億的圖片來訓練這些系統。

這些是很大的數據集,即使按照現在的標準,這些數據集並不容易獲得。

幸運的是,一些公司已經訓練了這些大型的網絡並且上傳了模型參數。

所以相比於從頭訓練這些網絡,在這一領域,由於這些數據集太大,

這一領域的一個實用操作就是下載別人的預訓練模型,而不是一切都要從頭開始(恩達老師的寶貴經驗吶,謹記謹記謹記)。但是即使你下載了別人的預訓練模型,我認為了解怎麼訓練這些算法也是有用的,以防針對一些應用你需要從頭實現這些想法。

這就是三元組損失,下個筆記中,我會給你展示Siamese網絡的一些其他變體,以及如何訓練這些網絡。


分享到:


相關文章: