1. 程式人生 > >《Deep Convolutional Network Cascade for Facial Point Detection》復現

《Deep Convolutional Network Cascade for Facial Point Detection》復現

 1.引言

       鏘鏘鏘,好久不見,我又肥來了,前一段時間上網找資料的時候偶然發現一篇關於人臉關鍵點檢測的文章,應該說這篇論文是關鍵點檢測的看山鼻祖,論文主頁:http://mmlab.ie.cuhk.edu.hk/archive/CNN_FacePoint.htm,一篇中文翻譯的部落格:基於DCNN的人臉特徵點定位。我大概看了一遍發現這個論文的思路對我有很大的幫助,同時整體神經網路結構的搭建也不算太複雜,因此決定將論文復現一下看看效果,同時我對論文提出的網路也進行了一點細微的修改,但是中間有點事所以這個計劃在進行了一半後就擱淺了,直到這幾天才將後續的部分完成,讓我們一起看一看實現的過程。

       我的訓練環境是使用Python3.6,Tensorflow—gpu,CUDA9.1,CUDNN7版本,每個網路進行1000epoch訓練,最終訓練效果如下圖所示,紅色點是網路預測的座標點,藍色點為資料集中給出的座標點,該網路的預測效果相對來說還是可以的,但是在嘴角部分的預測還有一定差距。

2.網路結構

       論文提出的網路整體思想是將網路分為兩個模組,第一模組是通過適應openCV、faster rcnn或者訓練的其他網路將原始圖片裁剪出人臉部分用作第二模組關鍵點檢測的資料,由於我使用的是Kaggle上提供的人臉關鍵點定位資料集,因此我沒有使用第一模組,如果需要使用第一模組我個人推薦使用openCV進行人臉的裁剪,因為我們在第一步僅需要將人臉大致範圍進行提取,結果中只要包含人臉關鍵區域即可,沒有必要專門搭建一個其他網路進行定位;第二模組又分為3個‘層級’,第一層對圖片關鍵點進行粗定位,第二層在第一層的基礎上對圖片進行細定位,第三層在第二層的基礎上進行精細定位。接下來對三個層級進行講解。(預設英文五官對應單詞首字母代表對應點的網路)

2.1第一層級

        第一層級有三個網路構成,一個全臉卷積,一個眼睛鼻子卷積,一個鼻子嘴角卷積,第一層最後檢測的左眼、右眼、鼻子、左嘴角以及右嘴角的座標有上述三個網路結果取平均後得出,比如鼻子在三個網路中都包含結果就將三個網路預測的鼻子座標相加除以三,類似的眼睛和嘴巴分別為兩個網路結果相加取平均,下圖是第一個F網路,整張人臉檢測的結構圖,可以發現原論文使用的是四個卷積層+兩個全連線層,在我實現的過程中改為了三個卷積層+一個Dropout層+一個全連線層;後兩個EN網路和NM網路結構和次類似,只是最後的全連線層維度不同。

2.2第二層級

       第二層級共有十個網路,分別為LE、RE、N、LM和RM五個網路,每個網路實現兩次,用以最後的取平均減小誤差,在這一層網路的結構由第一層的四個卷積變為兩個卷積層,論文給出的結構式兩個卷積層+兩個全連線層,相應的我的結構改為兩個卷積層+一個Dropout層+一個全連線層,值得注意的是這一層在輸入資料時需要依據第一層粗定位的座標點對原始影象進行裁剪,LE網路輸入為圖片的左眼,RE網路輸入的是圖片的右眼依此類推。

2.3第三層級

       第三層網路和第二層的網路結構保持一致,經過前兩層的訓練提取出的座標點已經有一定精度了,在第三層中我們依據第二層檢測的座標點進行裁剪輸入到第三層十個進行最後的精細預測,或許你會有疑問這樣看起來第二層和第三層沒有什麼區別,是否可以取消第三層?首先經過前兩輪提取在第三層裁剪的區域肯定與第二層的區域是不同的,相對來說第三層裁剪時我們期望的座標點在裁剪區域中心的概率很大,其次在第三層中裁剪的時候要比第二層裁剪的區域更加小,比如說嘴角的裁剪,在第二層有可能輸入的左嘴角區域包含嘴巴的一半,但是在第三層輸入的區域將僅僅包含左嘴角的一小塊區域。

3.網路訓練

       此部分可以參考我開頭髮的兩個連結第一個為原始論文主頁,第二個為博主對論文的解析,裡面對此部分都進行了詳細的描述,原文提出的損失函式是下圖形式的對歐式距離除以圖片長度的方式,在我現實時沒有對其取根號,其想法來自adma的思想,在訓練初期網路損失值過大通過取平方加大損失,進而加快網路的擬合速度,但是經過一定程度的迭代後當損失值減小時通過取平方減小損失,進而在反向傳播時小步更新權重。

4.總結

       這篇到這裡就結束了,這次的復現單純就是想玩玩吧,總的來說這篇論文實現起來沒有什麼特別難的地方,復現過程只在第二層第三層訓練時需要座標值的更新踩了一點坑,最後的結果看起來也是挺好的,對於網路的搭建我還有一些其他的想法就不一一細說了,之後再進行改進驗證一下自己的想法。原始碼在我改進之後會放到github上。