簡化版mtcnn--復現過程詳解

這篇博客記錄了我復現mtcnn的理論流程,相關處理(nms及iou等)操作可見本專欄,時間有限只用了邊框迴歸,人臉關鍵點沒有考慮,過些天再加上一波,代碼待整理之後放上。
人臉檢測旨在解決兩個問題,1是識別圖中有沒有人臉,2是有的話,人臉在什麼位置並畫出人臉框
在解決上述兩個問題時,mtcnn採用了下面兩個方法:

  • 找出所有可能是人臉的候選
  • 從候選區中篩選出最可能是人臉的候選區。
    可以看出,這種操作帶來高準確性的同時,也會使得其速度變慢,特別是在第一步中。

1.mtcnn訓練部分

1.1,怎麼產生正、負、部分樣本?

沒有對比就沒有差異,沒有差異就沒法學習。
問題1和問題2要結合起來看

  • 顧名思義,正樣本就是包含人臉的樣本框,負樣本爲不包含人臉的樣本框,部分樣本爲包含部分人臉的樣本框。
    在mtcnn作者通過iou來區分這三種樣本的:
    正:iou>0.65;部分樣本:iou>0.4;負樣本:iou<0.3。這些值需要根據不同的數據集進行調整。
      產生過程是一種隨機截取,具體爲,在我們拿到數據集後,裏面會有與該人臉對應的人臉框,即人臉的位置座標(x1,y1,w,h),這裏的隨機截取是有技巧的,不能在整個圖片上毫無目的的來截取,因爲我們想獲得足夠多的positive,negative,part,而假如只有一個人臉的話,直接隨機截取很容易獲得很多沒有用的圖片。所以這裏採用中心點偏移來隨機截取,即先找到數據集給定的人臉框中心點的位置,然後根據讓中心點進行隨機微調多次,再分次進行截取,通過計算其與數據集給定人臉框的iou值,最後resize爲12,24,48,這樣就可以獲得足夠多的正,負,部分樣本了,然後在保存的時候,給正樣本標爲1,負樣本標爲0,部分樣本標爲-1,就可以獲得神經網絡輸入對應的x和y_lable了。(對三個網絡,產生3個數據集,截取框的大小分別爲12,24,48)

1.2,採用偏移量進行邊框迴歸?

   但是,論文中和問題1中描述的有不同的是,在邊框迴歸的過程中,利用的是offset偏移量,計算方法爲:假設標定的人臉框左上角橫座標爲x1,框的寬高爲w和h,隨機產生的框的橫座標爲x1_,那麼,offset = (x1_-x1)/min(w,h),這裏存在歸一化可以把它理解爲,該點基於框的寬高的偏移程度,是往左偏移了0.1倍,還是往右偏移了0.2倍??等等。結合問題2,在隨機截取圖片後,先計算出offset,然後再通過計算iou將其分爲正負部分樣本,resize後,最後再給它們標上標籤,具體標法例子爲:正樣本:{1,offset_x1,offset_y1,offset_x2offset_y2},這樣就得到了我們真正的神經網絡輸入x和y_lable了。

  • 爲什麼採用偏移量進行邊框迴歸?
    假設一個圖裏面最小有12x12的人臉以及最大有500x500的人臉,如果直接預測座標和寬高,那麼預測值的波動範圍會比較大,模型的預測空間會非常大,會導致模式訓練不容易收斂。而採用偏移量的方式,會是預測空間比較小,會讓模型訓練容易收斂。
  • 損失函數的選擇及還原原圖座標
    這樣把x和y_label輸入神經網絡後,輸出的ylabel也爲置信度和偏移量offset,偏移量的損失函數爲mse平方差損失函數,訓練目的就是使得輸出的偏移量更接近給定的人臉框的偏移量,從而反算回去,得到原圖上預測到的人臉框座標,公式爲:

x1=x1+offsetmin(w,h){x1_*} = x1+offset*min(w,h)
關於人臉分類採用的交叉熵損失函數,這裏就不細說了。

  • 這裏爲什麼要進行歸一化?
    原因在於我們這裏使用了resize,對於圖片數據x和p網絡,我們需要將其resize爲12x12,而對於標籤,歸一化之後,resize對標籤中的offset值不會產生干擾。
  • 樣本如何去使用?
    1)在人臉分類過程中,即是非人臉問題,這裏採用只正樣本和負樣本,原因應該是兩者相差較大,在訓練中能使模型快速收斂。
    2)在邊框迴歸的問題中,使用了正樣本和部分樣本,原因在於,負樣本里面幾乎沒有人臉,而正樣本和部分樣本里面是存在人臉或部分人臉的,這樣子做offset來回歸是可行的。

2,mtcnn測試流程

前言,爲什麼要圖像金字塔?

  一句話,爲了解決目標的多尺度問題。因爲實際原因,我們需要處理的圖片中人臉的尺寸大小不一,爲了避免算法被人臉尺寸影響,我們需要創建一組具備不同分辨率的相同圖像集,並且在這個圖像集中搜索對象去搜索目標。

  上圖是mctnn的第一個網絡:P網絡,可以看出,P網絡能接受的輸入大小固定爲爲12x12,我們想要在測試中使得效果最佳,需要將待識別的人臉r按照縮放比例去resize到12x12得到類似金字塔的結構,再將這些圖片都傳入p網絡中處理。

整個流程可以從論文中這個圖看出來。(文中數據需要根據實際情況修改)
在這裏插入圖片描述
  第一行對應圖像金字塔處理。縮放規模爲0.7-0.8。拒絕調包!且看MTCNN人臉檢測推斷過程詳解!參考知乎博文:圖像金字塔在進行縮放操作時,默認把寬和高變爲1/2,那麼面積就變爲了1/4,如果認爲圖片縮放幅度過大,只想將面積變爲1/2,那麼只需將寬高變爲sqrt(1/2),即爲0.709。對圖片進行resize直到最小邊尺寸等於12爲止,這樣就得到了原圖,原圖x0.7,原圖x0.7^2…系列圖片,即爲圖像金字塔,然後把這些圖片都輸入P網絡。
在這裏插入圖片描述
  第二行對應把這些大小不一的圖片都輸入P網絡,p網絡會預測出一堆預測框偏移量,把這些預測框還原到原圖上後,將其進行nms非極大值抑制,篩選掉一大部分候選預測框,這裏nms的閾值設置爲,也就是iou的閾值0.5,也會得到一大部分候選預測框,此步爲粗略篩選。經過P網絡後,候選框變少,但任大量存在。

  第三行對應爲P網絡輸出的結果輸入R網絡。過程同上,這裏的R網絡設計的更爲精細。
在這裏插入圖片描述
輸入R網絡的數據爲:原始圖片,經過p網絡後得到的候選迴歸框。注意,這裏有個細節是:先根據p網絡提供的候選迴歸框從原圖上摳出圖片(是根據候選迴歸框邊長最大值去截取,這樣是因爲PNet中推理出來的bounding box座標可能超出元素圖片的大小,這時候需要做下圖片處理,把座標值限定在元素圖片內,而空出來的數據值爲0)。再把它resize爲24x2輸入網絡,這樣,R網絡會根據該數據輸出預測的y_label,即爲置信度和4個偏移量,同樣,先篩選出置信度>0.6的框,再還原到原圖上後,再對這些框進行nms,閾值設爲0.5,得到更精確的候選框。從圖中可以看出,經過R網絡後,候選框顯著變少我覺得這個圖應該在多幾個框才比較直觀。
  第四行對應爲R網絡輸出的結果輸入O網絡,流程同R網絡類似:
在這裏插入圖片描述
輸入O網絡的數據爲:原始圖片,經過R網絡輸出的候選迴歸框。同樣先通過R網絡提供的迴歸框最大邊長摳圖,再resize成risize爲48x48輸入O網絡,後面過程一樣,只是閾值設的比較高,我設的是置信度閾值設爲0.97,nms的閾值設爲0.7。最後得到返回的人臉框座標。

3.注

1)mtcnn訓練和測試是不同的,測試的時候是按照流程一步一步走的,訓練的時候,每個網絡都有自己的數據集,可以並行訓練。我剛學這個時候總是會把這兩者弄混,在看訓練代碼的時候總是想着圖像金字塔在哪,找不到就覺得自己真是個瓜皮,哈哈。
2)復現還有很多要完善的地方,例如學習率得隨着訓練過程變化,用矩陣運算代替for循環等等。
3)以上爲自己復現mtcnn的一點心得,參考了很多大神的博客理解及代碼,在此鞠躬!
在這裏插入圖片描述

參考博文:

http://www.sfinst.com/?p=1683
https://zhuanlan.zhihu.com/p/58825924
https://space.bilibili.com/471915350/
https://zhuanlan.zhihu.com/p/32121614

發佈了61 篇原創文章 · 獲贊 19 · 訪問量 6106
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章