1 什么是人臉識別( what is face recognition )
在相關文獻中經常會提到人臉驗證(verification)和人臉識別(recognition)。
verification就是輸入圖像,名字或id,判斷是不是。而人臉識別是輸入圖像,輸出這個人的名字或id。
我們先構造一個准確率高的verification,然后再把它應用到人臉識別中。
2 一次學習( One-shot learning )
假設現在要做一個人臉識別,但是你的數據庫對於每個人只有一張照片,要怎么做?
這個時候可能會覺得怎么可能只有一張照片,你要做人臉識別肯定要有足夠的數據啊,沒數據就去收集啊。
那現在數據庫中對於每個人都有充足的樣本數據,你構建了一個卷積神經網絡,最后用softmax輸出來判斷這個人是數據庫的哪個人,或者都不是。
那么,如果你的數據庫加入了新的人呢,比如說公司入職一批新員工,這要怎么做呢?再收集一波,然后加一批輸出單元然后重新訓練網絡嗎?這似乎不是個好辦法。
在人臉識別中,有一個挑戰就是,你有時只能通過一個樣本學習到是不是這個人,這就是一次學習。
所以我們要學習的是相似度的計算,你的神經網絡要學習的是,輸入兩張圖片,然后輸出這兩張圖片的差異,你希望輸入同一個人的兩張照片后輸出很小的值,而輸入兩個人的照片后輸出很大的值,我們就可以說當兩張圖片的差異小於某個閾值的時候,就預測是同一個人。這就是解決verification的一個可行辦法。
識別任務就是拿輸入的照片和數據庫中的照片做比較,可以產生很多差異值,取最小的差異值,就能從數據庫找到這個人的身份。如果某個人不在數據庫中,那么它跟數據庫中的照片的差異值都會很大。
3 Siamese網絡( Siamese Network )
輸入圖片x1,經過卷積網絡后,在最后一層輸出的128維向量,稱為f(x1)
輸入圖片x2,喂給同樣結構同樣參數的網絡,得到另一個128維向量,稱為f(x2)
最后,如果你相信f(x)能很好地代表輸入的圖片,那么定義差異d 為 f(x1) 和 f(x2)的距離范數,用d作為損失,來訓練這個網絡。
4 三元組損失( triplet loss)
具體如何定義這個表示距離的損失函數呢?
三元指的是我們的網絡要看三種性質人臉,anchor,positive,negative。anchor作為對比的目標,positive表示是和anchor是同一個人,negative表示和anchor不是同一個人。
我們把這三種人簡寫成A, P, N。
我們要做的是 $d(f(A),f(P)) \leqslant d(f(A),f(N))$ 即 $\left \| f(A) - f(P)) \right \|_2^2 \;-\; \left \| f(A) - f(N)) \right \|_2^2 \;\leqslant\; 0$。
這個公式需要改寫一下,有種情況雖然滿足但是不是我們想要的,0-0=0的情況。
為了防止這種情況,我們把公式右邊的0改成一個間隔參數α,這里α是負的。間隔參數拉大了它們之間的差異。
那么可以定義如下的損失函數,為了使損失非負,用了一個max(0, ),這樣優化的目標就是使得圖中綠色框中的差異項為<=0的值,這里的α是正的。
假如你現在有1w張圖片,你現在要做的就是構造出三元組,然后訓練你的算法。
構建訓練集的時候需要注意,A和N如果差異太大的話,這個網絡的分辨能力就會比較弱,所以要選A和N比較像的數據,或者說d(A,P)和d(A,N)要盡量接近,選擇“難訓練”的樣本作為訓練集,這樣網絡才會盡力地去區分N和P,才能訓練出分辨能力強的網絡。
做人臉識別的商業公司,它們一般都用百萬,千萬,億級別的數據來訓練,這么大的數據集並不容易獲得,幸運的是一些公司已經訓練了這些大型的網絡並上傳了網絡模型參數,所以,可以下載別人的預訓練模型來使用。
5 臉部驗證和二分類( Face verification and binary classification )
除了triplet loss還有其它學習參數的方法,讓我們來看看怎么把人臉驗證當作一個二分類問題。
另一個方法是選一對神經網絡,這兩個神經網絡的參數是相同的,輸入兩行圖片,同時計算兩個128維的向量,計算差異作為特征,最后接一層邏輯回歸,做二分類。
有個計算上的技巧,就是對於數據庫已有的人臉,可以先計算出最后一層前的向量,存起來要用的時候直接拿出來用,這樣就不用每次識別的時候又計算一次。
6 深度卷積網絡在學什么( what are deep convNets learning )
假如我們訓練好一個深度卷積網絡,我們在每一層的某個通道(channel)中找到最大激活的9個feature map(不同樣本中找)。然后換一個通道,循環這個過程,找出一堆這樣的圖像。
發現,第一層似乎在尋找一些邊緣,陰影的東西;第二層似乎學習到了更復雜的一些紋理和圖案;
第三層則學到了一些輪胎,形狀,人,還有一些比較難看出來;第四層開始學到了狗,動物的腳,鍾,螺旋狀的圖案;
第五層檢測出了鍵盤,人,眼睛,文本,狗,花;
可以感受到卷積的過程中,提取的特征從簡單到復雜。
7 風格遷移( style transfer )
風格遷移就是把一張圖片的風格和另一張圖片的內容結合,形成新圖片。
風格遷移有三張圖片。一張原始內容圖,content圖,簡稱C。一張原始風格圖,style圖,簡稱S。一張生成的圖片,generated圖,簡稱G。
損失函數分為兩部分,一部分計算C和G的差異,一部分計算S和G的差異,然后用α和β兩個超參來調節兩部分的權重。
實際要做的就是,先隨機生成一張圖片G,然后計算損失,做梯度下降,G就會在內容上越來越接近C,在風格上越來越接近S。
我們用預訓練卷積網絡,比如VGG,將C, S, G分別輸入到3個單獨的VGG網絡中卷積,稱C所在的網絡為C-VGG, S所在的網絡為S-VGG,G所在的網絡為G-VGG。
對於內容損失,取某一層l層,l不會太淺也不會太深,計算C-VGG和G-VGG在這一層的激活值的差異,可以用平方損失。
那么怎么表示風格損失呢?需要稍微解釋一下,風格就是不同通道的相關性。
我們之前將深度卷積到底在做什么的時候,在某層的某個單元取出了9個圖像塊,這9個圖像塊對應一個通道。
如下圖所示,第一個通道,紅色通道對應第2個九宮格,表示紋理;第二個通道,黃色通道對應第二行第一個九宮格,表示橙色的區域。
那么如果說一個圖片中的紋理部分,出現橙色的概率很高,我們就說這兩個通道相關度很高。相關度描述的就是兩個通道同時出現的概率。
定義下風格矩陣,把第1個通道的圖像對應位置的像素乘以自身再相加,得到矩陣的第一行第一列。把第1個通道的圖像和第2個通道的圖像對應位置的像素相乘再相加,得到矩陣的第一行第二列...把第k個通道的圖像和第k'個通道的圖像對應位置的像素相乘再相加,得到矩陣的第k行第k'列...
最后得到nc*nc的矩陣,nc表示通道數。這個矩陣也叫Gram矩陣。下面的F范數,其實就是向量2范數推廣到矩陣的概念。
我們同時對S和G的每一層進行這個運算,然后把結果進行差異計算,算出每一層的差異,然后用w對每層的差異做一個加權和,得到風格損失。
最后把內容損失和風格損失加權和,就得到最終的損失。
8 延伸到一維和三維( 1D and 3D generalizations of models )
之前學的是二維上的卷積,那么在一維和三維上的卷積是怎樣的呢,它們和二維卷積是類似的,可以類推到相似的結果。
對於1維卷積,假設有n個卷積序列,通道數為nc,那么長度為14*nc的原序列,通過n個長度為5*nc的卷積序列的卷積后,得到長度為10*n的序列。
對於3維卷積,假設有n個卷積核,通道數為nc,那么shape為14*14*14*nc的原張量,通過n個shape為5*5*5*nc的卷積張量的卷積后,得到shape為10*10*10*n的張量。
1維卷積一般用於處理序列數據,2維卷積一般用於處理圖像數據,而3維卷積可以用在處理電影視頻的數據,對不同時間點的3d圖像進行處理。