Coursera吳恩達《卷積神經網絡》課程筆記(4)-- 人臉識別與神經風格遷移

我的CSDN博客地址:紅色石頭的專欄 
我的知乎主頁:紅色石頭 
我的微博:RedstoneWill的微博 
我的GitHub:RedstoneWill的GitHub 
我的微信公衆號:紅色石頭的機器學習之路(ID:redstonewill) 
歡迎大家關注我!共同學習,共同進步!

《Convolutional Neural Networks》是Andrw Ng深度學習專項課程中的第四門課。這門課主要介紹卷積神經網絡(CNN)的基本概念、模型和具體應用。該門課共有4周課時,所以我將分成4次筆記來總結,這是第4節筆記,主要介紹卷積神經網絡的特殊應用:人臉識別與風格遷移。

1. What is face recognition

首先簡單介紹一下人臉驗證(face verification)和人臉識別(face recognition)的區別。

  • 人臉驗證:輸入一張人臉圖片,驗證輸出與模板是否爲同一人,即一對一問題。

  • 人臉識別:輸入一張人臉圖片,驗證輸出是否爲K個模板中的某一個,即一對多問題。

一般地,人臉識別比人臉驗證更難一些。因爲假設人臉驗證系統的錯誤率是1%,那麼在人臉識別中,輸出分別與K個模板都進行比較,則相應的錯誤率就會增加,約K%。模板個數越多,錯誤率越大一些。

2. One Shot Learning

One-shot learning就是說數據庫中每個人的訓練樣本只包含一張照片,然後訓練一個CNN模型來進行人臉識別。若數據庫有K個人,則CNN模型輸出softmax層就是K維的。

但是One-shot learning的性能並不好,其包含了兩個缺點:

  • 每個人只有一張圖片,訓練樣本少,構建的CNN網絡不夠健壯。

  • 若數據庫增加另一個人,輸出層softmax的維度就要發生變化,相當於要重新構建CNN網絡,使模型計算量大大增加,不夠靈活。

爲了解決One-shot learning的問題,我們先來介紹相似函數(similarity function)。相似函數表示兩張圖片的相似程度,用d(img1,img2)來表示。若d(img1,img2)較小,則表示兩張圖片相似;若d(img1,img2)較大,則表示兩張圖片不是同一個人。相似函數可以在人臉驗證中使用:

  • d(img1,img2)τd(img1,img2)≤τ : 一樣

  • d(img1,img2)>τd(img1,img2)>τ : 不一樣

對於人臉識別問題,則只需計算測試圖片與數據庫中K個目標的相似函數,取其中d(img1,img2)最小的目標爲匹配對象。若所有的d(img1,img2)都很大,則表示數據庫沒有這個人。

這裏寫圖片描述

3. Siamese Network

若一張圖片經過一般的CNN網絡(包括CONV層、POOL層、FC層),最終得到全連接層FC,該FC層可以看成是原始圖片的編碼encoding,表徵了原始圖片的關鍵特徵。這個網絡結構我們稱之爲Siamese network。也就是說每張圖片經過Siamese network後,由FC層每個神經元來表徵。

這裏寫圖片描述

建立Siamese network後,兩張圖片x(1)x(1)x(2)x(2)的相似度函數可由各自FC層f(x(1))f(x(1))f(x(2))f(x(2))之差的範數來表示:

d(x(1),x(2))=||f(x(1))f(x(2))||2d(x(1),x(2))=||f(x(1))−f(x(2))||2

值得一提的是,不同圖片的CNN網絡所有結構和參數都是一樣的。我們的目標就是利用梯度下降算法,不斷調整網絡參數,使得屬於同一人的圖片之間d(x(1),x(2))d(x(1),x(2))很小,而不同人的圖片之間d(x(1),x(2))d(x(1),x(2))很大。

  • x(i)x(i)x(j)x(j)是同一個人,則||f(x(1))f(x(2))||2||f(x(1))−f(x(2))||2較小

  • x(i)x(i)x(j)x(j)不是同一個人,則||f(x(1))f(x(2))||2||f(x(1))−f(x(2))||2較大

具體網絡構建和訓練參數方法我們下一節再詳細介紹。

4. Triplet Loss

構建人臉識別的CNN模型,需要定義合適的損失函數,這裏我們將引入Triplet Loss。

Triplet Loss需要每個樣本包含三張圖片:靶目標(Anchor)、正例(Positive)、反例(Negative),這就是triplet名稱的由來。顧名思義,靶目標和正例是同一人,靶目標和反例不是同一人。Anchor和Positive組成一類樣本,Anchor和Negative組成另外一類樣本。

這裏寫圖片描述

我們希望上一小節構建的CNN網絡輸出編碼f(A)f(A)接近f(D)f(D),即||f(A)f(D)||2||f(A)−f(D)||2儘可能小,而||f(A)f(N)||2||f(A)−f(N)||2儘可能大,數學上滿足:

||f(A)f(P)||2||f(A)F(N)||2||f(A)−f(P)||2≤||f(A)−F(N)||2

||f(A)f(P)||2||f(A)F(N)||20||f(A)−f(P)||2−||f(A)−F(N)||2≤0

根據上面的不等式,如果所有的圖片都是零向量,即f(A)=0,f(P)=0,f(N)=0f(A)=0,f(P)=0,f(N)=0,那麼上述不等式也滿足。但是這對我們進行人臉識別沒有任何作用,是不希望看到的。我們希望得到||f(A)f(P)||2||f(A)−f(P)||2遠小於||f(A)F(N)||2||f(A)−F(N)||2。所以,我們添加一個超參數αα,且α>0α>0,對上述不等式做出如下修改:

||f(A)f(P)||2||f(A)F(N)||2α||f(A)−f(P)||2−||f(A)−F(N)||2≤−α

||f(A)f(P)||2||f(A)F(N)||2+α0||f(A)−f(P)||2−||f(A)−F(N)||2+α≤0

順便提一下,這裏的αα也被稱爲邊界margin,類似與支持向量機中的margin。舉個例子,若d(A,P)=0.5d(A,P)=0.5α=0.2α=0.2,則d(A,N)0.7d(A,N)≥0.7

接下來,我們根據A,P,N三張圖片,就可以定義Loss function爲:

L(A,P,N)=max(||f(A)f(P)||2||f(A)F(N)||2+α, 0)L(A,P,N)=max(||f(A)−f(P)||2−||f(A)−F(N)||2+α, 0)

相應地,對於m組訓練樣本,cost function爲:

J=i=1mL(A(i),P(i),N(i))J=∑i=1mL(A(i),P(i),N(i))

關於訓練樣本,必須保證同一人包含多張照片,否則無法使用這種方法。例如10k張照片包含1k個不同的人臉,則平均一個人包含10張照片。這個訓練樣本是滿足要求的。

然後,就可以使用梯度下降算法,不斷訓練優化CNN網絡參數,讓J不斷減小接近0。

同一組訓練樣本,A,P,N的選擇儘可能不要使用隨機選取方法。因爲隨機選擇的A與P一般比較接近,A與N相差也較大,畢竟是兩個不同人臉。這樣的話,也許模型不需要經過複雜訓練就能實現這種明顯識別,但是抓不住關鍵區別。所以,最好的做法是人爲選擇A與P相差較大(例如換髮型,留鬍鬚等),A與N相差較小(例如髮型一致,膚色一致等)。這種人爲地增加難度和混淆度會讓模型本身去尋找學習不同人臉之間關鍵的差異,“盡力”讓d(A,P)d(A,P)更小,讓d(A,N)d(A,N)更大,即讓模型性能更好。

下面給出一些A,P,N的例子:

這裏寫圖片描述

值得一提的是,現在許多商業公司構建的大型人臉識別模型都需要百萬級別甚至上億的訓練樣本。如此之大的訓練樣本我們一般很難獲取。但是一些公司將他們訓練的人臉識別模型發佈在了網上,可供我們使用。

5. Face Verification and Binary Classification

除了構造triplet loss來解決人臉識別問題之外,還可以使用二分類結構。做法是將兩個siamese網絡組合在一起,將各自的編碼層輸出經過一個邏輯輸出單元,該神經元使用sigmoid函數,輸出1則表示識別爲同一人,輸出0則表示識別爲不同人。結構如下:

這裏寫圖片描述

每組訓練樣本包含兩張圖片,每個siamese網絡結構和參數完全相同。這樣就把人臉識別問題轉化成了一個二分類問題。引入邏輯輸出層參數w和b,輸出y^y^表達式爲:

y^=σ(k=1Kwk|f(x(i))kf(x(j))k|+b)y^=σ(∑k=1Kwk|f(x(i))k−f(x(j))k|+b)

其中參數wkwkbb都是通過梯度下降算法迭代訓練得到。

y^y^的另外一種表達式爲:

y^=σ(k=1Kwk(f(x(i))kf(x(j))k)2f(x(i))k+f(x(j))k+b)y^=σ(∑k=1Kwk(f(x(i))k−f(x(j))k)2f(x(i))k+f(x(j))k+b)

上式被稱爲χχ方公式,也叫χχ方相似度。

在訓練好網絡之後,進行人臉識別的常規方法是測試圖片與模板分別進行網絡計算,編碼層輸出比較,計算邏輯輸出單元。爲了減少計算量,可以使用預計算的方式在訓練時就將數據庫每個模板的編碼層輸出f(x)f(x)保存下來。因爲編碼層輸出f(x)f(x)比原始圖片數據量少很多,所以無須保存模板圖片,只要保存每個模板的f(x)f(x)即可,節約存儲空間。而且,測試過程中,無須計算模板的siamese網絡,只要計算測試圖片的siamese網絡,得到的f(x(i))f(x(i))直接與存儲的模板f(x(j))f(x(j))進行下一步的邏輯輸出單元計算即可,計算時間減小了接近一半。這種方法也可以應用在上一節的triplet loss網絡中。

6. What is neural style transfer

神經風格遷移是CNN模型一個非常有趣的應用。它可以實現將一張圖片的風格“遷移”到另外一張圖片中,生成具有其特色的圖片。比如我們可以將畢加索的繪畫風格遷移到我們自己做的圖中,生成類似的“大師作品”,很酷不是嗎?

下面列出幾個神經風格遷移的例子:

這裏寫圖片描述

一般用C表示內容圖片,S表示風格圖片,G表示生成的圖片。

7. What are deep ConvNets learning

在進行神經風格遷移之前,我們先來從可視化的角度看一下卷積神經網絡每一層到底是什麼樣子?它們各自學習了哪些東西。

典型的CNN網絡如下所示:

這裏寫圖片描述

首先來看第一層隱藏層,遍歷所有訓練樣本,找出讓該層激活函數輸出最大的9塊圖像區域;然後再找出該層的其它單元(不同的濾波器通道)激活函數輸出最大的9塊圖像區域;最後共找9次,得到9 x 9的圖像如下所示,其中每個3 x 3區域表示一個運算單元。

這裏寫圖片描述

可以看出,第一層隱藏層一般檢測的是原始圖像的邊緣和顏色陰影等簡單信息。

繼續看CNN的更深隱藏層,隨着層數的增加,捕捉的區域更大,特徵更加複雜,從邊緣到紋理再到具體物體。

這裏寫圖片描述

8. Cost Function

神經風格遷移生成圖片G的cost function由兩部分組成:C與G的相似程度和S與G的相似程度。

J(G)=αJcontent(C,G)+βJstyle(S,G)J(G)=α⋅Jcontent(C,G)+β⋅Jstyle(S,G)

其中,α,βα,β是超參數,用來調整Jcontent(C,G)Jcontent(C,G)Jstyle(S,G)Jstyle(S,G)的相對比重。

這裏寫圖片描述

神經風格遷移的基本算法流程是:首先令G爲隨機像素點,然後使用梯度下降算法,不斷修正G的所有像素點,使得J(G)J(G)不斷減小,從而使G逐漸有C的內容和G的風格,如下圖所示。

這裏寫圖片描述

9. Content Cost Function

我們先來看J(G)J(G)的第一部分Jcontent(C,G)Jcontent(C,G),它表示內容圖片C與生成圖片G之間的相似度。

使用的CNN網絡是之前訓練好的模型,例如Alex-Net。C,S,G共用相同模型和參數。首先,需要選擇合適的層數ll來計算Jcontent(C,G)Jcontent(C,G)。根據上一小節的內容,CNN的每個隱藏層分別提取原始圖片的不同深度特徵,由簡單到複雜。如果ll太小,則G與C在像素上會非常接近,沒有遷移效果;如果ll太深,則G上某個區域將直接會出現C中的物體。因此,ll既不能太淺也不能太深,一般選擇網絡中間層。

然後比較C和G在ll層的激活函數輸出a[l](C)a[l](C)a[l](G)a[l](G)。相應的Jcontent(C,G)Jcontent(C,G)的表達式爲:

Jcontent(C,G)=12||a[l](C)a[l](G)||2Jcontent(C,G)=12||a[l](C)−a[l](G)||2

a[l](C)a[l](C)a[l](G)a[l](G)越相似,則Jcontent(C,G)Jcontent(C,G)越小。方法就是使用梯度下降算法,不斷迭代修正G的像素值,使Jcontent(C,G)Jcontent(C,G)不斷減小。

10. Style Cost Function

什麼是圖片的風格?利用CNN網絡模型,圖片的風格可以定義成第ll層隱藏層不同通道間激活函數的乘積(相關性)。

這裏寫圖片描述

例如我們選取第ll層隱藏層,其各通道使用不同顏色標註,如下圖所示。因爲每個通道提取圖片的特徵不同,比如1通道(紅色)提取的是圖片的垂直紋理特徵,2通道(黃色)提取的是圖片的橙色背景特徵。那麼計算這兩個通道的相關性大小,相關性越大,表示原始圖片及既包含了垂直紋理也包含了該橙色背景;相關性越小,表示原始圖片並沒有同時包含這兩個特徵。也就是說,計算不同通道的相關性,反映了原始圖片特徵間的相互關係,從某種程度上刻畫了圖片的“風格”。

這裏寫圖片描述

接下來我們就可以定義圖片的風格矩陣(style matrix)爲:

G[l]kk=i=1n[l]Hj=1n[l]Wa[l]ijka[l]ijkGkk′[l]=∑i=1nH[l]∑j=1nW[l]aijk[l]aijk′[l]

其中,[l][l]表示第ll層隱藏層,k,k’分別表示不同通道,總共通道數爲n[l]CnC[l]。i,j分別表示該隱藏層的高度和寬度。風格矩陣G[l]kkGkk′[l]計算第ll層隱藏層不同通道對應的所有激活函數輸出和。G[l]kkGkk′[l]的維度爲n[l]cnc[l] x n[l]cnc[l]。若兩個通道之間相似性高,則對應的G[l]kkGkk′[l]較大;若兩個通道之間相似性低,則對應的G[l]kkGkk′[l]較小。

風格矩陣G[l](S)kkGkk′[l](S)表徵了風格圖片S第ll層隱藏層的“風格”。相應地,生成圖片G也有G[l](G)kkGkk′[l](G)。那麼,G[l][S]kkGkk′[l][S]G[l][G]kkGkk′[l][G]越相近,則表示G的風格越接近S。這樣,我們就可以定義出J[l]style(S,G)Jstyle[l](S,G)的表達式:

J[l]style(S,G)=1(2n[l]Hn[l]Wn[l]C)k=1n[l]Ck=1n[l]C||G[l][S]kkG[l][G]kk||2Jstyle[l](S,G)=1(2nH[l]nW[l]nC[l])∑k=1nC[l]∑k′=1nC[l]||Gkk′[l][S]−Gkk′[l][G]||2

定義完J[l]style(S,G)Jstyle[l](S,G)之後,我們的目標就是使用梯度下降算法,不斷迭代修正G的像素值,使J[l]style(S,G)Jstyle[l](S,G)不斷減小。

值得一提的是,以上我們只比較計算了一層隱藏層ll。爲了提取的“風格”更多,也可以使用多層隱藏層,然後相加,表達式爲:

Jstyle(S,G)=lλ[l]J[l]style(S,G)Jstyle(S,G)=∑lλ[l]⋅Jstyle[l](S,G)

其中,λ[l]λ[l]表示累加過程中各層J[l]style(S,G)Jstyle[l](S,G)的權重係數,爲超參數。

根據以上兩小節的推導,最終的cost function爲:

J(G)=αJcontent(C,G)+βJstyle(S,G)J(G)=α⋅Jcontent(C,G)+β⋅Jstyle(S,G)

使用梯度下降算法進行迭代優化。

11. 1D and 3D Generalizations

我們之前介紹的CNN網絡處理的都是2D圖片,舉例來介紹2D卷積的規則:

這裏寫圖片描述

  • 輸入圖片維度:14 x 14 x 3

  • 濾波器尺寸:5 x 5 x 3,濾波器個數:16

  • 輸出圖片維度:10 x 10 x 16

將2D卷積推廣到1D卷積,舉例來介紹1D卷積的規則:

這裏寫圖片描述

  • 輸入時間序列維度:14 x 1

  • 濾波器尺寸:5 x 1,濾波器個數:16

  • 輸出時間序列維度:10 x 16

對於3D卷積,舉例來介紹其規則:

這裏寫圖片描述

  • 輸入3D圖片維度:14 x 14 x 14 x 1

  • 濾波器尺寸:5 x 5 x 5 x 1,濾波器個數:16

  • 輸出3D圖片維度:10 x 10 x 10 x 16

更多AI資源請關注公衆號:紅色石頭的機器學習之路(ID:redstonewill) 
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章