1. 程式人生 > >TensorFlow 人臉識別網路與對抗網路搭建

TensorFlow 人臉識別網路與對抗網路搭建

640.gif?wxfrom=5&wx_lazy=1

本文來自作者滄夜 在 GitChat 上分享「TensorFlow 人臉識別網路與對抗網路搭建」,閱讀原文」檢視交流實錄

文末高能

編輯 | 嘉仔

寫在前面的話

本次文章坑挖的有些大,有些很不好寫,想了想其實人臉識別網路大約也是一個簡單的前饋神經網路。

但是這麼說又沒有神祕感,要是要用RNN模型又有些高射炮打蚊子。所以準備介紹介紹人臉識別是怎麼回事。

這裡掛一漏萬,從人臉監測開始,那麼什麼是人臉檢測呢:

人臉識別任務

其實總結起來人臉識別工作可以分為幾個部分人臉檢測(detection),人臉校準(aliment),人臉識別(recognise)。

還記得手機照相過程那個小框框吧,那個就屬於人臉檢測,有個非常有名的是MTCNN,名字比較唬人,其實就是三個簡單的卷積神經網路綜合起來的。

第一個用於大致確定人臉的位置,第二三個用於精確的識別、定位人臉。這是一種效率與精度兼顧的方式,因為第一層網路引數量少,計算速度快,識別後把人臉截出來需要做精確處理的時候再去多加點引數。

人臉識別recognise的話這個就複雜了,就是通過圖片和視訊去鑑別不同的人。這個需要更細節的一些東西,相比較而言應用範圍也廣得多,比如用來識別身份證上不同的人,比如某個AI智障機器人用來提供個性化服務。從人臉監測開始:

MTCNN

這個部分的內容可以看文章《Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks 》,同時還有兩張轉瘋了的照片在

這裡(https://zhuanlan.zhihu.com/p/28988009),我就不轉圖了,防止有些只看圖的人說我抄襲。

有些英語不好的人將其叫做MTCNN。第一層網路叫PNet,這個網路主要的作用就是監測人臉是否存在整個網路沒有識別特徵,來看下訓練集:

0?wx_fmt=png

大體上就是一些人臉,是不是感覺圖片很小?因為只有畫素,當然還有負面樣本,就是不是人頭像的,用來判別,都說現在的機器學習是在模仿人的認知。

但是我作為人,感覺還是看不清,所以機器識別起來也會有困難,但是引數少速度快。

這個loss函式選取平平無奇,對於是否為人臉選擇的函式為交叉熵,而對於人臉的 box 和 landmark 則用點的距離或者說二範數來表示。

這三個函式在訓練過程中所對應的權值是不同的,PNet、RNet中權值比較低,而最後一個ONet中的權值進行了提高。這個意思是ONet中更側重於人臉特徵點的識別。

第一層網路之後形成的圖片,為避免侵權用新聞圖片來看一看,選取尊敬的三胖領袖:

0?wx_fmt=png

可以看到效果很明顯,每個人臉都識別出來了,這個是做後續處理的基礎,也就是不漏報。

你第一層就有幾個人臉沒有拾取到是不行的,後續只能越來越少。但是出現了一個嚴重的問題就是膝蓋也被識別成了人臉。

之於膝蓋為什麼會被識別成人臉,用下圖解釋一下:

0?wx_fmt=png

還有一個小的問題就是,人臉框框太多了,這個稍後說。

主要是第一層網路做的太大概了,精確度不高,所以產生了畫素的CNN網路,這也是一個多層的神經網路,但是自由引數資料更多一些,所以錯誤率會降低,這層中開始出現了全連結網路,所以不能處理任意大小圖片,需要利用 PNet 所擷取的圖片:

0?wx_fmt=png

可以看到絕大部分膝蓋的錯誤預測已經沒有了。剩下的一個手那個地方的可信度也不高。再來看看比較像人臉的膝蓋:

0?wx_fmt=png

沒有什麼問題,錯誤判斷已經消失了,同時還把左上角的小女哈標註了出來。

這時候框框減少了,其實上一步之中也有這個操作,就是極大值抑制(NMS)這種方式來約束框的數量,這個是在物體識別和人臉識別中的常用演算法,通俗說法是從重疊的裡找一個最好的。

具體的演算法步驟是首先從堆疊的框中按照概率從大到小排序,從第一個開始,如果之後box的重疊面積與前一個超過一個設定值,那麼就把其從box序列中刪掉。之後再從box序列(刪減後)中選擇第二個重複上面的過程,通過這個過程來合併人臉識別的框(box)。

還有一個小的補充,在識別過程中由於人臉大小不一樣,但是我們的MTCNN網路結構要求人臉大小不能有太大的變化,因此對於圖片需要進行多個尺度的變換,這個圖節選自維基百科)體面的人都會給出引文地址。

0?wx_fmt=png

到此為止,內容已經介紹的差不多了,還差最後一步,直接輸出最終結果,這個是通過所謂的ONet,其實它依然是一個比較淺的卷積神經網路。但是最後一層為一個全連結層。

這個全連結層使得無法如第一個全卷積神經網路那樣來處理任意大小的圖片(用現有庫的話肯定不成),來看看最終的結果:

0?wx_fmt=png

由於圖片人臉清晰,使得識別效果很好,不重不漏,再來一張:

0?wx_fmt=png

這個是一個比賽的圖片,可以看到帶了眼鏡的也能識別,同時對於一些模糊的人臉也較好的進行了識別。可以說MTCNN這種結構對於人臉識別來說還是挺成功的。

深度網路

前面 MTCNN 的結構已經可以對拾取圖片中的人臉了,那麼接下來的工作就是區分每個臉是誰,這就是所說的 recognise。

當然我們需要用到 MTCNN 所擷取的人臉。用於人臉ID這個網路就複雜了,因為網路層數很多,常用的一些結構包括 Inception,ResNet 都是一種很深的網路結構,而 TensorFlow 包含一個 Inception 網路實現:

Conv2d_1a_3x3 Conv2d_2a_3x3 Conv2d_2b_3x3 MaxPool_3a_3x3 Conv2d_3b_1x1 Conv2d_4a_3x3 MaxPool_5a_3x3 Mixed_5b Mixed_5c Mixed_5d Mixed_6a Mixed_6b Mixed_6c Mixed_6d Mixed_6e Mixed_7a Mixed_7b Mixed_7c

這個mix代表一系列網路結構的綜合,之於文章在這裡(https://arxiv.org/pdf/1512.00567.pdf),有興趣的可以翻閱。可以用tensorboard點開一個節點看看:

0?wx_fmt=png

大概就是一系列卷積之後再來個連線,把每個卷積層學到的都留著繼續處理。

輸出是一個幾百個長度的向量谷歌的facenet的向量長度是128,整個過程類似於將一個圖片壓縮成一個定長的向量,這是一個資訊壓縮的過程,如果兩張人臉的向量二範數很小的話那麼就說明很大可能是同一個人臉。

具體例子就不演示了,訓練起來實在是挺麻煩。當然實現並不麻煩 TensorFlow 已經實現了,麻煩是資料尋找和處理,網上開源資料庫一大堆,資料量不大幾百萬個圖片吧。

GAN

這是附加內容

最後來聊聊老夫感覺挺神奇的一個應用就是對抗生成網路,有些英語不好的人喜歡叫GAN網路,這個網路結構並不複雜,但是可以完全用神經網路來生成圖片。

也就是給一些隨機數列,自動生成需要的圖片,當然可以用來開車,這完全取決於你的猥瑣程度。
這個網路中很重要的一個函式就是:

tf.nn.conv2d_transpose

執行的作用與卷積相反,傳統卷積是這樣的:

0?wx_fmt=gif

反捲積是這樣:

0?wx_fmt=gif

這兩張圖片都節選自開源專案(https://github.com/vdumoulin/conv_arithmetic)體面人抄襲都會給連結。簡單點說就是把一張圖片畫素數提高了。

有些宅用這些函式可以畫漫畫:

0?wx_fmt=png

還發了文章,文章名字叫:Learning to Simplify: Fully Convolutional Networks for Rough Sketch Cleanup。圖片就是節選自這個文章。

接著說我們的GAN網路,其分為兩個部分,第一部分為生成器,第二部分為判別器:生成器用於生成圖片以騙過判別器,而判別器用於判別圖片是否為生成器所生成,於是二人產生了一種博弈。

生成器將隨機噪聲生成圖片,用到的就是 conv2d_transpose 函式。其實可以看成是判別器網路倒過來,而判別器是幾層卷積網路,最後有一個輸出,當圖片是真實圖片輸出1,當為生成器生成的圖片輸出為0。

最後來看一看結果:

0?wx_fmt=png

效果還可以,但是給多個標籤,神經網路就會懵逼:

0?wx_fmt=png

比如同時給了兩個標籤2,3就會這樣。其實可以看成2、3兩個數字的合體。

 近期熱文

GitChat 與 CSDN 聯合推出

《GitChat 達人課:AI 工程師職業指南》

0?wx_fmt=jpeg

「閱讀原文」看交流實錄,你想知道的都在這裡