1、One-Shot學習(One-shot learning)
人臉識別所面臨的一個挑戰就是需要解決一次學習問題(one-shot learning problem),這意味著在大多數人臉識別應用中,你需要透過單單一張圖片或者單單一個人臉樣例就能去識別這個人。而歷史上,當深度學習只有一個訓練樣例時,它的表現並不好。
要讓人臉識別能夠做到一次學習,為了能有更好的效果,現在要做的應該是學習Similarity函式。Similarity函式的核心作用是計算兩個輸入(如向量、集合、機率分佈等)之間的相似度,不同的相似度函式適用於不同的場景。常見的相似度函式包括餘弦相似度、歐氏距離、Jaccard相似度等。
上述公式以兩張圖片作為輸入,然後輸出這兩張圖片的差異值。如果輸入同一個人的兩張照片,你希望輸出一個很小的值;如果輸入兩個長相差別很大的人的照片,則希望輸出一個很大的值。在識別過程中,一般設定閾值,它是一個超引數。如果d大於閾值,則預測是兩個不同的人。這是解決人臉驗證的一個可行方法。
我們已經知道函式d是如何工作的,透過輸入兩張照片,它將讓你能夠解決一次學習問題。那麼,下一節中將會學習如何訓練神經網路學會這個函式d。
2、Siamese 網路(Siamese network)
上節中函式d的作用就是輸入兩張人臉圖片,然後輸出相似度。實現這個功能的一個方式就是用Siamese網路。
上圖是常見的卷積網路,輸入圖片x^(1),然後經過卷積層、池化層和全連線層,最終得到特徵向量。假如它有128個數,它是由網路深層的全連線層計算出來的,給這128個數命個名字,f(x^(1)),可以看成是影像x^(1)的編碼。建立一個人臉識別系統的方法就是:如果要比較兩個圖片的話,把第二張圖片x^(2)餵給有同樣引數的神經網路,然後得到一個不同的128維向量。這裡x^(1)和x^(2)僅代表兩個輸入圖片,是任意兩個圖片。
接下來定義d,將x^(1)和x^(2)的距離定義為這兩種圖片編碼之差的範數:
對於兩個不同的輸入,執行相同的卷積神經網路,然後比較它們,這一般叫做Siamese網路架構(Siamese neural network architecture)。下面展示怎麼訓練這個Siamese神經網路。
由於兩個網路有相同的引數,因此就是訓練一個網路。你要做的就是學習引數,如果兩張圖片是同一個人,那兩個編碼的距離就很小;如果是不同的人,編碼距離就大一些。如果你改變這個網路所有層的引數,你會得到不同的編碼結果,你要做的就是用反向傳播(back propagation)來改變這些所有的引數,以確保滿足這些條件。
訓練Siamese網路時,最常用的損失函式是對比損失(Contrastive Loss)或三元組損失(Triplet Loss),下面我們將來學習三元組損失函式。
4、Triplet 損失(Triplet loss)
要想透過學習神經網路的引數來得到優質的人臉圖片編碼,方法之一就是定義三元組損失函式(triplet loss function),然後應用梯度下降。
為了應用三元組損失函式,你需要比較成對的影像。用三元組損失的術語來說,你要做的通常是看一個 Anchor 圖片,你想讓Anchor圖片和Positive圖片(Positive意味著是同一個人)的距離很接近。然而,當Anchor圖片與Negative圖片(Negative意味著是非同一個人)對比時,你會想讓他們的距離離得更遠一點。這就是為什麼叫做三元組損失,它代表你通常會同時看三張圖片(Anchor圖片、Postive圖片和Negative圖片),通常把它們簡寫成A、P、N。
下面來看改如何選擇這些三元組來形成訓練集。
一個問題是如果你從訓練集中,隨機地選擇A、P和N,遵守A和P是同一個人,而A和N是不同的人這一原則。隨機選擇的話約束條件很容易滿足,因為A和N比A和P差別很大的機率很大,這樣網路並不能從中學到什麼。所以要儘可能的選擇難(hard)訓練的A、P和N,使得d(A,P)和d(A,N)很接近,即:
這樣你的學習演算法會竭盡全力使右邊這個式子變大,或者使左邊這個式子變小,這樣左右兩邊至少有一個間隔(margin),並且選擇這樣的三元組還可以增加你的學習演算法的計算效率。因此,只有選擇難的三元組梯度下降法才能發揮作用,使得這兩邊離得儘可能遠。
5、什麼是神經風格遷移?
神經風格遷移(Neural Style Transfer, NST)是一種利用深度學習將兩幅影像的內容和風格融合在一起的技術。具體來說,它能夠將一幅影像的內容與另一幅影像的風格進行結合,生成一幅既保留原圖內容特徵、又具有目標圖風格的影像。
為了描述如何實現神經網路遷移,使用C來表示內容(content)影像,S表示風格(style)影像,G表示生成的影像(generated image)。為了實現神經風格遷移,我們需要知道卷積網路提取的特徵,在不同的神經網路,深層的、淺層的。
6、深度卷積網路學習什麼?
深度卷積網路到底在學什麼?下面將展示一些視覺化的例子,可以幫助我們理解卷積網路中深度較大的層真正在做什麼,這樣有助於理解如何實現神經風格遷移。
圖中展示瞭如何視覺化卷積神經網路(CNN)內部的工作方式,尤其是它的隱藏層如何從輸入影像中學習到特徵。這是基於AlexNet網路的一個例子,研究人員透過檢視神經網路的某些神經元(或稱為“單元”)在處理影像時的啟用情況,幫助我們理解每個神經元到底在學習什麼樣的特徵,透過上圖可看出到這個神經元主要對什麼樣的影像特徵特別敏感,例如可能對某個方向的邊緣、紋理、顏色特別“感興趣”。
從上圖來看,檢測已經有了一些進展,從檢測簡單的事物,比如說,第一層的邊緣,第二層的質地,到深層的複雜物體。
7、代價/成本函式(cost function)
要構建一個神經風格遷移系統,需要為生成的影像定義一個成本函式(cost function),透過最小化成本函式,可以生成你想要的任何影像。
重新描述一下問題:給定一個內容影像C和一個風格圖片S,目標是生成一個新圖片G。為了實現神經風格遷移,定義一個關於G的成本函式J(G)來評判生成影像的好壞,然後使用梯度下降法最小化J(G)來生成新的影像G。定義成本函式的公式如下:
第一部分被稱作內容代價(content cost),這是一個關於內容圖片和生成圖片的函式,它是用來度量生成圖片G的內容與內容圖片C的內容有多相似。第二部分是風格代價函式(style cost),是關於S和G的函式,用來度量圖片G的風格和S的風格的相似度。
如上圖,為了生成一個新影像,要做的是(1)隨機初始化生成影像G,它可能是100×100×3,可能是500×500×3,又或者是任何你想要的尺寸。(2)使用梯度下降法使成本函式J(G)最小化,更新公式:,在這個步驟中,實際上更新的是影像G的畫素值,也就是100×100×3。
看上圖的這個例子。假設你從這張內容圖片(編號1)和風格(編號2)圖片(畢加索畫作)開始,當你隨機初始化G,隨機初始化的生成影像可能就是這張隨機選取畫素的白噪聲圖(編號3)。接下來執行梯度下降演算法,最小化代價函式J(G),逐步處理畫素,這樣慢慢得到一個生成圖片(編號4、5、6),越來越像用風格圖片的風格畫出來的內容圖片。
8、內容代價函式(Content cost function)
我們先定義內容代價函式(content cost function)。
如上圖,(1)用隱含層l來計算內容代價函式,如果l是個很小的數,比如用隱含層1,這個代價函式就會使生成圖片畫素上非常接近內容圖片。然而如果你用很深的層,那麼你就會問,內容圖片裡是否有狗,然後它就會確保生成圖片裡有一個狗。所以在實際中,這個層l在網路中既不會選的太淺也不會選的太深。具體例子裡通常會選擇在網路的中間層,既不太淺也不很深,(2)然後用一個預訓練的卷積模型,可以是VGG網路或者其他的網路也可以。接下來你需要衡量假如有一個內容圖片和一個生成圖片他們在內容上的相似度,(3)我們令這個a^[l][C]和a^[l][G],分別代表這兩個圖片C和G的l層的啟用函式值。(4)如果這兩個啟用值相似,那麼就意味著兩個圖片的內容相似。
衡量兩個啟用值不同或相似的程度用如下公式:
取l層的隱含單元的啟用值,按元素相減,然後取平方,前面可以加上歸一化或者不加,比如1/2。這裡用的符號都是展成向量形式(vectors)的,因此對應元素相減變成了L2範數的平方。然後用梯度下降法來找到影像G,使得隱含層的啟用值和你內容影像的相似。
9、風格代價函式(Style cost function)
學習了內容代價函式之後,我們來了解風格代價函式(style cost function)。
這是一張彩色圖片,現在我們選擇了某一層l(藍色框部分)去為圖片的風格定義一個深度測量(deep measure),接下來將圖片的風格定義為l層中各個通道之間啟用項的相關係數(correlation)。
如上圖,假設有5個通道(channels),這裡用五種顏色表示。一般而言,神經網路中會有許多通道。在第一個通道中含有某個啟用項,第二個通道也含有某個啟用項,於是它們組成了一對數字。同理,可以得到很多數字對(pairs)。
在這裡,這個紅色的通道對應的第2個神經元,它能找出圖片中的特定位置是否含有這些垂直的紋理,而第二個通道(黃色的通道),對應第4個神經元,它可以粗略地找出橙色的區域。
如果我們使用相關係數來描述通道的風格,你能做的就是測量你的生成影像中第一個通道(紅色)是否與第二個通道(黃色)相關,透過測量,你能得知在生成的影像中垂直紋理和橙色同時出現或者不同時出現的頻率,這樣你將能夠測量生成的影像的風格與輸入的風格影像的相似程度。接下來具體講解。
如上圖,對於這兩個影像(風格影像S和生成影像G),需要計算一個風格矩陣(style matrix),說得更具體一點就是用l層來測量風格。其中a^[l]_i,j,k表示隱藏層l中(i,j,k)位置的啟用值,i,j,k分別表示該位置的高度、寬度以及對應的通道數。計算關於l層和風格影像的一個矩陣,即G^[l][S],這是一個n_c*n_c的矩陣,高度和寬度都是l層的通道數。矩陣中的k和k'被用來描述k通道和k'通道之間的相關係數。輸入的風格影像S構成的風格矩陣具體表現為:
備註:用符號i,j表示下屆,對i,j,k位置的啟用值乘以同樣位置的啟用值,然後i和j分別加到l層的高度和寬度。嚴格來說,它是一種非標準的互相關函式(unnormalized cross-covariance),因為沒有減去平均數,而是直接相乘。這是輸入的風格影像構成的風格矩陣,然後對生成影像G做同樣的操作。
風格矩陣就是把圖中各個高度和寬度的啟用項都遍歷一遍,並將k和k'通道中對應位置的啟用項都進行相乘。現在分別從風格影像S和生成影像G得到兩個矩陣。過程見下圖:
最後,上圖所示,將S和G代入到風格代價函式中去計算,得到這兩個矩陣的誤差,這裡用的Frobenius範數,實際上是計算兩個矩陣對應元素相減的平方的和。把這個式子展開,從k和k'開始作差,然後把所有的結果加起來,作者使用了一個歸一化常數(renormalization constant),再在外面加一個平方,一般我們只要將它乘以一個超引數beta就行。
如上圖,最後,這是對l層定義的風格代價函式J^[l],實際上,如果各層都使用風格代價函式,結果會更好,你可把各個層的結果(各層的風格代價函式)都加起來,對每個層定義權重,即額外的(extra)超引數,用lambda^[l]表示。這樣將在神經網路中使用不同的層,包括之前的一些可以測量類似邊緣這樣的低階特徵的層,以及之後的一些能測量高階特徵的層,使得我們的神經網路在計算風格時能夠同時考慮到這些低階和高階特徵的相關係數。這樣,在基礎的訓練中你在定義超引數時,可以儘可能的得到更合理的選擇。
把這些東西封裝起來,就定義了一個全體代價函式:
接著用梯度下降法或者其他最佳化演算法來尋找合適的影像G,並計算J(G)的最小值,這樣將能夠得到非常好看的結果。