范世朝,鄭國(guó)強(qiáng),孫國(guó)慶,韓旭
(河南科技大學(xué)信息工程學(xué)院,河南 洛陽 471023)
常規(guī)的基于FPGA的人臉識(shí)別系統(tǒng)大多是利用HDL語言來實(shí)現(xiàn),這就要求開發(fā)者熟悉硬件之間的邏輯關(guān)系。為了使軟件開發(fā)者能更方便的參與FPGA開發(fā),Xilinx公司推出了HLS高層次綜合工具和PYNQ系列FPGA開發(fā)板。對(duì)于軟件開發(fā)者可以在HLS平臺(tái)利用C語言實(shí)現(xiàn)邏輯功能,之后高層次綜合會(huì)自動(dòng)將C語言轉(zhuǎn)化為Verilog語言,生成相應(yīng)的IP核。而PYNQ系列開發(fā)板ARM端內(nèi)置Jupyter notebook網(wǎng)絡(luò)服務(wù)器,Linux系統(tǒng)和IPython內(nèi)核,可以十分方便的利用Python對(duì)生成的IP核進(jìn)行調(diào)用,大大降低了開發(fā)門檻[1]。
本文利用PYNQ-Z2開發(fā)板為基礎(chǔ),設(shè)計(jì)出一個(gè)基于卷積神經(jīng)網(wǎng)絡(luò)的人臉識(shí)別系統(tǒng),該系統(tǒng)能夠識(shí)別輸入的人臉圖像的面部特征,并判斷目標(biāo)是否是訓(xùn)練庫中的用戶,如果是會(huì)在結(jié)果中標(biāo)識(shí)出目標(biāo)的名字。該系統(tǒng)的總體架構(gòu)如圖1:
圖1 系統(tǒng)總體架構(gòu)圖
利用Python調(diào)用PC端的攝像頭,實(shí)時(shí)采集圖像數(shù)據(jù),并進(jìn)行人臉識(shí)別,當(dāng)識(shí)別出人臉時(shí),會(huì)自動(dòng)抓取圖片并進(jìn)行保存。這里對(duì)人臉進(jìn)行識(shí)別的方法是調(diào)OpenCV的cv2級(jí)聯(lián)分類器haarcascade_frontalface_alt2.xml,同時(shí)在調(diào)用級(jí)聯(lián)器時(shí),對(duì)級(jí)聯(lián)器的detectMultiScal函數(shù)中minNeighbors參數(shù)進(jìn)行設(shè)置,來設(shè)定需要達(dá)到的檢測(cè)有效點(diǎn)數(shù),本文需要達(dá)到的檢測(cè)有效點(diǎn)數(shù)是2,意味著只有連續(xù)兩次識(shí)別成功時(shí)才會(huì)認(rèn)為識(shí)別出了人臉數(shù)據(jù)。同時(shí)為了保證后續(xù)進(jìn)行模型訓(xùn)練時(shí)圖像的大小相同,在識(shí)別時(shí)設(shè)置保存的人臉圖像大小統(tǒng)一為64×64[2]。
整個(gè)數(shù)據(jù)集的制作流程如下:
圖2 數(shù)據(jù)集制作流程
訓(xùn)練主要采用的是TensorFlow框架。訓(xùn)練時(shí),系統(tǒng)輸入層大小是64×64,卷積層有32個(gè)3×3大小的卷積核,并使用same方式卷積。池化層與卷積層交替循環(huán),三次池化均為最大池化,大小為2×2。第三層池化層之后是一層全連接層和一層輸出層。經(jīng)8個(gè)輸出端的輸出層輸出預(yù)測(cè)結(jié)果。訓(xùn)練時(shí)選用的激活函數(shù)是ReLU函數(shù),使用TensorFlow自帶的AdamOptimizer優(yōu)化器對(duì)模型參數(shù)進(jìn)行訓(xùn)練。模型訓(xùn)練完畢后將生成的模型文件導(dǎo)入Jupyter notebook[3][4]。
卷積神經(jīng)網(wǎng)絡(luò)的重點(diǎn)在卷積層,池化層和全連接層,其中,全連接層我們通過復(fù)用卷積模塊的方式來使用,這樣可以節(jié)省片上資源,只需要將卷積核的大小從3×3改為16×16,但是也要注意一些參數(shù)維度的改變。設(shè)計(jì)方案如下:
通過HLS設(shè)計(jì)平臺(tái),利用C語言或者C++設(shè)計(jì)子函數(shù)實(shí)現(xiàn)卷積層和池化層,之后進(jìn)行高級(jí)綜合將其轉(zhuǎn)化為Verilog語言,封裝成IP核。IP核設(shè)計(jì)完成后需要設(shè)計(jì)block design以使IP核與ARM端通信。這里卷積模塊與池化模塊都通過AXI總線與PYNQ連接,在導(dǎo)入IP核后VIVADO會(huì)自動(dòng)進(jìn)行連接,連接后的結(jié)果如下:
圖3 block design 設(shè)計(jì)
之后將設(shè)計(jì)好的block design導(dǎo)出為bit文件和tcl文件,并將導(dǎo)出的bit文件和tcl文件下載到PYNQ開發(fā)板的SD卡中就可以復(fù)現(xiàn)人臉識(shí)別系統(tǒng)。
將訓(xùn)練好的模型文件和生成的bit和tcl文件導(dǎo)入Jupyter notebook后就可以編寫Python代碼復(fù)現(xiàn)人臉識(shí)別系統(tǒng)。首先需要在Python代碼中導(dǎo)入Overlay以便于調(diào)用制作的卷積層和池化層的函數(shù),之后利用OpenCV識(shí)別待檢測(cè)圖像的人臉部分,提取出來人臉特征與模型文件進(jìn)行比對(duì),之后將比對(duì)結(jié)果進(jìn)行輸出即可。
本設(shè)計(jì)用的仿真策略是通過HLS工具編寫test bench文件對(duì)卷積模塊和池化模塊進(jìn)行仿真驗(yàn)證。
對(duì)于卷積層模塊仿真如下圖所示,使用same方式進(jìn)行卷積,所謂same方式卷積,即在進(jìn)行卷積運(yùn)算會(huì)在輸入四周補(bǔ)零之后再進(jìn)行運(yùn)算,可以保證輸入和輸出的矩陣大小是等同的,仿真結(jié)果如下:
圖4 卷積模塊仿真
資源占用情況如下,其中DSP:主要用來進(jìn)行數(shù)字信號(hào)處理。LUT是查找表,但是本質(zhì)上就是一個(gè)RAM,它把數(shù)據(jù)事先寫入RAM后,每當(dāng)輸入一個(gè)信號(hào)就等于輸入一個(gè)地址進(jìn)行查表,找出地址對(duì)應(yīng)的內(nèi)容,然后輸出。FF:觸發(fā)器,一種時(shí)鐘信號(hào)觸發(fā)時(shí)才能動(dòng)作的存儲(chǔ)單元電路。
圖5 資源占用
對(duì)于池化層模塊,使用3×3最大池化,即在3×3的區(qū)域內(nèi)選擇一個(gè)最大值進(jìn)行輸出:
圖6 池化模塊仿真
其中資源占用情況如圖所示:
圖7 資源占用
本文提出了一種基于PYNQ-Z2的FPGA人臉識(shí)別系統(tǒng),同時(shí)構(gòu)建其軟硬件平臺(tái),使用OpenCV級(jí)聯(lián)器進(jìn)行人臉檢測(cè),使用卷積神經(jīng)網(wǎng)絡(luò)訓(xùn)練模型,利用HLS生成卷積層和池化層的IP核,并利用其仿真工具編寫test bench文件對(duì)結(jié)果進(jìn)行了仿真測(cè)試,經(jīng)過測(cè)試可知,本文提出的方法能夠滿足實(shí)際需求,并無需考慮硬件的邏輯結(jié)構(gòu),顯著降低了開發(fā)難度,同時(shí)資源占用較低。