Triplet 損失
要想通過學習神經網絡的參數來得到優質的人臉圖片編碼,方法之一就是定義三元組損失函數然后應用梯度下降。
為了應用三元組損失函數,你需要比較成對的圖像,比如這個圖片,為了學習網絡的參數,你需要同時看幾幅圖片,對於前兩張圖片,你想要它們的編碼相似,因為這是同一個人,對於后兩張圖片,你會想要它們的編碼差異大一些,因為這是不同的人。
用三元組損失的術語來說,你要做的通常是看一個 Anchor 圖片,你想讓 Anchor 圖片和 Positive 圖片(Positive 意味着是同一個人)的距離很接近。然而,當 Anchor 圖片與 Negative圖片(Negative 意味着是非同一個人)對比時,你會想讓他們的距離離得更遠一點。
這就是為什么叫做三元組損失,它代表你通常會同時看三張圖片,你需要看 Anchor 圖片、 Postive 圖片,還有 Negative 圖片,我要把 Anchor 圖片、 Positive 圖片和 Negative 圖片簡寫成 A、P、N。
把這些寫成公式的話,你想要的是網絡的參數或者編碼能夠滿足以下特性,也就是說你想要${\left\| {f(A) - f(P)} \right\|^2}$,你希望這個數值很小,准確地說,你想讓它小於等${f(A)}$ 和${f(N)}$ 之間的距離,或者說是它們的范數的平方,即:${\left\| {f(A) - f(P)} \right\|^2} \le {\left\| {f(A) - f(N)} \right\|^2}$,${\left\| {f(A) - f(P)} \right\|^2}$就是$d(A,P)$,${\left\| {f(A) - f(N)} \right\|^2}$就是$d(A,N)$,你可以把d看作是距離(distance) 函數,這也是為什么我們把它命名為d。
現在我要對這個表達式做一些小的改變,有一種情況滿足這個表達式,但是沒有用處,就是把所有的東西都學成 0,如果f總是輸出 0, 即$0 - 0 \le 0$,這就是 0 減去 0 還等於 0, 如果所有圖像的f都是一個零向量,那么總能滿足這個方程。所以為了確保網絡對於所有的編碼不會總是輸出 0,也為了確保它不會把所有的編碼都設成互相相等的。另一種方法能讓網絡得到這種沒用的輸出,就是如果每個圖片的編碼和其他圖片一樣,這種情況,你還是得到 0-0。
為了阻止網絡出現這種情況,我們需要修改這個目標,也就是,這個不能是剛好小於等於 0,應該是比 0 還要小,所以這個應該小於一個−a值, 即:
${\left\| {f(A) - f(P)} \right\|^2} - {\left\| {f(A) - f(N)} \right\|^2} \le - a$
這里的a是另一個超參數,這個就可以阻止網絡輸出無用的結果。按照慣例,我們可以修改為如下的形式:
${\left\| {f(A) - f(P)} \right\|^2} - {\left\| {f(A) - f(N)} \right\|^2} + a \le 0$
而不是把-a寫在后面,它也叫做間隔(margin)。
舉個例子,假如間隔設置成 0.2,如果在這個例子中,$d(A,P) = 0.5$,如果 Anchor 和Negative 圖片的d,$d(A,P)$ 只大一點,比如說 0.51,條件就不能滿足。雖然 0.51 也是大於0.5 的,但還是不夠好,我們想要$d(A,P)$比$d(A,N)$ 大很多,你會想讓這個值$d(A,N)$ 至少是 0.7 或者更高,或者為了使這個間隔,或者間距至少達到 0.2,你可以把這項調大或者這個調小,這樣這個間隔a,超參數a 至少是 0.2,在$d(A,P)$和$d(A,N)$ 之間至少相差 0.2,這就是間隔參數a的作用。它拉大了 Anchor 和 Positive 圖片對和 Anchor 與 Negative 圖片對之間的差距。
之間至少相差 0.2,這就是間隔參數a的作用。它拉大了 Anchor 和 Positive 圖片對和 Anchor 與 Negative 圖片對之間的差距。
為了定義這個損失函數,我們取這個和 0 的最大值:
$L(A,P,N) = \max ({\left\| {f(A) - f(P)} \right\|^2} - {\left\| {f(A) - f(N)} \right\|^2} + a,0)$
這個max函數的作用就是,只要這個${\left\| {f(A) - f(P)} \right\|^2} - {\left\| {f(A) - f(N)} \right\|^2} + a \le 0$,那么損失函數就是 0。
另一方面如果這個${\left\| {f(A) - f(P)} \right\|^2} - {\left\| {f(A) - f(N)} \right\|^2} + a \le 0$,然后你取它們的最大值,這樣你會得到一個正的損失值。通過最小化這個損失函數達到的效果就是使這部分:
${\left\| {f(A) - f(P)} \right\|^2} - {\left\| {f(A) - f(N)} \right\|^2} + a$
成為 0,或者小於等於 0。只要這個損失函數小於等於 0,網絡不會關心它負值有多大。
這是一個三元組定義的損失,整個網絡的代價函數應該是訓練集中這些單個三元組損失的總和。假如你有一個 10000 個圖片的訓練集,里面是 1000 個不同的人的照片,你要做的就是取這 10000 個圖片,然后生成這樣的三元組,然后訓練你的學習算法,對這種代價函數用梯度下降,這個代價函數就是定義在你數據集里的這樣的三元組圖片上。
注意,為了定義三元組的數據集你需要成對的A和P,即同一個人的成對的圖片,為了訓練你的系統你確實需要一個數據集,里面有同一個人的多個照片。這是為什么在這個例子中,我說假設你有 1000 個不同的人的 10000 張照片,也許是這 1000 個人平均每個人 10 張照片,組成了你整個數據集。如果你只有每個人一張照片,那么根本沒法訓練這個系統。當然,訓練完這個系統之后,你可以應用到你的一次學習問題上,對於你的人臉識別系統,可能你只有想要識別的某個人的一張照片。但對於訓練集,你需要確保有同一個人的多個圖片,至少是你訓練集里的一部分人,這樣就有成對的 Anchor 和 Positive 圖片了。
一個問題是如果你從訓練集中,隨機地選擇A、 P和N,遵守A和P是同一個人,而A和N是不同的人這一原則。有個問題就是,如果隨機的選擇它們,那么這個約束條件$d(A,P) + a \le d(A,N)$, 很容易達到,因為隨機選擇的圖片,A和N比A和P差別很大的概率很大。這樣網絡並不能從中學到什么。
所以為了構建一個數據集,你要做的就是盡可能選擇難訓練的三元組A、 P和N。具體而言,你想要所有的三元組都滿足這個條件$d(A,P) + a \le d(A,N)$, 難訓練的三元組就是,你的A、 P和N的選擇使得$d(A,P)$ 很接近$d(A,N)$, 即$d(A,P) \approx d(A,N)$, 這樣 你的學習算法會竭盡全力使右邊這個式子$d(A,N)$變大, 或者使左邊這個式子$d(A,P)$ 變小,這樣左右兩邊至少有一個a的間隔。並且選擇這樣的三元組還可以增加你的學習算法的計算效率,如果隨機的選擇這些三元組,其中有太多會很簡單,梯度算法不會有什么效果,因為網絡總是很輕松就能得到正確的結果,只有選擇難的三元組梯度下降法才能發揮作用,使得這兩邊離得盡可能遠。
總結一下,訓練這個三元組損失你需要取你的訓練集,然后把它做成很多三元組:
定義了這些包括A、 P和N圖片的數據集之后,你還需要做的就是用梯度下降最小化我們之前定義的代價函數J,這樣做的效果就是反向傳播到網絡中的所有參數來學習到一種編碼,使得如果兩個圖片是同一個人,那么它們的d就會很小,如果兩個圖片不是同一個人,它們的d就會很大。