深度學習(十七)基於改進Coarse
基於改進Coarse-to-fine CNN網路的人臉特徵點定位
原文地址:http://blog.csdn.net/hjimce/article/details/50099115
作者:hjimce
一、相關理論
本篇博文主要講解2013年face++的大牛們提出粗到精人臉特徵點定位演算法paper:《ExtensiveFacialLandmarkLocalizationwithCoarse to fineConvolutionalNetworkCascade》,發表於2013年ICCV上的一篇用於定位多個人臉特徵點的文獻,實現了68個人臉特徵點的高精度定位。這篇paper沒有給出訓練數據,也沒有給出測試模型、源代碼等,所以源代碼需要自己寫,訓練數據我們需要自己到IBUG網站下載,可以下載到兩千多張的訓練數據,這篇paper的代碼花了我兩周的時間,主要是裁一些細節方面很麻煩。
我個人感覺這篇文章的創新點不是很大,基本上是在文獻:《Deep Convolutional Network Cascade for Facial Point Detection》的基礎上做了一點點的修改,使得我們構建的CNN模型可以用於定位更多的特徵點,總結為一句話就是如果想要看懂這篇文獻,還是建議先好好學習paper:《Deep Convolutional Network Cascade for Facial Point Detection》,熟悉代碼是怎麼實現的,然後再來搞這篇文章的演算法,就只需要改一改就OK了。
人臉68特徵點的定位方法,也是採用了從粗到精的定位思想,網路屬於DCNN,開始講解這篇paper之前,我先講解一下文獻的創新點,因為如果你已經熟悉了《Deep Convolutional Network Cascade for Facial Point Detection》的演算法,我們只要把創新點抓住,就OK了。本篇給我的感覺最大的創新點在於:在網路的輸入方面,不是用人臉檢測器檢測到的人臉區域圖片作為網路的輸入,而是採用CNN預測人臉的bounding box,這個改進對初始level定位精度提高非常多,如下圖所示,當我們輸入一張圖片的時候,我們用CNN,分別預測出Innerpoints和Contourpoints的最小包圍盒:
切記:上面的兩個部分的特徵點預測是完全分開的,各自的網路可以進行並行訓練、預測。就像上面,兩部分的分開預測,第一層次的目的都是為了獲得BoundingBox。
雖然文獻還提出了一些其它方面的細節,但是我感覺基本上對精度影響都不大,比如文獻最後在預測inner point的時候,還多了一個層次網路level 4(對總精度提高非常小,後面再講解),如果你僅僅是為了學習這個演算法的話,完全可以不用level 4,當然如果你要實現最高的精度(用於商用),就要把老老實實根據文獻的演算法,一步一步來了。好了,言歸正傳,下面開始講解paper演算法。在這篇paper的演算法中,被預測的68個人臉特徵點分為兩個部分。
第一部分:主要是人臉五官的特徵點預測,這部分預測點的個數為51,在文獻中又把這部分特徵點命名為:Innerpoints,貌似文獻中並沒有顯示51個點,如下圖所示:
第二部分:用於預測人臉外輪廓的17個特徵點。我們又稱之為:Contourpoints ,請記住Contourpoints和Innerpoints這兩個名詞指的是哪部分特徵點,我後面都使用這兩個詞進行講解。
Innerpoints和Contourpoints這兩部分相互獨立,用不同的網路結構進行預測,也就說這兩部分可以並行計算,其中contour point的預測比較簡單,paper的大部分精力都花在講解inner points 上面,演算法也都是講解inner points,因為inner points是五官特徵點的位置,定位比較複雜,所以才要花費更多的精力去提高精度。
一、Innerpoints預測
Innerpoints的預測是一個四層次的DCNN模型。level 1就是我們前面講的預測bounding box;level 2 用於這51個點的初始定位,也就是粗定位;level 3 用於精定位;level 4 用於更精定位(這一層次對精度提高很小)。
第一層次(level 1):這個就是我們上面講的預測最小包圍盒。輸入一張完整的圖片,我們通過這一層CNN,預測這51個點的最小包圍盒(BoundingBox)。Boundingbox包含矩形左上角的坐標、右下角的坐標,也就是網路的輸出是一個4維的向量:
輸入 輸出
第一層次
第二層次(level 2):網路的輸入,就是我們通過第一層次預測到的51個點的最小包圍盒中的人臉圖片;網路的輸出是51個特徵點預測位置(粗定位位置)。這一層次比較簡單,說白了就是我們常見的CNN,用普通的CNN預測51個特徵點(當然用這一層預測出來的位置,只能作為初始位置,因為通過這一層預測的精度還不夠高,只能作為51個點的粗定位。我們需要有後面繼續兩個層次網路進行精定位)。
第二層次
網路的輸入:把level1得到的最小包圍盒中的圖片裁剪出來,作為輸入,進行51個點人臉特徵點預測。
網路的輸出:因為我們是要預測51個特徵點,所以CNN的輸出是102神經元。
第三層次(level 3):因為我們上面一層的網路,已經預測到了51個特徵點,然而這51個點的位置還不夠高,我們需要對其做進一步的精定位。
第二層次預測的51個點,之所以精度不夠高,是因為我們輸入的圖片是大的圖片,是對全局的統一預測(具體解釋可以參考文獻《DeepConvolutionalNetworkCascadeforFacialPointDetection》),容易受冗餘信息的干擾。說的簡單一點吧:假設你要定位嘴巴的特徵點,你的輸入圖片就應該只有嘴巴部分的區域圖片,這樣的精度才會比較高,而不是你把一整張人臉圖片作為輸入,這樣冗餘信息太多,容易干擾到我們的嘴巴區域的定位。
因此我們這一層次的網路,就是要利用level2的網路預測到的51個點,把五官的圖片裁剪出來,然後對五官進行分別的定位。具體的示意圖如下:
第三層次
網路輸入:利用level2的51個點,對五官圖片裁剪,把裁剪的五官,進行分開訓練、預測。因為我們要各個器官分開訓練,因此自然而然本層需要有4個CNN模型,每個模型用於預測各自的特徵點
網路輸出:各個器官的特徵點
第四層次(level 4):這一層次的輸入,與文獻《DeepConvolutionalNetworkCascadeforFacialPointDetection》相比,稍稍做了修改。跟我想像的有點不一樣,paper通過把level3的各個五官預測結果,計算各五官的旋轉角度,然後把五官都擺正了,作為第四層次網路輸入圖片,然後在進行預測。
第四層次
這一層網路,對於我們來說可以不去實現,只到level3就好了,這篇paper是為了達到state-off-art所以才增加了level4。其實這一層網路,對精度的提高非常非常小,我們看一下paper的每一層的誤差:
各層次網路的誤差
好好看一下上面這個表格的數據,level2作為初始的預測,驗證誤差是0.051,通過leve3的精定位,誤差減小到了0.0438,也就是說相對精度相當於提高了14%,這一層精度的提高很明顯。然而從level3到level4誤差從0.0438到0.0431,好像性能提高不了多少。因此對於我們如果要用於商用,需要考慮計算時間效率、精度等綜合因素,可以不要採用paper的level4,不划算,精度提高那麼小,計算時間卻增加了相當多。
二、Contourpoints預測
這17個點的預測比較簡單粗暴,就只是兩個層次的DCNN模型,這兩個層次說的簡單一點就是類似上面Innerpoints的第一、二兩個層次網路。
第一層次:這個在前面已經講過了,也就是預測Contourpoints的最小包圍盒(下圖中的底部示意圖)。
第二層次:CNN直接預測這17個特徵點。
這個預測過程,沒有精定位過程。也就是沒有第三、四層次的CNN精定位,一來是因為這些臉龐特徵點的圖片區域比較大,如果加上第三、四層次的話,會比較耗時間;二來是因為paper還沒想到比較好的方法,用於精定位。
總結:總的來說呢,這篇文獻的思想和《DeepConvolutionalNetworkCascadeforFacialPointDetection》的思想是一樣的,看文獻的名字就知道了,是在這篇paper的基礎上,進行改進的一種用於多個特徵點預測的網路結構。因為paper《DeepConvolutionalNetworkCascadeforFacialPointDetection》只預測5個特徵點,於是face++他們就在這篇文獻的基礎上做了改進,使網路結構可以用於很多個特徵點的預測。
從這篇paper的創新方面講:
1、文獻把人臉的特徵點定位,分開成兩個部分了:Inner和Contour兩部分特徵點,進行分開預測
2、在Inner的預測部分,從level2開始把五官裁剪分開,進行精定位。
3、在每個器官的每個特徵點的定位方面,文獻並沒有像《DeepConvolutionalNetworkCascadeforFacialPointDetection》的方法,把每個特徵點的都用獨立的網路進行定位,不然如果按照《DeepConvolutionalNetworkCascadeforFacialPointDetection》的思想,51個特徵點的定位,精定位的每一層次就要有102個CNN模型(因為《DeepConvolutionalNetworkCascadeforFacialPointDetection》文獻每個特徵點的精定位是用了兩個網路進行訓練、預測,然後用兩個網路的輸出作為平均值,所以是102個網路),這樣太耗時間了,萬一我要定位300個特徵點,不得崩潰。因此face++的這篇paper並沒有把每個特徵點分開獨立訓練、預測,僅僅把各個器官分開訓練。
4、多了一個bounding box 層,可以大大提高特徵點粗定位網路的精度。
三、相關細節與原理解釋
採用粗定位到精定位的過程,有很多優點:
1、各個五官分開預測的原因解釋
各個部分分開訓練,這樣網路的損失函數是分開的。這樣做可以提高精度的原因在於:因為網路各個部位特徵點的定位難度不同,或者說定位難度不平衡。比如,contour特徵點的定位比inner特徵點的定位難度大,這個主要是因為人臉外輪廓往往比較模糊、還有受到頭髮等背景因素的干擾,所以人臉的外輪廓的特徵點的定位難度會比較大。這些因素,引起了訓練損失函數各個特徵點嚴重的不平衡,比如比較難定位的contour的特徵點,就會對損失函數,佔用比較大的比重,因此如果我們68個特徵點一起訓練的話,L2損失函數值基本上是contour的特徵點佔用了比較大的比重。所以文獻才採用把inner和contour分開預測,這樣可以避免不平衡問題。
同理,在inner預測部分,把五官的預測都分開。比如因為眉毛的誤差往往會比較大,而眼睛的預測精度就比較高了,這樣把各個器官都分開,不共用一個損失函數,可以避免不平衡問題。
2、採用多層回歸的原因
也就是採用從粗定位到精定位的原因,這個感覺paper解釋的有點不好,可以自己去看一下《DeepConvolutionalNetworkCascadeforFacialPointDetection》文獻的解釋,這裡懶得解釋了。打了一個早上的字,才講解到這邊,心塞……。
3、採用CNN預測boundingbox
相比與直接採用人臉檢測器,進行預測人臉矩形框來說,這個方法比較靠譜。因為採用人臉檢測器檢測到的人臉框,往往包含了太多了無關的背景,會對我們的網路有一定的干擾。另一方面,如果直接採用人臉檢測器,檢測到的人臉有的時候,並不是位於矩形的中心,這樣對結果也會有一定的影響。
四、網路結構及其訓練
OK,到了這裡我們就要講具體的相關實現了。首先我們先做個定義:N1表示為innerpoint各個特徵點的初始位置預測,也就是相當於inner的level2。N2表示為contourpoint點的預測(contour的level2)。
下面是N1的網路結構圖,網路的輸入是60*60大小的圖片:
網路結構方面基本上與傳統的CNN模型,差不多,最大的區別在於locallysharingweights,也就是上面的unsharedconv層,我們平時所遇到的CNN都是globalsharingweights的。但是對於特徵點的預測,五官的高層特徵差別比較大,所以需要在高層採用unsharedweight的方式,在低層採用globalsharingweights。
1、網路訓練:採用隨機梯度下降,同時採用圖片相似變換(旋轉、縮放、平移等),對數據進行擴充,防止過擬合。
2、數據預處理:採用數據歸一化到:均值為0,方差為1,然後採用hyper-tangent函數,把數據映射到-1~1之間。還有就是以上各層,在進行圖片裁剪的時候,需要稍微大一點點,不然當定位稍微不準的時候,直接採用原比例進行裁剪,會把我們想要的部分也可能給剔除掉。
六、演算法試驗
1、boundingboxlevel測試(level1到level2)
為了快速驗證文獻的主要思想、創新點,也就是增加boundingboxlevel層,我對《DeepConvolutionalNetworkCascadeforFacialPointDetection》演算法進行了改進測試,先測試5個特徵點的情況,因為我對文獻《DeepConvolutionalNetworkCascadeforFacialPointDetection》之前已經比較熟悉了,而且代碼也寫過了一遍,所以利用已有的代碼,直接測試本篇paper所提出的boundingboxlevel,看看增加boudingbox層與直接採用人臉檢測器,對各特徵點初始位置預測精度能提高多少?
我根據paper的演算法,進行人臉特徵點定位試驗,只測試了5個特徵點的預測,比較採用boundingboxlevel和facedetector對5個特徵點初始位置預測精度的影響。驗證過程:主要是測試boundingbox層對精度的影響,paper在驗證集上測試誤差,然後與直接採用人臉框檢測的精度預測結果,對人臉特徵點初始預測精度的影響。
(1)直接採用人臉檢測器作為level1
直接採用人臉檢測器作為level1,在我的測試集上,損失誤差如下:
測試過程中,為了簡單起見,暫時沒有使用unsharedweights的、也沒有使用fabs層,直接採用facedetector各特徵點的預測結果(藍色的點代表標準點,紅色點表示利用網路進行預測的點):
紅色的點是預測點,藍色點是手工標定的點
(2)採用boundingboxestimation作為level1
下面是採用boundingbox作為DCNN的level1,最後測試level2預測的精度:
結論:採用boundingbox作為level1,相比於直接採用人臉檢測器作為level1,人臉五官特徵點的初始位置預測,誤差可以減少0.02左右,相對精度相當與提高了26%。相關預測效果(藍色的點代表標準點,紅色點表示利用網路進行預測的點):
精度的提高還是比較明顯的。
2、68個特徵點測試(level2到level3)
因為5個點的訓練數據很多,所以上面一開始我才使用5個點的訓練數據1w張,作了boundingboxlevel層的測試。最後為了測試68個點的情況,我從ibug網站:
http://ibug.doc.ic.ac.uk/resources/300-W/下載了68個點的訓練數據,總共有3k張,我等窮人只能硬著頭皮上,利用3k張做訓練測試。而且我比較懶,數據擴充也只用了360度旋轉,沒有採用鏡像,因為鏡像數據擴充的時候,各個特徵點的序號是要改變的,最討厭這些小細節了(特別是五官的裁剪,然後預測到特徵點後,要重新組合,好心煩),所以乾脆不鏡像了,因為自己一個人要搞這些小細節,實在是很苦逼,很心煩。最後我也沒有使用縮放擴充。(ps:文獻使用了旋轉、鏡像、縮放等數據擴充,而且也不知到用了多少訓練數據圖片),總之窮人的難處,說多了,都是淚啊,啰嗦了這麼多,該繼續搬磚了……。
在第一部分,我已經測試了boundingboxlevel1層對leve2層精度的影響,因此接著我就直接測試從leve2到leve3的粗預測到精定位過程(最後驗證,性能跟文獻說的差不多,提高了15%左右)。
(1)鼻子從粗到細
為了清楚查看從leve2到leve3的精度變化我裁剪出鼻子部位的預測結果,進行比較測試(藍色的點代表標準點,紅色點表示利用網路進行預測的點):
粗定位精定位
試驗1、粗定位&灰度圖像:
試驗2、精定位&灰度圖像&左右expand大小選擇0.3,上下expand選擇0.1
(2)嘴巴從粗到細
試驗1、粗&灰度圖像:
試驗2、細&灰度圖像:
精度反而比粗定位的精度降低了。於是接著我用彩色圖像定位嘴巴,得到如下的試驗
試驗3、細&彩色圖像:
總結:對於嘴巴部位的精度,有可能是訓練數據的原因,最後我是採用彩色圖像作為網路的輸入,提高精度
(3)右眼眼睛從粗到細:
試驗1、粗&灰度圖像:
試驗2、精&灰度圖像:
(4)左眼從粗到細
試驗1、粗&灰度圖像:
試驗2、精&灰度圖像:
(6)左眉毛從粗到細
試驗1、粗&灰度圖像:
試驗2、精&灰度圖像:
(7)51點整體誤差
試驗1、粗&灰度圖像:
試驗2、精&灰度圖像
最後結果:
左邊圖是標準的基準點,右邊是文獻paper演算法的最後預測結果。
參考文獻:
1、《ExtensiveFacialLandmarkLocalizationwithCoarse-to-fineConvolutionalNetworkCascade》
2、《Face Alignment at 3000 FPS via Regressing Local Binary Features》
3、《Deep Convolutional Network Cascade for Facial Point Detection》
4、http://ibug.doc.ic.ac.uk/resources/300-W/
**********************作者:hjimce 時間:2015.11.29 聯繫QQ:1393852684 原創文章,轉載請保留原文地址、作者等信息***************
推薦閱讀:
※著裝可以讓女人比想像中漂亮(深度好文)
※【深度】基督徒的雙十一
※你的背後有人嗎?領導者用人之道(深度)!
※深度心靈
※第四次工業革命——智能機器人深度研究