王 婷,陳斌岳,張福海
(南開大學 電子信息與光學工程學院,天津300350)
隨著人工智能的快速發(fā)展,卷積神經(jīng)網(wǎng)絡(luò)越來越受到人們的關(guān)注。 由于它的高適應性和出色的識別能力,它已被廣泛應用于分類和識別、目標檢測、目標跟蹤等領(lǐng)域[1]。 與傳統(tǒng)算法相比,CNN 的計算復雜度要高得多,并且通用CPU 不再能夠滿足計算需求。 目前,主要解決方案是使用GPU 進行CNN 計算。 盡管GPU 在并行計算中具有自然優(yōu)勢,但在成本和功耗方面存在很大的缺點。卷積神經(jīng)網(wǎng)絡(luò)推理過程的實現(xiàn)占用空間大,計算能耗大[2],無法滿足終端系統(tǒng)的CNN 計算要求。 FPGA 具有強大的并行處理功能,靈活的可配置功能以及超低功耗,使其成為CNN 實現(xiàn)平臺的理想選擇。 FPGA 的可重配置特性適合于變化的神經(jīng)網(wǎng)絡(luò)網(wǎng)絡(luò)結(jié)構(gòu)。 因此,許多研究人員已經(jīng)研究了使用FPGA 實現(xiàn)CNN 加速的方法[3]。 本文參考了Google 提出的輕量級網(wǎng)絡(luò)MobileNet 結(jié)構(gòu)[4],并通過并行處理和流水線結(jié)構(gòu)在FPGA 上設(shè)計了高速CNN 系統(tǒng),并將其與CPU 和GPU 的實現(xiàn)進行了比較。
在深度學習領(lǐng)域中,卷積神經(jīng)網(wǎng)絡(luò)占有著非常重要的地位,它的圖像識別準確率接近甚至高于人類的識別水平。卷積神經(jīng)網(wǎng)絡(luò)是同時具有層次結(jié)構(gòu)性和局部連通性的人工神經(jīng)網(wǎng)絡(luò)[5]。 卷積神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)都是類似的,它們采用前向網(wǎng)絡(luò)模型結(jié)構(gòu),節(jié)點使用神經(jīng)元來實現(xiàn)分層連接。 并且,相鄰層之間的節(jié)點是在局部區(qū)域內(nèi)相連接,同一層中的一些神經(jīng)元節(jié)點之間是共享連接權(quán)重的。 傳統(tǒng)的卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)如圖1 所示,卷積神經(jīng)網(wǎng)絡(luò)是直接將準備識別的原始圖像作為輸入,然后依次通過多個隱藏層連接到各層,得到識別結(jié)果。
圖1 卷積神經(jīng)網(wǎng)絡(luò)典型結(jié)構(gòu)
MobileNet 是用于移動和嵌入式設(shè)備的有效模型。MobileNet 基于簡化的架構(gòu),并使用深度可分離卷積來構(gòu)建輕型深度神經(jīng)網(wǎng)絡(luò)。 為了進一步減少參數(shù)數(shù)量并促進在FPGA 上的部署,本文中使用了經(jīng)過修改的CNN 網(wǎng)絡(luò)結(jié)構(gòu),如圖2 所示。 共有9 個卷積層和3 個池化層。
圖2 卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)
在卷積神經(jīng)網(wǎng)絡(luò)中,卷積運算占據(jù)了大部分計算量。傳統(tǒng)的卷積分為兩個步驟,即每個卷積核與每張?zhí)卣鲌D片進行按位乘法然后相加,此時的計算量為DF*DF*DK*DK*M*N,DF 是輸入特征圖的尺寸,DK 是卷積核的尺寸,M、N 分別是輸入通道數(shù)和輸出通道數(shù)。 本文采用的卷積方式不同于傳統(tǒng)卷積,首先按照輸入通道進行按位相乘,得到的結(jié)果通道數(shù)是沒有變化的,接下來使用1*1 的卷積核再進行計算,以改變通道數(shù)。這種方法的計算量為DK*DK*M*DF*DF+1*1*M*N*DF*DF, 第1 項表示的是卷積核為3 時的計算量,第2 項表示卷積核為1 時的計算量,當DK=3 時,這種卷積方式比傳統(tǒng)卷積減少了8 倍多的計算量,計算量的大幅度減少更有利于部署在資源有限的FPGA 端。 運算一個卷積層需要6 個循環(huán)嵌套來實現(xiàn),循環(huán)順序按照輸出通道>輸入通道>高度>寬度>卷積內(nèi)核元素依次來排列計算。 對于每一卷積層來說,最外面的循環(huán)按照順序遍歷所有像素。上述循環(huán)結(jié)構(gòu)的優(yōu)化實現(xiàn)可以使用循環(huán)展開,循環(huán)拆分以及循環(huán)合并的指令方法,以設(shè)計加速器的IP 核。
在訓練了卷積神經(jīng)網(wǎng)絡(luò)之后,參數(shù)數(shù)據(jù)是一個32 位浮點數(shù)。 相關(guān)實驗已經(jīng)證實,精度降低一定程度對CNN識別精度的影響非常微弱[6]。 因此,本文設(shè)計中經(jīng)過嘗試不同量化位數(shù)后,在保證了精度的情況下選擇輸入的圖像數(shù)據(jù)和權(quán)重數(shù)據(jù)使用9 位定點數(shù)。這種設(shè)計大大降低了FPGA 資源的利用率,并提高了網(wǎng)絡(luò)運行速度。
卷積神經(jīng)網(wǎng)絡(luò)的計算成本主要有卷積層的大量乘法運算,在FPGA 中通常使用DSP 資源進行乘法運算,而通常不足的DSP 資源會成為卷積神經(jīng)網(wǎng)絡(luò)部署在FPGA 端的瓶頸。 BOOTH 算法實現(xiàn)的乘法器可有效地代替使用DSP 資源的傳統(tǒng)乘法。 在Vivado HLS 中,數(shù)據(jù)都是以十六位二進制帶符號的補碼表示,原碼乘法器的移位相加方法并不能直接推廣用于補碼的乘法運算中。普通的移位相加運算量比較大,乘數(shù)的每一位都產(chǎn)生部分積,乘數(shù)中值為1 的位數(shù)決定著累加的次數(shù)。 BOOTH算法的思想是將乘數(shù)近似為一個較大的整數(shù)值,利用這個整數(shù)值與被乘數(shù)相乘的結(jié)果減去這個整數(shù)值的補數(shù)與被乘數(shù)相乘的結(jié)果,對于具有連續(xù)的1 和0 的乘數(shù)來說產(chǎn)生的部分積較少。 具體運算步驟如下:
(1)被乘數(shù)X 與乘數(shù)Y 均為有符號數(shù)補碼,運算結(jié)果也是補碼。
(2)初始部分積為0,乘數(shù)Y 末尾添加附加位,初始值為0。
(3)判斷乘數(shù)Y 后兩位:若是01 則部分積加被乘數(shù)X 再右移一位, 若是10 則部分積減被乘數(shù)X 再右移一位,若是00 以及11 則只進行右移一位操作。
(4)累加n+1 次(n 表示數(shù)據(jù)數(shù)值位數(shù)),右移n 次。
卷積層之間的運算有兩種實現(xiàn)模式,分為層串行模式和層并行模式[7]。 本文在設(shè)計基于FPGA 的CNN 加速器時,選擇了高度的靈活性和實現(xiàn)難度低的層串行模式。
在層串行模式中,F(xiàn)PGA 中的所有PE 單元都只用于實現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)中一層的功能。并且通過重復調(diào)用存在的PE 單元,即使用時分復用PE 單元的策略來實現(xiàn)整個神經(jīng)網(wǎng)絡(luò)的運算[8]。 根據(jù)卷積神經(jīng)網(wǎng)絡(luò)單層操作的類似性原理,因此考慮由單層實現(xiàn)的層串行模式是確實可行的。 并且,在這種操作模式下,從DDR 中讀取數(shù)據(jù)傳輸給PE 單元,PE 單元計算得到結(jié)果后將其寫回到DDR,數(shù)據(jù)控制比較簡單。 然而,對于中間數(shù)據(jù)的存儲,層串行模式是通過AXI 總線協(xié)議將每一層的中間運算結(jié)果都再傳輸?shù)酵獠看鎯ζ鱀DR 中,因此這種方法對IO 帶寬的要求非常高[9]。
為了增大吞吐量并解決因帶寬瓶頸而造成的傳輸時間過長,可以減少每一層的數(shù)據(jù)訪問以及存儲空間,以實現(xiàn)最大程度的數(shù)據(jù)和模塊復用。 因此,本文將每三層合并為一組,然后將結(jié)果輸出到DDR,從而將12 層CNN 結(jié)構(gòu)減少為5 層,這將節(jié)省一部分傳輸步驟。 此操作將多層融合在一起而形成局部組合的方法,將從DRAM 接收的輸入數(shù)據(jù)和操作的中間結(jié)果緩存都存儲在片上BRAM 存儲器中。
在帶寬瓶頸的影響下,整個硬件平臺的加速性能主要受到數(shù)據(jù)的訪存效率限制。為了有效控制數(shù)據(jù)流的訪存將使用緩沖技術(shù),以增加帶寬利用率[10]。 乒乓操作的緩沖方式是使用兩個數(shù)據(jù)存儲器,先將數(shù)據(jù)存儲在第一個數(shù)據(jù)緩存中,當?shù)谝粋€數(shù)據(jù)緩存存滿時,數(shù)據(jù)將轉(zhuǎn)換到第二個數(shù)據(jù)緩存中存儲,并在相同時刻讀取第一個數(shù)據(jù)緩存中的數(shù)據(jù)。這種方式使得單通道的數(shù)據(jù)傳輸有效地變化為雙通道的數(shù)據(jù)流傳輸, 數(shù)據(jù)流經(jīng)過緩沖后,不斷地傳遞到數(shù)據(jù)處理模塊,這將使數(shù)據(jù)傳輸時間與數(shù)據(jù)運算時間重疊,以抵消大部分的時間[11]。
為了提高加速器系統(tǒng)的吞吐效率,在片內(nèi)的輸入緩存設(shè)置了圖像輸入緩存和權(quán)值輸入緩存,以及結(jié)果輸出緩存。 輸入緩存的作用是從外部存儲器DDR 中載入所需數(shù)據(jù)以及所需參數(shù),輸出緩存的作用是將存儲運算結(jié)果輸出至外部存儲器DDR 中或者是再應用于計算單元中。緩存結(jié)構(gòu)根據(jù)DMA 的方式來進行數(shù)據(jù)交互。本文的輸入圖像、權(quán)值以及輸出的計算結(jié)果都采用如圖3 所示的乒乓緩沖方式。兩個數(shù)據(jù)緩沖模塊通過二選一復用器相互配合使用,使數(shù)據(jù)可以沒有停頓地依次加載到計算單元中,計算單元可以時時刻刻處于計算狀態(tài),以此充分利用了有限的計算資源。
圖3 乒乓緩存數(shù)據(jù)流
加速器的總體設(shè)計如圖4 所示,由PS 和PL 組成。其中PS 主要負責圖像數(shù)據(jù)預處理,權(quán)重數(shù)據(jù)預處理和特征定位的任務,而PL 負責整個CNN 計算部分。 加速器系統(tǒng)通過AXI 總線將CPU 和外部存儲器DDR 中的卷積神經(jīng)網(wǎng)絡(luò)參數(shù)權(quán)重,以及要識別的輸入圖像像素數(shù)據(jù)傳遞給PL 部分。 當操作控制指令傳遞到PL 端時,PL 端啟動系統(tǒng)主程序,并通過輸入緩沖區(qū)的乒乓操作將參數(shù)和像素數(shù)據(jù)傳輸?shù)竭\算操作邏輯單元。在完成整個卷積神經(jīng)網(wǎng)絡(luò)的計算后,輸出數(shù)據(jù)通過AXI 總線通過輸出緩沖區(qū)傳輸?shù)紻DR 存儲器,并輸出最終結(jié)果。
圖4 加速器系統(tǒng)的整體設(shè)計
實驗采用Xilinx Zynq UltraScale+MPSoC ZU3EG A484 Development Board 對本文目標檢測定位算法進行加速。片內(nèi)由ARM 處理器與可重構(gòu)FPGA 構(gòu)成,片上資源主要 由432 個BRAM 和360 個DSP 組 成。 CPU 采 用Intel Core i5 2500K 處理器,GPU 是NVIDIA UeForce UTX 960。所用到的軟件開發(fā)工具為賽靈思公司開發(fā)的Vivado 設(shè)計套件Vivado IDE 和Vivado HLS。
傳統(tǒng)的FPGA 設(shè)計流程復雜且繁瑣,為了簡化開發(fā)流程,加速器系統(tǒng)采用高級綜合方式來進行優(yōu)化設(shè)計[12]。首先采用Vivado HLS 開發(fā)工具將CNN 計算過程的高級編程語言C++轉(zhuǎn)化為硬件描述語言,再封裝為Vivado 的IP 核輸出。 Vivado HLS 工具具體的設(shè)計流程如圖5 所示。 然后利用Vivado IDE 開發(fā)工具,導入封裝好的CNN運算IP 核、主控單元zynq_ultra_ps、時鐘單元以及AXI傳輸模塊。 通過綜合、設(shè)定約束、布局布線來實現(xiàn)完成整個加速器系統(tǒng)的設(shè)計。
圖5 Vivado HLS 工具設(shè)計流程
表1 列出了默認乘法的FPGA 的資源使用情況,表2 列出了部分乘法用BOOTH 算法代替的資源使用情況,由于開發(fā)板的LUT 資源使用率已經(jīng)很高,因此部分乘法還是采用了DSP 資源。 BRAM 用于圖像數(shù)據(jù)、網(wǎng)絡(luò)權(quán)重及輸出數(shù)據(jù)的緩存,DSP 以及LUT 用于卷積模塊的乘加運算,該設(shè)計高效地利用了FPGA 的內(nèi)部資源。
表1 默認乘法FPGA 內(nèi)部資源的利用率
表2 BOOTH 乘法FPGA 內(nèi)部資源的利用率
表3 中顯示了將FPGA 中CNN 的性能與Intel Core i5 CPU 和NVIDIA UeForce UTX 960 UPU 進行比較的結(jié)果。 基于FPGA 優(yōu)化設(shè)計的卷積神經(jīng)網(wǎng)絡(luò)處理單個圖像所需的時間比CPU 要少得多,相當于GPU 的速度。 GPU功耗是本文設(shè)計的30 倍以上。
表3 不同硬件平臺的性能評估
本文提出了一種基于FPGA 有限資源的卷積神經(jīng)網(wǎng)絡(luò)加速器。利用BOOTH 算法實現(xiàn)乘法,有效降低了DSP 資源占用量。通過流水線結(jié)構(gòu)和卷積運算的并行性提高了卷積運算的速度。網(wǎng)絡(luò)加速器的內(nèi)部結(jié)構(gòu)在資源有限的開發(fā)板上實現(xiàn)12 層CNN 網(wǎng)絡(luò), 并將其與CPU 和GPU進行比較。 實驗結(jié)果表明,嵌入式FPGA 的功耗和性能具有很大的優(yōu)勢,更適合于移動端的部署。