TensorFlow人臉識別(TensorFlow+Dlib+OpenCV)基於深度學習的人臉識別 搭建卷積神經網絡--理論及代碼詳解,包含文檔和源代碼

1 項目概述

人臉識別在現代社會中有着非常廣泛的應用。此次數字圖像處理課程中,我選擇做一個基於深度學習的人臉識別系統。我設計的基於深度學習的人臉識別系統,通過攝像頭獲取圖片,使用dlib分類器定位人臉,使用卷積神經網絡進行人臉識別。我設計的系統有三個輸出類別。除了可以識別我和另外一個同學外,我還在網絡上的LFW人臉圖片庫中下載了一定的圖片,來作爲第三個類別爲圖片標記標籤。關於系統的詳細設計思路和實現過程將在下面幾個部分進行詳述。

本文檔作者爲Luke(wlg)。
本文檔最初是課程報告,現做了少量改編僅供學習交流使用。
未經允許,嚴禁複製、轉載或引用文檔的任何部分!特此聲明!
完整代碼+文檔下載地址:https://github.com/lukegood/DIY_Face_recognition_system
請進入上述CSDN鏈接獲取源代碼和全文。
如需輸入密碼,請關注微信公衆號Luke小站(微信號lukeluke01),回覆project即可獲取密碼。

2 模塊功能和結構劃分

我實現的系統共分爲攝像頭採集和處理圖片模塊、本地圖片處理模塊、卷積神經網絡搭建和訓練模塊以及測試模塊四個部分,每個部分保存在一個.py文件中。
攝像頭採集和處理圖片模塊主要負責採集人臉圖片,通過調用攝像頭截取照片,定位人臉,指定規格化,並最終保存人臉圖片。
本地圖片處理模塊主要用於處理我在網絡上下載下來作爲第三個分類類別使用的圖片,其主要功能是將圖片讀入,使用dlib定位人臉,然後將人臉圖片保存成我設定好的規格以便使用。
卷積神經網絡搭建和訓練模塊主要完成前向傳播、劃分訓練集與測試集、反向傳播等功能,是整個系統的關鍵部分。
測試部分主要來調用攝像頭捕獲人臉圖片,然後讀入之前保存好的訓練成熟的網絡進行識別。
系統結構如下圖所示:
在這裏插入圖片描述
圖 1系統結構

3 項目實現

3.1 樣本的採集和處理

樣本的採集和處理主要集中在攝像頭採集和處理圖片模塊、本地圖片處理兩個模塊中。
首先,使用攝像頭採集和處理圖片模塊來採集和處理我和另外一個同學的圖片。使用OpenCV調用攝像頭,然後截取圖片並灰度化,之後使用dlib找到人臉並以合適的規格保存圖片。具體流程如下圖所示:
在這裏插入圖片描述
圖 2採集流程
在網上下載LFW圖片庫的圖片並不符合我想使用的規格,所以設計了本地照片處理模塊。在本地照片處理中,流程基本和上面一致,不同的地方在於輸入不再從攝像頭中讀入,而是本地的圖片。具體流程如下圖所示:
在這裏插入圖片描述
圖 3本地圖片處理流程
下面來解釋與樣本採集與處理有關的關鍵代碼。
首先使用**camera = cv2.VideoCapture(0)**來打開攝像頭,在經過灰度化處理後,使用dlib分類器定位人臉,獲取到相應的座標。
在這裏插入圖片描述
圖 4定位人臉座標
獲取到人臉的左下角和右上角座標後,在通過攝像頭獲取的圖片中把人臉截取出來,保存成我們想要的規格。可通過代碼face = img[x1:y1,x2:y2],face = cv2.resize(face, (size,size))來完成。
在完成對圖片的採集和處理後,接下來進行神經網絡的搭建工作。

本文檔作者爲Luke(wlg)。
本文檔最初是課程報告,現做了少量改編僅供學習交流使用。
未經允許,嚴禁複製、轉載或引用文檔的任何部分!特此聲明!
完整代碼+文檔下載地址:https://github.com/lukegood/DIY_Face_recognition_system
請進入上述CSDN鏈接獲取源代碼和全文。
如需輸入密碼,請關注微信公衆號Luke小站(微信號lukeluke01),回覆project即可獲取密碼。

3.2 卷積神經網絡的構建和訓練

3.2.1 卷積、池化、激活和捨棄

卷積層在整個網絡中具有重要的作用,用來提取樣本的特徵並進行處理,選擇好卷積層對整個卷積神經網絡識別的準確率有重要的影響。在選擇卷積核的時候,一般採用“小卷積核,多卷積層數”的原則。因此,我最終採用了在圖像識別中非常常用的三層卷積的結構。卷積核大小採用3乘3,在行和列上的移動步長均定爲1。爲了保證樣本在經過卷積層後規格不變,方便下一步處理,我使用了“全零填充”,也就是在樣本外面加一層“0”。
在每一層卷積層後,我都連接了一個池化層,採用最大池化來進行下采樣。我將池化層的分辨率定爲2乘2,也就是將卷積後的樣本分成了很多個2乘2的小區域,在每個小區域裏採集最大值,然後合併起來作爲池化層的輸出結果。用於池化的原因,雖然卷積過後樣本規格並沒有發生變化,但是池化會使樣本的長寬減小一半。
在完成池化後,我又讓樣本過了一次激活函數。激活函數的作用是給神經網絡加入一些非線性的因素,使得神經網絡可以更好的解決分類問題。在選擇激活函數的時候,我採用了relu函數。我經過查閱文獻發現,當前很多文獻都推薦使用relu函數,原因是它的計算代價小並且能夠減輕梯度消失的問題。爲了減小訓練時間,我最終選擇了使用relu函數。
在這裏插入圖片描述
圖 5relu函數示意圖
在完成激活往下一層網絡輸入前,我又引入了捨棄。引入舍棄的原因在於,我們構造的網絡需要訓練的參數普遍很大,而且很容易產生過擬合的問題。爲了增強模型的泛化性,可以通過捨棄,隨機的讓某些參數不參與訓練。但是,捨棄僅僅是針對訓練階段而言的,在模型真實使用的時候,所有的參數都是要參與到計算中來的。
最終,這一部分的網絡結構如下圖所示:
在這裏插入圖片描述
圖 6結構示意
在我設計的網絡結構中,首先將準備好的樣本輸入(64643),經過卷積後,樣本規格不變,但是通道數由3變爲了32。然後經過池化層時,樣本的長寬各減半,所以在經過第一層卷積和池化後,樣本規格變爲了323232。其他層的計算方法與第一層完全相同。在經過了第二層卷積核池化後,樣本規格變爲了161632。在經過了第三層卷積核池化過後,樣本的規格變爲了8864,並作爲輸入進入到全連接神經網絡中。
代碼上,配置卷積層、池化層以及使用激活函數和引入舍棄,都可以通過調用TensorFlow裏的函數實現,爲了方便起見,可以自己定義函數,在裏面再調用TensorFlow的函數,這樣只需要在自己的函數裏把TensorFlow需要的參數配置好,以後只需要調用自己的函數傳樣本和待優化參數就可以了。具體如下所示:
在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述
圖 7自己包裝好創建卷積、池化、捨棄的函數

3.2.2 全連接神經網絡

在全連接神經網絡中,我主要設置了一層隱藏層和一層輸出層。根據我查閱的文獻,增加隱藏層的層數可以降低網絡誤差,但是同時增加了網絡的複雜性,容易使網絡產生過擬合的傾向,因此往往通過增加隱藏層節點個數來獲得較低的誤差比增加層數要好一些。
爲了確定設置多少個隱藏層節點較好,我進行了一些嘗試,分別嘗試了256、512、1024三種隱藏層節點情況下網絡在測試集上的準確率。
爲了控制變量,將輸入樣本確定爲6000,其中我、我srf的搭檔以及第三分類圖片各2000張。訓練集和測試集的比例設置爲95:5,batch_size設置爲100個樣本,執行400個batch_size後停止。
256、512、1024個隱藏層節點下的測試集準確率和loss如下圖所示:

(請進入github鏈接獲取源代碼和全文:https://github.com/lukegood/DIY_Face_recognition_system
如需輸入密碼,請關注微信公衆號Luke小站(微信號lukeluke01),回覆project即可獲取密碼。)

本項目參考了:http://tumumu.cn/2017/05/02/deep-learning-face,在此表示感謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章