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

紅色石頭發表於2018-08-02

《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)\leq \tau : 一樣
  • d(img1,img2)> \tau : 不一樣

對於人臉識別問題,則只需計算測試圖片與資料庫中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^{(2)}的相似度函式可由各自FC層f(x^{(1)})f(x^{(2)})之差的範數來表示:

d(x^{(1)},x^{(2)})=||f(x^{(1)})-f(x^{(2)})||^2

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

  • x^{(i)}x^{(j)}是同一個人,則||f(x^{(1)})-f(x^{(2)})||^2較小
  • x^{(i)}x^{(j)}不是同一個人,則||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(D),即||f(A)-f(D)||^2儘可能小,而||f(A)-f(N)||^2儘可能大,數學上滿足:

||f(A)-f(P)||^2\leq ||f(A)-F(N)||^2

||f(A)-f(P)||^2-||f(A)-F(N)||^2\leq 0

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

||f(A)-f(P)||^2-||f(A)-F(N)||^2\leq -\alpha

||f(A)-f(P)||^2-||f(A)-F(N)||^2+\alpha \leq 0

順便提一下,這裡的\alpha也被稱為邊界margin,類似與支援向量機中的margin。舉個例子,若d(A,P)=0.5\alpha=0.2,則d(A,N)\geq0.7

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

L(A,P,N)=max(||f(A)-f(P)||^2-||f(A)-F(N)||^2+\alpha,\ 0)

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

J=\sum_{i=1}^mL(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,N)更大,即讓模型效能更好。

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

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

5. Face Verification and Binary Classification

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

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

\hat y=\sigma(\sum_{k=1}^Kw_k|f(x^{(i)})_k-f(x^{(j)})_k|+b)

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

\hat y的另外一種表示式為:

\hat y=\sigma(\sum_{k=1}^Kw_k\frac{(f(x^{(i)})_k-f(x^{(j)})_k)^2}{f(x^{(i)})_k+f(x^{(j)})_k}+b)

上式被稱為\chi方公式,也叫\chi方相似度。

在訓練好網路之後,進行人臉識別的常規方法是測試圖片與模板分別進行網路計算,編碼層輸出比較,計算邏輯輸出單元。為了減少計算量,可以使用預計算的方式在訓練時就將資料庫每個模板的編碼層輸出f(x)儲存下來。因為編碼層輸出f(x)比原始圖片資料量少很多,所以無須儲存模板圖片,只要儲存每個模板的f(x)即可,節約儲存空間。而且,測試過程中,無須計算模板的siamese網路,只要計算測試圖片的siamese網路,得到的f(x^{(i)})直接與儲存的模板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)=\alpha \cdot J_{content}(C,G)+\beta \cdot J_{style}(S,G)

其中,\alpha,\beta是超引數,用來調整J_{content}(C,G)J_{style}(S,G)的相對比重。

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

9. Content Cost Function

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

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

然後比較C和G在l層的啟用函式輸出a^{[l](C)}a^{[l](G)}。相應的J_{content}(C,G)的表示式為:

J_{content}(C,G)=\frac12||a^{[l](C)}-a^{[l](G)}||^2

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

10. Style Cost Function

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

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

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

G_{kk’}^{[l]}=\sum_{i=1}^{n_H^{[l]}}\sum_{j=1}^{n_W^{[l]}}a_{ijk}^{[l]}a_{ijk’}^{[l]}

其中,[l]表示第l層隱藏層,k,k’分別表示不同通道,總共通道數為n_C^{[l]}。i,j分別表示該隱藏層的高度和寬度。風格矩陣G_{kk’}^{[l]}計算第l層隱藏層不同通道對應的所有啟用函式輸出和。G_{kk’}^{[l]}的維度為n_c^{[l]} x n_c^{[l]}。若兩個通道之間相似性高,則對應的G_{kk’}^{[l]}較大;若兩個通道之間相似性低,則對應的G_{kk’}^{[l]}較小。

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

J^{[l]}_{style}(S,G)=\frac{1}{(2n_H^{[l]}n_W^{[l]}n_C^{[l]})}\sum_{k=1}^{n_C^{[l]}}\sum_{k’=1}^{n_C^{[l]}}||G_{kk’}^{[l][S]}-G_{kk’}^{[l][G]}||^2

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

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

J_{style}(S,G)=\sum_l\lambda^{[l]}\cdot J^{[l]}_{style}(S,G)

其中,\lambda^{[l]}表示累加過程中各層J^{[l]}_{style}(S,G)的權重係數,為超引數。

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

J(G)=\alpha \cdot J_{content}(C,G)+\beta \cdot J_{style}(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資源請關注公眾號:AI有道(ID:redstonewill)

相關文章