張 衛(wèi),劉宇紅,張榮芬
貴州大學(xué) 大數(shù)據(jù)與信息工程學(xué)院,貴陽(yáng)550025
當(dāng)前,深度學(xué)習(xí)(Deep Learning)得到了廣泛的應(yīng)用與發(fā)展[1-2],而CNN也在越來(lái)越多的場(chǎng)景中被使用,諸如在視頻分析[3-4]、人臉識(shí)別[5-6]等領(lǐng)域都得到了廣泛的應(yīng)用,尤其是在圖像識(shí)別場(chǎng)景中取得了突破性的進(jìn)展。
CNN 是一種擁有多層感知器、局部連接和權(quán)值共享的網(wǎng)絡(luò)結(jié)構(gòu)[7],有較強(qiáng)的容錯(cuò)、學(xué)習(xí)和并行處理能力[8],從而降低了網(wǎng)絡(luò)模型的復(fù)雜性和網(wǎng)絡(luò)連接權(quán)值的個(gè)數(shù)。雖然CNN 的應(yīng)用廣泛,但需要大量時(shí)間來(lái)訓(xùn)練其模型的參數(shù),特別是在參數(shù)數(shù)據(jù)量很大時(shí)?,F(xiàn)階段實(shí)現(xiàn)CNN主要采用消費(fèi)級(jí)的通用處理器(Central Processing Unit,CPU)來(lái)實(shí)現(xiàn)[9],數(shù)據(jù)量過(guò)大時(shí)會(huì)采用圖形處理器(Graphics Processing Unit,GPU)來(lái)實(shí)現(xiàn)。近年來(lái),基于FPGA 實(shí)現(xiàn)的方式凸顯出巨大的優(yōu)勢(shì)[10]。CNN 是典型的并行運(yùn)算模型,在CNN的卷積層和池化層中,每一層的卷積運(yùn)算都只與當(dāng)前層的特征運(yùn)算核相關(guān),與其他層相比具有獨(dú)立性和不相關(guān)性。而FPGA 作為一種高度密集型計(jì)算加速器件,其硬件結(jié)構(gòu)有助于算法中并行運(yùn)算的加速[11]。當(dāng)前,利用FPGA 實(shí)現(xiàn)CNN 的方式以Verilog HDL 和HLS 為主。北京大學(xué)軟件與微電子學(xué)院采用Verilog HDL語(yǔ)言來(lái)設(shè)計(jì)IP核[12],并根據(jù)CNN模型設(shè)置了多種不同種類(lèi)的IP 核,可實(shí)例化不同的CNN網(wǎng)絡(luò),充分利用FPGA 的并行性提升了CNN 運(yùn)算速度和效率,但I(xiàn)P核設(shè)計(jì)過(guò)于復(fù)雜,通用性不強(qiáng),并且需要具備一定的硬件邏輯知識(shí)才能使用這些IP核。而HLS實(shí)際上是把高層的C、C++或SystemC的代碼綜合成Verilog HDL 描述,具有易于理解與使用、開(kāi)發(fā)時(shí)間短等特點(diǎn),故本文采用HLS來(lái)設(shè)計(jì)CNN中的卷積層和池化層的IP核,進(jìn)而利用IP核來(lái)搭建整個(gè)系統(tǒng)。
本文首先對(duì)深度學(xué)習(xí)中的CNN算法模型及結(jié)構(gòu)進(jìn)行介紹和研究,然后將CNN 模型中的卷積層和池化層設(shè)計(jì)為IP 核,通過(guò)將函數(shù)的運(yùn)算規(guī)模參數(shù)協(xié)議設(shè)為axi_master,減少了模型分類(lèi)的時(shí)間,提升了模型運(yùn)算性能。為了驗(yàn)證IP核的功能性,本文進(jìn)一步采用時(shí)分復(fù)用技術(shù)在FPGA平臺(tái)上對(duì)MNIST數(shù)據(jù)集進(jìn)行了系統(tǒng)驗(yàn)證。
神經(jīng)網(wǎng)絡(luò)是一種模仿生物的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)和功能的數(shù)學(xué)模型,可以模擬人的判斷能力。CNN 是神經(jīng)網(wǎng)絡(luò)的一種,在圖像和語(yǔ)音識(shí)別方面能夠給出更好的判斷結(jié)果。
CNN 包含卷積層、池化層和全連接層。典型的卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)如圖1所示。一個(gè)卷積塊為連續(xù)M個(gè)卷積層和個(gè)b池化層,一個(gè)卷積網(wǎng)絡(luò)可以堆疊N個(gè)連續(xù)的卷積塊,然后再接著K個(gè)全連接層。其中,卷積層通過(guò)“卷積核”作為中介。同一個(gè)卷積核在所有圖像內(nèi)是共享的,圖像通過(guò)卷積操作后仍然保留原先的位置關(guān)系,能得到圖像中的某些特征。但通過(guò)卷積層處理的特征維度大,數(shù)據(jù)量大,需要使用池化層進(jìn)行下采樣后才可進(jìn)行分類(lèi)。池化層保留數(shù)據(jù)中最顯著的特征,不會(huì)對(duì)數(shù)據(jù)丟失產(chǎn)生影響。全連接層則是一個(gè)完全連接的神經(jīng)網(wǎng)絡(luò),根據(jù)權(quán)重每個(gè)神經(jīng)元反饋的比重不一樣,最后通過(guò)Softmax函數(shù)得到分類(lèi)的結(jié)果。
圖1 典型的卷積網(wǎng)絡(luò)神經(jīng)結(jié)構(gòu)
得到分類(lèi)結(jié)果后,CNN 通過(guò)誤差反向傳播算法來(lái)進(jìn)行權(quán)重參數(shù)和偏置參數(shù)的學(xué)習(xí),這主要通過(guò)計(jì)算卷積層中參數(shù)的梯度來(lái)實(shí)現(xiàn)。具體計(jì)算過(guò)程可由如下公式表示。
第l個(gè)卷積層的第p(1 ≤p≤P)個(gè)特征映射凈輸入Z(l,p)可由公式(1)表示:
其中,X(l-1)∈R(M×N×D)為第l-1 層的輸入特征映射,W(l,p,d)和b(l,p)為第l層的卷積核以及偏置,該層共有P×D個(gè)卷積核和P個(gè)偏置,可以分別使用鏈?zhǔn)椒▌t來(lái)計(jì)算其梯度。
損失函數(shù)L(Y,Y?)關(guān)于卷積核W(l,p,d)和偏置b(l,p)的偏導(dǎo)分別由公式(2)和公式(3)表示:
其中,1 ≤i≤M-l+1,1 ≤j≤N-p+1。可以看出,每層參數(shù)的梯度依賴其所在層的誤差項(xiàng)δ(l,p)。卷積層和池化層的誤差項(xiàng)的計(jì)算不同,分別由公式(4)和公式(5)表示:
本文所設(shè)計(jì)的CNN 模型結(jié)構(gòu)如圖2 所示。該結(jié)構(gòu)有10 層,第1 層和最后一層分別是輸入層和輸出層,輸入層完成測(cè)試圖像數(shù)據(jù)的輸入獲取,因?yàn)閷?shí)驗(yàn)中采用MNIST數(shù)據(jù)集,所以輸入數(shù)據(jù)為784個(gè)。輸出層與前一層連接的權(quán)重個(gè)數(shù)為20×10=200,輸出結(jié)果為10種。為了降低過(guò)擬合,系統(tǒng)在輸出層的前一層還加入了Dropout層。
第1、2、3、4、6、8 層為卷積層,卷積核有5×5 和3×3兩種,卷積核移動(dòng)步長(zhǎng)均為1,無(wú)填充。第5層和第7層為池化層,池化步長(zhǎng)均為2,均采用最大池化。系統(tǒng)設(shè)計(jì)采用Relu函數(shù)作為激活函數(shù)。
各卷積層的參數(shù)為:
卷積層1 權(quán)重為5×5×5=125個(gè),偏置為5個(gè)。
卷積層2 權(quán)重為5×5×5×5=625個(gè),偏置為5個(gè)。
卷積層3 權(quán)重為3×3×5×5=225個(gè),偏置為5個(gè)。
圖2 本文設(shè)計(jì)的CNN網(wǎng)絡(luò)層次結(jié)構(gòu)圖
卷積層4 權(quán)重為3×3×5×5=225個(gè),偏置為5個(gè)。
卷積層6 權(quán)重為3×3×5×10=450個(gè),偏置為10個(gè)。
卷積層8 權(quán)重為3×3×10×20=1 800個(gè),偏置為20個(gè)。
因此整個(gè)卷積層總共有3 270個(gè)參數(shù)。
圖2 模型中卷積層和池化層均采用HLS 來(lái)實(shí)現(xiàn)。HLS 實(shí)際上是把高層的C、C++或SystemC 的代碼綜合成Verilog HDL描述,然后用下層的邏輯綜合來(lái)獲得網(wǎng)絡(luò)表,最后生成硬件電路。本文采用C 語(yǔ)言來(lái)編寫(xiě)代碼,使用Vivado HLS工具來(lái)生成IP核。
編寫(xiě)C 語(yǔ)言后,添加人為約束,就可以得到想要的硬件電路。其中,人為約束是設(shè)計(jì)電路的重點(diǎn)。本文設(shè)計(jì)的卷積電路是通用的,支持不同規(guī)格的輸入。用于實(shí)現(xiàn)卷積層IP核的Conv函數(shù)的表達(dá)式如下所示:
void Conv()
{填充運(yùn)算
for循環(huán)1:遍歷CHout
for循環(huán)2:遍歷Hin
for循環(huán)3:遍歷Win
{for循環(huán)4:遍歷Ky
for循環(huán)5:遍歷Kx
{for循環(huán)6:遍歷CHin
{tp=feature_in[h*CHin*Win+w*CHin+cin]*
W[ii*Kx*CHin*CHout+jj*CHin*CHout+cin*CHout+cout];
sum+=tp;}}
sum+=bias[cout];
feature_out[i*Wout*CHout+j*CHout+cout]=sum;}}
式中,CHin、Hin、Win分別為輸入特征的通道數(shù)、高、寬,CHout為輸出通道,Kx、Ky為卷積核的大小,Sx、Sy為步幅大小,mode是卷積的填充模式,relu_en是relu函數(shù)的使能,feature_in[]、feature_out[]、W[]、bias[]是輸入、輸出特征的運(yùn)算規(guī)模大小。
從Conv 函數(shù)的表達(dá)式可以看出,tp為輸入特征feature_in[h][w][cin] 和權(quán)重w[ii][jj][cin][cout] 進(jìn)行卷積運(yùn)算的結(jié)果,再加上偏置值bias[cout],即可得到輸出特征的值feature_out。對(duì)于有不同的高、寬、通道的圖像輸入、不同大小的卷積核濾波器,均可以使用該函數(shù)。通過(guò)Export RTL 操作,Conv 函數(shù)可生成如圖3(a)所示的IP 核,該IP 核的性能指標(biāo)Latency 和Interval 如圖3(b)所示。
圖3 卷積層IP核及其性能指標(biāo)
卷積運(yùn)算通過(guò)6 個(gè)for 循環(huán)遍歷輸入輸出來(lái)實(shí)現(xiàn),基本思想是采用滑窗法,而對(duì)其中的參數(shù)的優(yōu)化更為重要。對(duì)于函數(shù)中的運(yùn)算規(guī)模參數(shù),本文采用s_axilite 協(xié)議進(jìn)行約束優(yōu)化,可生成s_axi_AXILiteS 接口,用于更快地配置電路。對(duì)于函數(shù)中的數(shù)據(jù)來(lái)源參數(shù),采用m_axi 協(xié)議進(jìn)行約束優(yōu)化,可生成m_axi_gmen 接口,這便于卷積層主動(dòng)從存儲(chǔ)器中讀取特征數(shù)據(jù)和寫(xiě)入運(yùn)算結(jié)果,其工作過(guò)程如圖4所示。這里因?yàn)閰?shù)可配置導(dǎo)致for循環(huán)的邊界為變量,所以無(wú)法使用pipiline來(lái)并行化流水線進(jìn)行加速,會(huì)在一定程度上限制卷積運(yùn)算的速度。
圖4 卷積層IP核在系統(tǒng)中的工作過(guò)程
池化層的設(shè)計(jì)原理與卷積層類(lèi)似。通過(guò)Pool 函數(shù)生成的池化層IP 核也可對(duì)不同規(guī)模的輸入做池化運(yùn)算。池化運(yùn)算通過(guò)5 個(gè)for 循環(huán)來(lái)實(shí)現(xiàn),并可選擇性地做平均池化、最小池化和最大池化。通過(guò)Export RTL操作生成的池化層IP 核如圖5(a)所示,該IP 核的性能指標(biāo)Latency 和Interval 如圖5(b)所示。Pool 函數(shù)的表達(dá)式如下所示:
void Pool()
{for循環(huán)1:遍歷CHin
for循環(huán)2:遍歷Hin/Ky
for循環(huán)3:遍歷Win/Kx
{for循環(huán)4:遍歷Ky
for循環(huán)5:遍歷Kx
判斷池化模式:
平均池化:
sum+=(feature_in[h*CHin*Win+w*CHin+c)]/(Kx*Ky);
最小池化:
sum=min(sum,feature_in[h*CHin*Win+w*CHin+c]);
最大池化:
sum=max(sum,feature_in[h*CHin*Win+w*CHin+c];}
feature_out[i*Wout*CHin+j*CHin+c]=sum;}
式中,CHin、Hin、Win分別為輸入特征的通道數(shù)、高、寬,Kx、Ky為卷積核的大小,mode 是池化的模式,feature_in[]、feature_out[]為運(yùn)算規(guī)模大小。
圖5 池化層IP核及其性能參數(shù)
圖6 給出了池化層IP 核在系統(tǒng)中的工作過(guò)程。池化層IP 核接收到CPU 發(fā)來(lái)的指令后,主動(dòng)從存儲(chǔ)器中讀取特征數(shù)據(jù),池化運(yùn)算完成后,將運(yùn)算結(jié)果寫(xiě)入存儲(chǔ)器中。
圖6 池化層IP核在系統(tǒng)中的工作過(guò)程
系統(tǒng)的硬件部分包括ZYNQ處理器、兩個(gè)卷積層IP核、一個(gè)池化層IP 核以及連接各部分的axi總線。接收到ZYNQ處理器發(fā)來(lái)的指令后,IP核自行從存儲(chǔ)器中獲取神經(jīng)網(wǎng)絡(luò)的權(quán)重參數(shù)、偏置參數(shù)[13]以及圖像數(shù)據(jù),并將神經(jīng)網(wǎng)絡(luò)算法分類(lèi)的結(jié)果寫(xiě)入存儲(chǔ)器中。使用vivido工具完成的系統(tǒng)硬件圖如圖7所示,兩個(gè)卷積層IP核的m_axi_gmen 均連至ZYNQ 處理器的S_AXI_HP0 接口,池化層IP 核的m_axi_gmen 連至S_AXI_HP1 接口,ZYNQ 處理器的M_AXI_GP0 口同時(shí)連接三個(gè)IP 核的s_axi_AXILiteS接口。
硬件完成后,先生成比特流文件,再使用SDK工具開(kāi)始軟件設(shè)計(jì)。軟件設(shè)計(jì)主要是搭建CNN 的網(wǎng)絡(luò)結(jié)構(gòu),并將其中的卷積層和池化層運(yùn)算通過(guò)調(diào)用RunConv和RunPool 函數(shù)來(lái)實(shí)現(xiàn)。RunConv 函數(shù)中的InstancePtr參數(shù)為卷積層IP核的指針,通過(guò)這個(gè)指針可以調(diào)用不同的卷積層IP 核,當(dāng)指針指向0 時(shí)調(diào)用Conv_0 IP 核,指針指向1 時(shí)調(diào)用Conv_1 IP 核。RunPool 函數(shù)中也定義了類(lèi)似的指針,本文網(wǎng)絡(luò)中池化電路需求較少,且為了節(jié)約資源,本文只定義了一份池化電路,故指針一直指向0,調(diào)用Pool_0 IP 核。實(shí)際上,Conv_0 IP 核硬件電路用于計(jì)算核為5×5 的卷積運(yùn)算,Conv_1 IP 核用于計(jì)算核為3×3 的卷積運(yùn)算,Pool_0 IP 核硬件電路用于計(jì)算最大池化。
利用時(shí)分復(fù)用技術(shù),可加速整個(gè)系統(tǒng)的運(yùn)算。圖8詳細(xì)闡述了文中時(shí)分復(fù)用技術(shù)的應(yīng)用。在一張圖片的測(cè)試過(guò)程中,將圖片數(shù)據(jù)輸入神經(jīng)網(wǎng)絡(luò)后,卷積層C1和C2通過(guò)Conv_0 IP核進(jìn)行計(jì)算,卷積層C3、C4、C6和C8通過(guò)Conv_1 IP 核進(jìn)行計(jì)算,池化層P5 和P7 均通過(guò)Pool_0 IP核進(jìn)行計(jì)算。根據(jù)FPGA的并行性[14],三個(gè)IP核硬件電路同時(shí)運(yùn)行,能提升整個(gè)CNN 網(wǎng)絡(luò)的運(yùn)算性能。
圖7 系統(tǒng)硬件圖
圖8 時(shí)分復(fù)用技術(shù)應(yīng)用圖
系統(tǒng)設(shè)計(jì)中的具體硬件使用Xilinx 公司的ZYNQ-7000 xc7z010clg400-1 芯片作為試驗(yàn)平臺(tái),該芯片內(nèi)部擁有28 KB個(gè)邏輯單元,2.1 MB的嵌入式存儲(chǔ)器,80個(gè)嵌入式乘法器,片內(nèi)資源較為豐富,基本能夠滿足該網(wǎng)絡(luò)模型中硬件設(shè)計(jì)所需要的資源。CPU 軟件訓(xùn)練平臺(tái)使用Core i7-8700k處理器,主頻為3.4 GHz。
該硬件部分的系統(tǒng)資源消耗如表1 所示。系統(tǒng)設(shè)計(jì)中采用了大量的if語(yǔ)句和for循環(huán)語(yǔ)句用來(lái)進(jìn)行卷積運(yùn)算和池化運(yùn)算,導(dǎo)致系統(tǒng)中LUT 和FF 以及DSP 的邏輯資源消耗較多,但可以看出本文所使用的ZYNQ器件基本能夠滿足硬件框架需求。
表1 硬件部分的資源消耗
訓(xùn)練過(guò)程中,以學(xué)習(xí)率為0.5、每次輸入批次為50、迭代次數(shù)為10 000 在CPU 中進(jìn)行訓(xùn)練[15],訓(xùn)練集為MNIST數(shù)據(jù)集中的60 000張像素為28×28的灰度圖片,圖像數(shù)值范圍為0~255,最終對(duì)MNIST數(shù)據(jù)集的10 000張手寫(xiě)數(shù)字測(cè)試圖片進(jìn)行測(cè)試得到的平均識(shí)別正確率為96.83%。
測(cè)試過(guò)程中,先將CPU 中已訓(xùn)練好的網(wǎng)絡(luò)算法的權(quán)值參數(shù)、偏置參數(shù)以及MNIST 數(shù)據(jù)集的10 000 張手寫(xiě)數(shù)字測(cè)試圖片存儲(chǔ)在SD 卡中,PS 端給出指令后,IP核讀取SD 卡內(nèi)數(shù)據(jù),運(yùn)算完成后再將分類(lèi)結(jié)果存儲(chǔ)在存儲(chǔ)器中,最后通過(guò)串口打印出分類(lèi)結(jié)果。某次測(cè)試中串口打印的部分結(jié)果如圖9所示,其中,第925張圖片的預(yù)測(cè)值為0,實(shí)際的數(shù)字為2,預(yù)測(cè)錯(cuò)誤,其余圖片均預(yù)測(cè)正確。如表2 所示,經(jīng)10 000 次迭代測(cè)試后,各手寫(xiě)數(shù)字的整體識(shí)別正確率為95.34%,與軟件平臺(tái)正確率96.83%基本一致。表3 給出了各手寫(xiě)數(shù)字的識(shí)別正確率,其中手寫(xiě)數(shù)字6的正確率最差,為91.57%,但仍在可接受范圍內(nèi)。
FPGA 硬件平臺(tái)和CPU 軟件平臺(tái)所需的測(cè)試用時(shí)如表4所示,神經(jīng)網(wǎng)絡(luò)在CPU軟件平臺(tái)上迭代1次需要5.633×10-2s,而在FPGA 硬件平臺(tái)上[16]迭代1 次需要1.941×10-2s,再結(jié)合10 000次迭代后的測(cè)試用時(shí)對(duì)比,可以看出采用多個(gè)卷積層IP核實(shí)現(xiàn)時(shí)分復(fù)用后對(duì)電路的加速效果約為3 倍。但因?yàn)閷?shí)現(xiàn)卷積層和池化層IP的函數(shù)參數(shù)可配置,導(dǎo)致不能對(duì)函數(shù)內(nèi)for 循環(huán)做并行優(yōu)化和流水優(yōu)化,故算法的加速效果受到一定限制。
圖9 串口打印的部分結(jié)果
表2 FPGA硬件平臺(tái)和CPU軟件平臺(tái)的整體識(shí)別正確率對(duì)比
表3 各手寫(xiě)數(shù)字的識(shí)別正確率
表4 FPGA硬件平臺(tái)和CPU軟件平臺(tái)所需的測(cè)試用時(shí)對(duì)比
值得一提的是,由于FPGA與GPU并行處理的機(jī)理類(lèi)同,若采用GPU服務(wù)器開(kāi)展對(duì)比,根據(jù)文獻(xiàn)[17-19]可知,本文最終的識(shí)別效果和加速性能與GPU 模式的性能大抵相當(dāng),其優(yōu)勢(shì)在于基于FPGA 的CNN 系統(tǒng)可以部分替代GPU 服務(wù)器開(kāi)展相應(yīng)的圖片處理工作,在嵌入式應(yīng)用、邊緣計(jì)算方面具有更好的應(yīng)用前景。
本文通過(guò)使用HLS 設(shè)計(jì)了一種可實(shí)現(xiàn)卷積運(yùn)算和池化運(yùn)算、可配置參數(shù)的IP核,并利用時(shí)分復(fù)用技術(shù)和生成的IP 核在FPGA 平臺(tái)上實(shí)現(xiàn)了整個(gè)10 層網(wǎng)絡(luò)的CNN系統(tǒng)算法結(jié)構(gòu)。針對(duì)MNIST數(shù)據(jù)集的實(shí)驗(yàn)結(jié)果表明,該硬件系統(tǒng)的10 000次迭代的準(zhǔn)確率為95.34%,與CPU軟件平臺(tái)準(zhǔn)確率基本一致。不足的是,由于實(shí)現(xiàn)IP核的Conv 函數(shù)和Pool 函數(shù)的參數(shù)均為變量,無(wú)法使用pipeline和流水線技術(shù)對(duì)函數(shù)中的for循環(huán)進(jìn)行加速,導(dǎo)致系統(tǒng)的加速性能受限。但利用時(shí)分復(fù)用技術(shù)使得多個(gè)IP 核同時(shí)參與運(yùn)算,最終的加速性能約為CPU 系統(tǒng)的3 倍,能夠與GPU 的加速性能大抵相當(dāng),在嵌入式應(yīng)用、邊緣計(jì)算方面,具有潛在的應(yīng)用前景。總的來(lái)說(shuō),利用本文設(shè)計(jì)的IP核,可以使用FPGA在短時(shí)間內(nèi)實(shí)現(xiàn)一個(gè)CNN硬件系統(tǒng),并能部分替代GPU工作,充分體現(xiàn)了HLS的快捷性,對(duì)指導(dǎo)基于Verilog HDL的CNN硬件實(shí)現(xiàn)也具有重要意義。