人臉檢測中Triplet Loss的訓練

2021-10-05 02:36:16 字數 2309 閱讀 9929

triplet loss 是在**facenet中提出的,用於訓練人臉識別和找出同乙個人的不同角度、姿勢、光線條件下的**。為了達到這個目標,我們就需要一張ancor,即告知模型哪個人面是我們需要識別的或者說是需要找到與之類似的臉部,還需要乙個positive,用於讓模型去學習什麼樣的是與ancor類似的,及negative,去判斷什麼樣的是不同的。而triplet loss就是模型的損失函式,在機器學習中,判斷相似性一般都是用距離來判斷,兩者的距離越近,則越相似,反之則越不相同。所以,triplet loss函式,就希望ancor與 positive通過模型學習到的embedding向量間的距離越短越好,而ancor與negative之間的距離越遠越好,並且,為了避免模型偷懶,triplet loss加了乙個margin,這個類似於 svm的正負樣本間的最大間距。triplet loss 公式如下:

loss = max(||f(a) - f( p)||2- ||f(a) - f(n)||2 + margin, 0)

其中,f(a),f(p ), f(n)表示的是通過模型學習到的三個的embedding 向量。

最開始triplet loss的訓練並不容易,它需要訓練很長的時間才能收斂。因為最開始是將(ancor, positive, negative) 三張為一組,用三個共享weights的模型訓練得到它們的embedding資料,然後再用這三個embedding資料去計算triplet loss, 再反向傳播更資料模型的weights資料。這樣,假設乙個批次我們能訓練100組(ancor, positive, negative), 即300 張,我們的訓練資料中有15個人,每個人20張,共300張,這300張可能組成2850組(ancor, positive, negative) ,即300張,我們需要訓練29個批次[^1],所以最初人臉識別的訓練時間會很長。

後來在in dense of the triplet loss for person re-indetification **中提到了改進的方法。提出了batch all, batch hard。 在**中說到,要讓triplet loss訓練有好的效果,我們需要為模型提供比較好的訓練資料對,這樣可以加快模型的收斂,這裡說的是batch hard方式( 在後面會詳細解釋)。不論batch all還是batch hard, 我們並不需要把訓練資料按前面提到的那樣,組成(ancor, positive, negative)資料後,再餵給模型,而是一次性將300張餵給模型,然後輸入維度為(300, 128)的embeddings資料,其中300為batch_size, 128為我們embeddings資料的維度。然後我們可以使用這些embeddings 資料來計算triplet loss。計算步驟如下:

1. 計算距離: 計算embedding向量組的距離,計算公式為:||a - b||2, 計算後的pairwise_distance維度為(300, 300)

2. 如果是batch all, 即意味著,我們要從上面得到pairwise_distance的matrix去找出所有有效的(ancor, positive, negative) 資料組的距離值。對於ancor_positive的距離,我們將第一步得到的距離維度擴充套件成(300, 300, 1), 而ancor_negative的距離是將其擴充套件成(300, 1, 300)維,然後兩者相減,得到維度為(300,300,300)的matrix, 再加上margin資料,作為triplet loss的中間值,我們還需要通過相應的label(用於標名是否是同乙個人)過濾出所有的真實可用的(ancor, positive, negative)組的loss值,然後用max(loss, 0)得到triplet loss, 再對triplet loss取平均值,不過這裡需要注意的是,求均值時,要去掉triplet loss為0的數量(即easy triplets)[^2]。

3. 如果是batch hard, 意味著我們只取那些ancor與positive的距離最大,ancor與negative的距離最小的組成triplets。即為ancor找出hard positive(是同一人,但不容易辯認出來的)和hard negative(不是同乙個人,但很相似的人的)。因此首先根據label找出有效的 ancor_positive 資料對的距離,再從中找出hard positive的距離;然後用同樣的方法找出有效的ancor_negative 的距離,因為這裡要取最小值,我們可以先將無效的ancor_negative的距離加上最大值,再取最小值,最後算出triplet loss, 再取平均值。

使用這種方法訓練triplet loss後,效果會很好,而且就算我們不用已訓練好的imagenet的模型,如vgg, inceptionv3等,而是自己重新建立乙個更小一些的cnn網路模型,也是能得到不錯的訓練效果。當然,對做一些預處理,如檢測出人臉區域,栽剪,對齊,對訓練的速度都有一定的幫助。

reference

人臉識別之人臉檢測

人臉識別分為人臉檢測 人臉預處理 蒐集和學習人臉以及人臉識別四個部分,此部分將人臉檢測。本文基於opencv進行的。在opencv中常用的人臉檢測器有基於lbp的特徵檢測 基於haar的特徵檢測,兩者的區別 前者比後者快好幾倍且不需要許可協議,但很多haar檢測器需要許可協議。基於haar的臉部檢測...

OpenCV人臉檢測 眼睛檢測之在人臉以外找眼睛

今天在學習opencv人臉檢測時,發現眼睛檢測是在人臉以外尋找眼睛的,源 如下 import cv2 def detect face cascade cv2.cascadeclassifier cascades haarcascade frontalface default.xml eye casc...

人臉檢測2

下面的 是講具體如何訓練 當時我想研究車牌識別的,用此方法對車牌進行訓練沒有成功,呵呵。下面是成功的例子,注意是 opencv中的traincascade.exe不是 另外那個 opencv traincascade.exe data data vec a.vec bg e lch train im...