FaceNet

傳統的基於CNN的人臉識別方法爲:算法

  1. 利用CNN的siamese網絡來提取人臉特徵網絡

  2. 而後利用SVM等方法進行分類ide

facnet亮點

  1. 利用DNN直接學習到從原始圖片到歐氏距離空間的映射,從而使得在歐式空間裏的距離的度量直接關聯着人臉類似度;模塊化

  2. 引入triplet損失函數,使得模型的學習能力更高效。函數

部分結果展現:學習

而這篇文章中他們提出了一個方法系統叫做FaceNet,它直接學習圖像到歐式空間上點的映射,其中呢,兩張圖像所對應的特徵的歐式空間上的點的距離直接對應着兩個圖像是否類似。測試

 

                        圖1優化

      這是一個簡單的示例,其中圖中的數字表示這圖像特徵之間的歐式距離,能夠看到,圖像的類內距離明顯的小於類間距離,閾值大約爲1.1左右。翻譯

實現

這篇文章中,最大的創新點應該是提出不一樣的損失函數,直接是優化特徵自己,用特徵空間上的點的距離來表示兩張圖像是不是同一類。網絡結構以下:blog

              圖2

上圖是文章中所採用的網絡結構,上圖步驟能夠描述爲:

  1.前面部分採用一個CNN結構提取特徵,

  2.CNN以後接一個特徵歸一化(使其特徵的||f(x)||2=1,這樣子,全部圖像的特徵都會被映射到一個超球面上),

  3.再接入一個embedding層(嵌入函數),嵌入過程能夠表達爲一個函數,即把圖像x經過函數f映射到d維歐式空間。

  4.此外,做者對嵌入函數f(x)的值,即值閾,作了限制。使得x的映射f(x)在一個超球面上。

  5.接着,再去優化這些特徵,而文章這裏提出了一個新的損失函數,triplet損失函數(優化函數),而這也是文章最大的特色所在。

 Triplet Loss(三元組損失函數):

如下是Triplet損失函數的原理(Triplet翻譯爲三元組):

思想:

   什麼是Triplet Loss呢?故名思意,也就是有三張圖片輸入的Loss(以前的都是Double Loss或者是    SingleLoss)。

    本文經過LDA思想訓練分類模型,使得類內特徵間隔小,類間特徵間隔大。爲了保證目標圖像 與類內圖片(正樣本)特徵距離小,與類間圖片(負樣本)特徵距離大。須要Triplet損失函數來實現。

根據上文,能夠構建一個約束條件:

把上式寫成損失(優化)函數,經過優化(減少)損失函數的值,來優化模型。損失函數爲:

 

Triplet Selection(generate)

  在上面中,若是嚴格的按照上式來進行學習的話,它的T(窮舉全部的圖像3元組)是很是大的。
       舉個例子:在一個1000我的,每人有20張圖片的狀況下,其T=(1000*20)*19*(20*999)(總圖片數*每一個圖片類內組合*每一個圖片類間組合),也就是O(T)=N^2 ,因此,窮舉是不大現實的。那麼,咱們只能從這全部的N^2箇中選擇部分來進行訓練。如今問題來了,怎麼從這麼多的圖像中挑選呢?答案是選擇最難區分的圖像對。

給定一張人臉圖片,咱們要挑選:
    1.一張hard positive:即在類內的另外19張圖像中,跟它最不類似的圖片。(正樣本里面最差的樣本)
    2.一張hard negative:即在類間的另外20*999圖像中,跟它最爲類似的圖片。(負樣本里面最差的樣本)
    挑選hard positive 和hard negative有兩種方法,offline和online方法,具體的差異只是在訓練上。


問題描述:爲了確保模型快速收斂,選擇違反公式1的約束條件的三元組(損失函數的負樣本,與前面的類間圖片表示的「負樣本」不同)是相當重要的。這意味着給定,咱們須要:

   1.選擇一個,使得

   2.選擇一個,使得 

 

解決方案:

在整個訓練集上尋找argmax和argmin是困難的。若是找不到,會使訓練變得困難,難以收斂,例如錯誤的打標籤和差勁的反映人臉。所以須要採起兩種顯而易見的方法避免這個問題:

  1.離線更新三元組(每隔n步)。採用最近的網絡模型的檢測點 並 計算數據集的子集的argmin和argmax(局部最優)。

  2.在線更新三元組。在mini-batch上 選擇很差的正(類內)/負(類間)訓練模型。(一個mini-batch能夠訓練出一個子模型)

  本文中採用上述第二種方法。本文中,採用如下方法:

       1.使用大量 mini-batch,從而獲得幾千個很差的訓練模型。

       2.計算mini-batch上的argmin和argmax。

 總結:以上全部過程博主歸納爲:爲了快速收斂模型-->須要找到訓練的很差的mini-batch上的差模型(負樣本)-->從而找到 不知足約束條件/使損失增大 的三元組

 

在本文中,訓練集的每一個mini-batch包含:

1. 每一個身份的40我的臉

2. 隨機放一些負樣本人臉

 

實際採用方法:

1.採用在線的方式 (做者說,在線+不在線方法結果不肯定)

2.在mini-batch中挑選全部的anchor positive 圖像對 (由於實際操做時,發現這樣訓練更穩定)

3.依然選擇最爲困難的anchor negative圖像對 (能夠提早發現很差的局部最小值)

 特殊狀況:

選擇最爲困難的負樣本,在實際當中,容易致使在訓練中很快地陷入局部最優,或者說整個學習崩潰f(x)=0 //我在CNN學習的時候也常常會遇到這個問題,不過個人是f(x)=1。爲了不這個問題,在選擇negative的時候,使其知足式(3):

左邊:Positive pair的歐式距離右邊:negative pair的歐式距離。把這一個約束叫做semi-hard (半序關係)。由於雖然這些negative pair的歐式距離 遠小於 Positive pair的歐式距離,可是 negative pair的歐式距離的平方 接近於Positive pair的歐式距離的平方。

深度網絡結構

最優化算法: 

1. SGD+標準BP

2. AdaGrad

起始的學習率:0.05 (以後逐漸遞減,直到模型收斂)

訓練時間:在cpu集羣上訓練1000-2000 h,從500 h開始,loss大幅減小。

參數:設置爲0.02

網絡結構:(均使用修正的線性單元做爲非線性激活函數)


1. 左邊是ZF-Net。原文描述以下:

步長不爲1的時候,輸入維數又很大的時候,該怎麼計算,通過本身的研究得出公式(池化也是同樣計算):
input_size: 輸入維數大小
filter_size: 卷積核大小
stride: 步長
feature map = [(input_size - filter_size+ stride) /stride]  ;;上取整,邊界不丟棄(加上一個stride再除以stride,由於最後1次滑動也算入)

輸入層:224*224像素,3顏色通道

1st隱藏層:卷積。每一個顏色通道96個濾波器,大小7*7,x和y方向上的步長均爲2。卷積獲得110*110的特徵圖( 特徵圖邊長=(224-7+2)/2)--> 通過 一個修正的線性單元(Relu, 圖中未顯示)-->池化。3*3的最大池化,x和y方向上的步長均爲2。池化獲得50*50的特徵圖( 特徵圖邊長=(110-3+2)/2) )

BN層:對比和歸一化這96個特徵層

2345層:原理同上

67層:全鏈接層,把第5層的特徵圖轉化成一維向量。

8層:softmax層,把輸出值歸一化( soft(軟化)+max(最大值歸1,其他歸0) )

2.右邊是GooLeNet。層數更多,參數更少。網絡結構以下:

 

 

對上圖作以下說明:
1 . 顯然GoogLeNet採用了模塊化的結構,方便增添和修改;
2 . 網絡最後採用了average pooling來代替全鏈接層,想法來自NIN,事實證實能夠將TOP1 accuracy提升0.6%。可是,實際在最後仍是加了一個全鏈接層,主要是爲了方便之後你們finetune;
3 . 雖然移除了全鏈接,可是網絡中依然使用了Dropout ;
4 . 爲了不梯度消失,網絡額外增長了2個輔助的softmax用於向前傳導梯度。文章中說這兩個輔助的分類器的loss應該加一個衰減係數,但看caffe中的model也沒有加任何衰減。此外,實際測試的時候,這兩個額外的softmax會被去掉。

 

下面是文中實驗用到的一些網絡模型:

NN1:ZF-Net(Zeiler&Fergus),在前幾個卷積層中加入了1*1*d的卷積層,有效的減少了參數的個數。但和GoogleNet相比,參數量仍是很大。

 

NN2:GooleNet。如圖6。與原模型主要區別在於:
1.使用的是L2池化而不是max池化。

2.池化的卷積核大小通常是3*3(除了最後那個平均池化),而且並行於每一個輸入模塊裏的卷積模塊。

若是在1*1,3*3,5*5池化後有維度降低,那麼把它們鏈接起來做爲最後的輸出。

 

NNS1:剪裁後的GooleNet。爲了使得模型能夠嵌入到移動設備中,本文中也對模型進行了裁剪。NNS1即只須要26M的參數和220M的浮點運算開銷。

 

NNS2:剪裁後的GooleNet。NNS2則只有4.3M的參數和20M的浮點運算量。

 

NN3:GooleNet。與NN2結構同樣,但輸入圖片大小隻有160*160。這樣極大幅度的下降了對CPU的需求。

 

NN4:GooleNet。與NN2結構同樣,但輸入圖片大小隻有96*96。這樣極大幅度的下降了對CPU的需求。

相關文章
相關標籤/搜索