周李敏,孫 靜,楊宏波,潘家華,王威廉+
(1.云南大學(xué) 信息學(xué)院,云南 昆明 650500;2.云南省阜外心血管病醫(yī)院 結(jié)構(gòu)性心臟病病區(qū),云南 昆明 650102)
心音信號(hào)在評(píng)估心血管疾病(cardiovascular disease,CVD)的初診篩查中起著至關(guān)重要的作用[1],但心音聽診在很大程度上取決于醫(yī)師的臨床經(jīng)驗(yàn)和檢查技能。與此同時(shí)人工智能興起,故而將深度學(xué)習(xí)應(yīng)用于心音自動(dòng)分類系統(tǒng)的研究應(yīng)運(yùn)而生[1,2]。心音自動(dòng)分類系統(tǒng)包括心音信號(hào)預(yù)處理、特征提取以及分類3個(gè)部分,可將深度學(xué)習(xí)的方法用于分類部分以達(dá)到智能識(shí)別正、異常心音信號(hào)的目的。
卷積神經(jīng)網(wǎng)絡(luò)(convolutional neutral network,CNN)和循環(huán)神經(jīng)網(wǎng)絡(luò)(recurrent neural network,RNN)是深度學(xué)習(xí)的代表算法,但其計(jì)算密集、參數(shù)龐大的特點(diǎn)對(duì)擅長(zhǎng)處理調(diào)度的中央處理器(central processing unit,CPU)并不友好[3]。圖形處理器(graphics processing unit,GPU)的架構(gòu)雖適用于密集型計(jì)算,然而功耗太大的缺點(diǎn)導(dǎo)致其難以應(yīng)用于移動(dòng)端。專用集成電路(application specific integrated circuit,ASIC)具有低功耗、高性能的優(yōu)點(diǎn),但其研發(fā)周期長(zhǎng)、成本高,難以做到廣泛的適配?,F(xiàn)場(chǎng)可編程邏輯門陣列(field programmable gate array,F(xiàn)PGA)兼?zhèn)銰PU和ASIC的優(yōu)勢(shì),且可根據(jù)不同算法的運(yùn)算邏輯靈活設(shè)計(jì)對(duì)應(yīng)的硬件電路。故在FPGA上設(shè)計(jì)的CNN、RNN加速器將更適于實(shí)際的開發(fā)場(chǎng)景。
在硬件加速研究領(lǐng)域,Kowsaly提出了一種可替代傳統(tǒng)二叉樹加法器的新加法器,進(jìn)一步降低了硬件利用率,從而顯著提升了CNN在FPGA上的運(yùn)行效率[4]。張強(qiáng)使用高層次綜合(high-level synthesis,HLS)對(duì)CNN各層進(jìn)行定制化編程,并利用流水線約束實(shí)現(xiàn)硬件加速,對(duì)比于單CPU部署方案效率提升了約14.7倍[5]。余運(yùn)俊等采用剪枝的方法對(duì)長(zhǎng)短期記憶神經(jīng)網(wǎng)絡(luò)(long short-term memory,LSTM)進(jìn)行精簡(jiǎn)壓縮,并最終實(shí)現(xiàn)了低功耗下相對(duì)較高性能的LSTM加速器[6]。近年來,許多研究者將CNN和RNN應(yīng)用于心音分類領(lǐng)域,取得了良好的分類效果[7,8]。LSTM神經(jīng)網(wǎng)絡(luò)是一種特殊的RNN,在語音、自然語言處理等領(lǐng)域有不可替代的作用。Deng M等結(jié)合了CNN和LSTM兩種網(wǎng)絡(luò)架構(gòu),首次在心音信號(hào)分類過程中采用遞歸卷積神經(jīng)網(wǎng)絡(luò)(recurrent convolutional neural network,CRNN),達(dá)到了目前效果最好的分類準(zhǔn)確率[9]。雖然目前已有不少研究者設(shè)計(jì)了基于FPGA的定制化CNN或LSTM加速器,但缺少兼?zhèn)銫NN和LSTM優(yōu)勢(shì)的CRNN硬件加速器。此外,定制化的加速器無法兼容不同網(wǎng)絡(luò)結(jié)構(gòu),且具有硬件占用率高、模型加載延時(shí)長(zhǎng)的缺點(diǎn)。
為解決上述問題,本文設(shè)計(jì)了一個(gè)基于FPGA的CRNN硬件加速器,該加速器的CNN加速模塊可根據(jù)不同網(wǎng)絡(luò)結(jié)構(gòu)進(jìn)行動(dòng)態(tài)配置,并將此加速器實(shí)際應(yīng)用于心音分類系統(tǒng)中的分類部分。根據(jù)卷積層和LSTM層的運(yùn)算特點(diǎn),通過采用參數(shù)量化、交錯(cuò)緩存、分片緩存、滑動(dòng)窗機(jī)制及HLS指令優(yōu)化等方法,在性能與功耗上取得了較好的加速效果。
CRNN的網(wǎng)絡(luò)結(jié)構(gòu)非常靈活,其可由卷積層、LSTM層、池化層、全連接層4種通用部分組合構(gòu)成。對(duì)于傳統(tǒng)卷積神經(jīng)網(wǎng)絡(luò)而言,卷積層計(jì)算量占整個(gè)卷積神經(jīng)網(wǎng)絡(luò)計(jì)算量的90%以上[10]。CRNN中除了卷積層以外,LSTM層中大量的向量矩陣乘法運(yùn)算同樣需要消耗很大的算力。因此,CRNN硬件加速的核心在于卷積層和LSTM層。
卷積層由若干卷積核構(gòu)成,目的是從輸入特征圖中提取更高級(jí)的特征。卷積核在輸入特征圖上滑動(dòng)并與窗口內(nèi)的像素點(diǎn)進(jìn)行內(nèi)積運(yùn)算得到下一級(jí)特征圖。卷積核實(shí)際上是一種離散濾波器,濾波器參數(shù)即權(quán)值。卷積層運(yùn)算的偽代碼如代碼1所示。
代碼1:卷積層前向計(jì)算偽代碼。
for(n=0;n for(h=0;h for(w=0;w { newsum=0; for(m=0;m for(j=0;j for(k=0;k sum+=Fin[h+j][w+k][m]*kernel[j][k][m][n]; Fout[h][w][n]=sum; } 從算法角度來講,一次完整的卷積層運(yùn)算需要對(duì)N、H、W、M、K、J共6個(gè)維度進(jìn)行循環(huán)遍歷(一般情況下J=K)。但實(shí)際上這6層循環(huán)之間互不依賴,調(diào)換順序也毫無影響,故可以根據(jù)加速器算力峰值、硬件利用率、邏輯復(fù)雜度、最終性能等參數(shù)來選擇如何展開循環(huán)以及展開到什么程度。通俗來講,就是選擇并行度類型以及并行度大小。常見的并行度類型如圖1所示[11]。 圖1 常見的卷積層并行度類型 (1)輸入通道并行,如圖1(a)所示。將代碼1中的輸入通道循環(huán)部分展開,同時(shí)計(jì)算PM個(gè)輸入通道的數(shù)據(jù),因而并行度為PM。 (2)輸出通道并行,如圖1(b)所示。將代碼1中的輸出通道循環(huán)部分展開,同時(shí)計(jì)算PN個(gè)輸入通道的數(shù)據(jù),因而并行度為PN。 (3)卷積核內(nèi)并行,如圖1(c)所示。將代碼1中的卷積核行于列循環(huán)部分展開,同時(shí)計(jì)算PK個(gè)輸入通道的數(shù)據(jù),因而并行度為PK。 LSTM神經(jīng)網(wǎng)絡(luò)由Sepp Hochreiter等于1997年首次提出,它獨(dú)特的設(shè)計(jì)結(jié)構(gòu)能夠存儲(chǔ)任意時(shí)間段內(nèi)的長(zhǎng)期依賴關(guān)系。LSTM由細(xì)胞狀態(tài)、輸入門、輸 入調(diào)制門、遺忘門以及輸出門5個(gè)部分組成,其中每個(gè)門包括一個(gè)向量矩陣乘法加權(quán)操作和一個(gè)使用激活函數(shù)的操作。細(xì)胞狀態(tài)的作用是讓LSTM能夠保持長(zhǎng)期的記憶;門結(jié)構(gòu)的作用是在每一時(shí)刻決定哪些信息應(yīng)該保留,哪些信息需要遺忘。在信息傳遞過程中,LSTM通過門限機(jī)制對(duì)上一時(shí)刻細(xì)胞狀態(tài)、當(dāng)前時(shí)刻輸入和上一時(shí)刻隱藏狀態(tài)進(jìn)行處理從而達(dá)到刪除或者增加信息的目的。 圖2 LSTM層內(nèi)部結(jié)構(gòu) 如圖2所示,LSTM神經(jīng)網(wǎng)絡(luò)的前向計(jì)算流程主要分為:忘記階段、選擇記憶階段、輸出階段[12]。忘記階段首先需要計(jì)算遺忘門的輸出ft,再根據(jù)計(jì)算結(jié)果對(duì)上一時(shí)刻輸入的細(xì)胞狀態(tài)ct-1進(jìn)行選擇性忘記。該階段的計(jì)算公式為式(1) ft=sigmoid(Wfxxt+Wfhht-1+bf) (1) 選擇記憶階段首先需要通過計(jì)算輸入門的輸出it來對(duì)當(dāng)前時(shí)刻輸入xt進(jìn)行選擇性記憶,然后再計(jì)算輸入調(diào)制門的輸出gt,最后綜合考慮上一階段沒有忘記的信息以及本階段選擇記憶的新信息,完成當(dāng)前時(shí)刻的細(xì)胞狀態(tài)ct的更新。該階段的算公式為式(2)~式(4) it=sigmoid(Wixxt+Wihht-1+bi) (2) gt=tanh(Wgxxt+Wghht-1+bg) (3) ct=ft⊙ct-1+it⊙gt (4) 輸出階段首先需要計(jì)算輸出門的輸出ot,然后再計(jì)算當(dāng)前時(shí)刻細(xì)胞狀態(tài)ct經(jīng)過tanh激活函數(shù)后的縮放輸出,最后綜合考慮決定當(dāng)前時(shí)刻隱藏狀態(tài)ht。該階段的計(jì)算公式為式(5)、式(6) ot=sigmoid(Woxxt+Wohht-1+bo) (5) ht=ot⊙tanh(ct) (6) 傳統(tǒng)的FPGA開發(fā)是使用VHDL/Verilog硬件描述語言進(jìn)行硬件電路設(shè)計(jì)的,該方法開發(fā)效率低、實(shí)現(xiàn)難度大。HLS可將C/C++直接綜合為VHDL或者Verilog,從而縮短了算法設(shè)計(jì)、驗(yàn)證以及實(shí)現(xiàn)的開發(fā)周期。本文實(shí)驗(yàn)將采用HLS開發(fā)方法對(duì)硬件電路進(jìn)行模塊化設(shè)計(jì),并對(duì)卷積層加速器和LSTM層加速器的設(shè)計(jì)與優(yōu)化思路做重點(diǎn)介紹。 2.1.1 整體架構(gòu) 網(wǎng)絡(luò)結(jié)構(gòu)中不同的卷積層往往具有不同的類型參數(shù),這些參數(shù)包括輸入輸出通道數(shù)、輸入輸出特征圖尺寸、卷積核個(gè)數(shù)及輸入通道數(shù)等。最簡(jiǎn)單的硬件電路設(shè)計(jì)策略是針對(duì)每一層卷積層做定制化設(shè)計(jì)。但定制化設(shè)計(jì)的網(wǎng)絡(luò)模型在當(dāng)前卷積層的計(jì)算完成后需要花費(fèi)數(shù)百毫秒來重新配置新卷積層,嚴(yán)重影響了整體性能。為減少加載不同卷積層的延時(shí),本文將設(shè)計(jì)具有高度兼容性的動(dòng)態(tài)可配置卷積層,按照各個(gè)類型參數(shù)取其最大值的情況來設(shè)計(jì)一個(gè)適合所有卷積層的硬件架構(gòu)。 本文設(shè)計(jì)的動(dòng)態(tài)可配置卷積層加速器整體架構(gòu)如圖3所示。直接存儲(chǔ)器訪問(direct memory access,DMA)通過HP接口訪問存儲(chǔ)在片外雙速率同步動(dòng)態(tài)隨機(jī)存儲(chǔ)器(dual date rate synchronous dynamic random memory,DDR)中的數(shù)據(jù),并將數(shù)據(jù)轉(zhuǎn)換成AXI4-Stream格式的流數(shù)據(jù)。先將當(dāng)前卷積層的全部權(quán)值通過FPGA的AXI4-Stream總線從DDR傳入片上緩存Weight_Buffer,再將輸入特征圖通過AXI4-Stream總線從DDR傳入片上緩存Input_Buffer。鑒于模型參數(shù)龐大,Input_Buffer僅存儲(chǔ)本次計(jì)算需要的數(shù)據(jù),待本次計(jì)算完成后再更新下一次計(jì)算需要的輸入特征值。數(shù)據(jù)處理模塊(data process module,DPM)從Input_Buffer中獲取輸入特征值、從Weight_Buffer中獲取權(quán)值,然后依次進(jìn)行滑動(dòng)窗乘法累加操作、輸入通道累加操作、激活函數(shù)操作,這里的激活函數(shù)選擇的是比ReLU效果更好的Leaky ReLU。計(jì)算完的輸出特征值先存入Output_Buffer中,待這一批的數(shù)據(jù)全部計(jì)算完成后,再通過AXI4-Stream總線將計(jì)算結(jié)果值從Output_Buffer傳回DDR以作為下一層卷積層的輸入特征值。Control通過AXI4-Lite接口控制卷積層加速模塊的啟動(dòng)時(shí)序以及配置其具體參數(shù)。 圖3 卷積層加速模塊架構(gòu) 2.1.2 定點(diǎn)量化 在FPGA上實(shí)現(xiàn)浮點(diǎn)運(yùn)算的資源消耗和時(shí)間代價(jià)均比定點(diǎn)運(yùn)算高[13],且CRNN模型的參數(shù)類型為32位浮點(diǎn)數(shù),如果直接儲(chǔ)存將會(huì)占用較多FPGA內(nèi)存資源,因此定點(diǎn)量化勢(shì)在必行。Int16定點(diǎn)量化能在保證計(jì)算精度的同時(shí)提高計(jì)算效率、減小內(nèi)存耗用。按照式(7)、式(8)對(duì)輸入特征值、權(quán)值以及輸出特征值進(jìn)行量化與反量化[14] (7) R=(Q-Z)×S (8) 其中,R表示浮點(diǎn)值,Q表示定點(diǎn)量化值,S表示所選定點(diǎn)量化模型中的最小刻度,Z表示所選定點(diǎn)量化模型中0的浮點(diǎn)值所對(duì)應(yīng)的量化值。本文實(shí)驗(yàn)中輸入特征值、權(quán)值、輸出特征值的數(shù)據(jù)位寬設(shè)為16 bit,其中高8位為整數(shù)位,低8位為小數(shù)位。為保留較高計(jì)算精度以及防止計(jì)算結(jié)果溢出,將中間計(jì)算值的數(shù)據(jù)位寬設(shè)為32 bit,其中高16位為整數(shù)位,低16位為小數(shù)位。 2.1.3 數(shù)據(jù)緩存 (1)Input_Buffer。以具有RGB這3個(gè)輸入通道的卷積層為例,輸入特征圖最簡(jiǎn)單的緩存方法即順序傳輸各個(gè)輸入通道內(nèi)的像素點(diǎn)至Input_Buffer,如圖4(a)所示。然而計(jì)算輸出特征值時(shí),需要遍歷所有輸入通道對(duì)卷積結(jié)果進(jìn)行累加,因此這種緩存方法會(huì)增加Output_Buffer的大小。解決方式是如圖4(b)所示的通道交錯(cuò)式緩存,該緩存方法能夠明顯減少Output_Buffer的內(nèi)存耗用。假設(shè)輸入特征圖尺寸為R×C,卷積核尺寸為K×K,CRNN模型中最大輸入通道數(shù)為M。為了同時(shí)對(duì)M個(gè)輸入通道執(zhí)行交錯(cuò)式緩存操作,故Input_Buffer應(yīng)設(shè)計(jì)為M個(gè)尺寸為K×C的Line_Buffer。 圖4 順序緩存與交錯(cuò)緩存對(duì)比 (2)Weight_Buffer。設(shè)CRNN模型中最大輸入通道數(shù)為M,最大輸出通道數(shù)為N,且卷積核尺寸為K×K??紤]到最糟糕的消耗情況,Weight_Buffer應(yīng)設(shè)計(jì)為M×N個(gè)尺寸為K×K的緩存區(qū)。 (3)Output_Buffer。設(shè)CRNN模型中最大輸出通道數(shù)為N,Output_Buffer用于緩存當(dāng)前卷積層輸出特征圖所有輸出通道上同一位置的像素點(diǎn),故Output_Buffer設(shè)計(jì)為1×N的緩存區(qū)。 2.1.4 核心運(yùn)算設(shè)計(jì) DPM是卷積層加速器的運(yùn)算核心,而滑動(dòng)窗乘法累加單元又是DMP的核心單元,接下來著重介紹一下該單元的運(yùn)算機(jī)制與并行優(yōu)化設(shè)計(jì)。 (1)滑動(dòng)窗機(jī)制。圖5(a)為輸入特征圖。如圖5(b)所示,Line_Buffer本質(zhì)是一個(gè)移位寄存器陣列,每當(dāng)捕獲到新的輸入特征值時(shí),對(duì)應(yīng)列的數(shù)據(jù)將會(huì)向上移位,并在該列插入新的輸入特征值。以此類推,直至緩存到輸入特征圖的最后三行。如圖5(c)所示,當(dāng)輸入特征圖的前兩行和前三列緩存完成后,才會(huì)觸發(fā)第一次卷積運(yùn)算。第二次觸發(fā)卷積運(yùn)算如圖5(d)所示,之后每更新3個(gè)新數(shù)據(jù),觸發(fā)一次卷積運(yùn)算。滑動(dòng)窗口負(fù)責(zé)從Line_Buffer中拾取數(shù)據(jù)并觸發(fā)卷積,設(shè)卷積核尺寸為K×K,則滑動(dòng)窗口也應(yīng)設(shè)計(jì)為窗口大小為K×K的Window_Buffer。 圖5 滑動(dòng)窗機(jī)制 (2)HLS指令優(yōu)化。本文實(shí)驗(yàn)主要使用了HLS中的PIPELINE指令和ARRAY_PARTITION指令對(duì)算法進(jìn)行優(yōu)化。循環(huán)內(nèi)層對(duì)數(shù)據(jù)的操作大致可分為3個(gè)步驟:讀取數(shù)據(jù)、計(jì)算數(shù)據(jù)、存儲(chǔ)數(shù)據(jù)。PIPELINE指令是HLS中增加硬件運(yùn)算并行度的一項(xiàng)重要的優(yōu)化技術(shù),其能將循環(huán)外層完全流水,最大程度地增加并行度從而提升系統(tǒng)的吞吐量。ARRAY_PARTITION指令可以將多維數(shù)組分割成多個(gè)獨(dú)立的模塊,從而可以在同一個(gè)時(shí)鐘周期內(nèi)讀出多個(gè)數(shù)據(jù),提高數(shù)據(jù)帶寬。假設(shè)權(quán)值數(shù)組的尺寸為N×M×K×K,并用ARRAY_PARTITION指令將其重新排列成(Cout,Cin,K×K)的3D陣列。定點(diǎn)量化后權(quán)值的數(shù)據(jù)位寬為16位,故64位的DMA傳輸模式最多可以并行4個(gè)輸入通道,也即Cin=4,相應(yīng)地,Cout=(N×M)/4。 (3)并行計(jì)算設(shè)計(jì)。由圖1知,常見的并行度類型有:輸入通道并行、輸出通道并行、卷積核內(nèi)并行。上文分析到由于數(shù)據(jù)位寬和DMA傳輸模式的限制,最多只能并行4個(gè)輸入通道,故只需要4個(gè)Window_Buffer配合Line_Buffer完成滑動(dòng)窗乘法累加計(jì)算。相應(yīng)地,輸入通道并行度PM=4。當(dāng)Line_Buffer緩存至輸入特征圖第K行及第K-1列數(shù)據(jù)后,觸發(fā)Window_Buffer內(nèi)第一次卷積計(jì)算?;瑒?dòng)窗乘法累加運(yùn)算相當(dāng)于對(duì)卷積核內(nèi)行列循環(huán)進(jìn)行展開,同時(shí)計(jì)算K×K個(gè)數(shù)據(jù),因此卷積核內(nèi)并行度PK=K×K。理論上不同卷積核之間的卷積計(jì)算相互獨(dú)立,因此在硬件資源充足的條件下,輸出通道并行度PN=N。對(duì)卷積層運(yùn)算進(jìn)行并行化設(shè)計(jì)后的偽代碼如代碼2所示。 代碼2:并行優(yōu)化后的卷積層偽代碼。 weight_typeweight[M][N] #pragmaHLSARRAY_PARTITIONvariable=weightblockfactor=4dim=1 for(i=0;i for(j=0;j for(k=0;k { #pragmaHLSPIPELINEI1=1 load_weight; } for(r=0;r for(c=0;c for(m=0;m { #pragmaHLSPIPELINEI1=ICONV line_buffer; sliding_window; conv_mac; output_stream_merge; } 2.2.1 整體架構(gòu) CRNN模型通常僅有一層LSTM,故為提高硬件電路設(shè)計(jì)效率,本文將對(duì)LSTM層執(zhí)行定制化設(shè)計(jì)方案。定制化設(shè)計(jì)的LSTM層加速器整體架構(gòu)如圖6所示,主要包括緩存區(qū)、向量矩陣運(yùn)算區(qū)、逐點(diǎn)運(yùn)算區(qū)。為方便分片緩存及后續(xù)運(yùn)算,首先將當(dāng)前時(shí)刻輸入xt和上一時(shí)刻隱藏狀態(tài)ht-1合并為一個(gè)長(zhǎng)向量Input_Vec,同時(shí)將輸入門、輸入調(diào)制門、遺忘門以及輸出門各自的權(quán)重合并為一個(gè)大的權(quán)重矩陣Weight_Mat,然后對(duì)Input_Vec和Weight_Mat執(zhí)行向量矩陣運(yùn)算,并將其計(jì)算結(jié)果傳輸?shù)紸dder_Tree組件進(jìn)行并行累加,最后加上偏置向量Bias_Vec得到向量矩陣運(yùn)算區(qū)最終運(yùn)算結(jié)果。在逐點(diǎn)運(yùn)算區(qū),根據(jù)式(1)~式(6)計(jì)算分別得到it、gt、ft、ot、ct、ht,并將當(dāng)前時(shí)刻細(xì)胞狀態(tài)ct、當(dāng)前時(shí)刻隱藏狀態(tài)ht傳輸至緩存區(qū)用于下一時(shí)刻各項(xiàng)數(shù)據(jù)的計(jì)算。 圖6 LSTM層加速模塊架構(gòu) 2.2.2 分片緩存 LSTM層參數(shù)主要包括權(quán)重矩陣Weight_Mat和輸入長(zhǎng)向量Input_Vec,其中Weight_Mat包含了Wix、Wgx、Wfx、Wox、Wih、Wgh、Wfh、Woh。由于FPGA存儲(chǔ)資源和查找表數(shù)量有限,本文將對(duì)權(quán)重矩陣和輸入長(zhǎng)向量采取分片緩存策略。如圖7所示,Input_Vec的大小為(Input_Vec+Hidden_Size),合并后的Weight_Mat的大小為(Input_Vec+Hidden_Size)×(4×Hidden_Size)。Input_Vec和Weight_Mat均被劃分為長(zhǎng)度為32的片區(qū),不足32的部分填充0補(bǔ)齊。在向量矩陣運(yùn)算過程中,將Input_Vec的每一個(gè)分片都與Weight_Mat的對(duì)應(yīng)數(shù)據(jù)相乘累加,直至遍歷完Input_Vec的全部分片。片緩存區(qū)中數(shù)據(jù)的乘法累加操作仍通過滑動(dòng)窗完成,滑動(dòng)窗口大小為1×32。向量矩陣運(yùn)算部分的偽代碼如代碼3所示,同樣使用了HLS指令中的PIPELINE與ARRAY_PARTITION指令對(duì)算法進(jìn)行并行優(yōu)化。 代碼3:LSTM層向量矩陣運(yùn)算偽代碼。 weight_typeweight[4*Hidden_Size][(Hidden_Size+Input_Vec)/32]; #pragmaHLSARRAY_PARTITIONvariable=weightblockfactor=4dim=1 for(i=0;i<4*Hidden_Size;i=i+1) for(j=0;j for(k=0;k<32;k=k+1) { #pragmaHLSPIPELINEI1=1 load_weight; } for(i=0;i<4*Hidden_Size;i=i+1) for(j=0;j for(m=0;m<(Hidden_Size+Input_Vec)/4*32;m=m+1) { #pragmaHLSPIPELINEI1=ILSTM tile_buffer; sliding_window; tile_mac; output_stream_merge; } 圖7 分片緩存 2.2.3 激活函數(shù) FPGA實(shí)現(xiàn)激活函數(shù)的常用方法有泰勒級(jí)數(shù)展開法、查找表法以及分段函數(shù)擬合法等。泰勒級(jí)數(shù)展開法擬合效果最佳,但復(fù)雜的運(yùn)算會(huì)消耗大量乘法器資源,且計(jì)算時(shí)間較長(zhǎng)。查找表法最為簡(jiǎn)單快速且不消耗乘法器,但其需要事先將不同變量對(duì)應(yīng)的函數(shù)值存入ROM中。隨著函數(shù)計(jì)算精度的提高,其所需的存儲(chǔ)資源會(huì)顯著增加。本文采用的分段函數(shù)擬合法將低階多項(xiàng)式和查找表相結(jié)合,很好地平衡了計(jì)算精度與計(jì)算時(shí)間之間的矛盾。 sigmoid函數(shù)和tanh函數(shù)的表達(dá)式如下[15] (9) (10) 利用MATLAB內(nèi)置函數(shù)polyfit分別擬合式(9)、式(10)得到sigmoid、tanh的擬合函數(shù)。因LSTM層的輸入輸出數(shù)據(jù)均量化為16位定點(diǎn)數(shù),故需對(duì)擬合函數(shù)進(jìn)行相應(yīng)倍數(shù)放大。修正后的sigmoid、tanh擬合函數(shù)見表1、表2。如若輸入數(shù)據(jù)為負(fù)數(shù),則將其轉(zhuǎn)換為補(bǔ)碼再根據(jù)式(11)求解。運(yùn)算過程中除法涉及的除數(shù)4096為2的冪次方,因而可以通過移位寄存器輕易實(shí)現(xiàn) f(x)=4096-f(65 536-x)(32 768≤x≤65 535) (11) 表2 FPGA擬合tanh函數(shù) 本文設(shè)計(jì)的遞歸卷積神經(jīng)網(wǎng)絡(luò)加速器選擇ARM+FPGA異構(gòu)SoC硬件平臺(tái)進(jìn)行開發(fā),其中FPGA作為從處理器部署CRNN加速器,ARM作為主處理器通過AXI4-Lite接口與CRNN加速器交互并控制其運(yùn)行。實(shí)驗(yàn)平臺(tái)為Xilinx公司Zynq-7000系列的ZedBoard開發(fā)板,開發(fā)環(huán)境為Vivado HLS 2019.01。PC端操作系統(tǒng)為Windows 10,其中央處理器型號(hào)為Intel Core i7-9750H CPU 2.60 GHz,其顯示適配器型號(hào)為NVIDIA GetForce GTX 1660 Ti。 本文實(shí)驗(yàn)中所使用的心音數(shù)據(jù)來自于心音挑戰(zhàn)賽數(shù)據(jù)庫,研究者可從PhysioNet網(wǎng)站上自行下載。先對(duì)心音信號(hào)進(jìn)行小波去噪,然后采用梅爾對(duì)數(shù)頻率系數(shù)(log Mel-frequency spectral coefficients,MFSC)對(duì)其進(jìn)行特征提取,最后將輸出的32×16時(shí)頻特征圖輸入到不同模型中進(jìn)行分類[16]。其中包含66 688張訓(xùn)練圖、11 724張測(cè)試圖。圖8為不同模型中心音分類算法的性能對(duì)比。實(shí)驗(yàn)結(jié)果表明CRNN-a模型對(duì)心音信號(hào)的分類效果最佳。如表3所示,模型CRNN-a除輸入層外共分為5層,分別是卷積層C1/C2、LSTM層LS3、池化層S4、全連接層F5。在PC端完成CRNN-a模型的訓(xùn)練過程后,保存訓(xùn)練參數(shù)值并對(duì)其進(jìn)行Int16定點(diǎn)量化,最后再移植到FPGA硬件平臺(tái)中。 圖8 不同模型中心音分類算法性能對(duì)比 表3 CRNN-a的網(wǎng)絡(luò)結(jié)構(gòu) 在100 MHz的時(shí)鐘頻率下,PL端的各模塊資源占用情況見表4,資源利用率見表5。卷積層中的卷積運(yùn)算和LSTM層中的向量矩陣運(yùn)算均需要使用大量乘法器,且LSTM層中的激活函數(shù)運(yùn)算還需要用到查找表,故DSP和LUT的利用率都很高。此外,卷積層和LSTM層均有規(guī)模龐大的權(quán)值矩陣和偏置向量需要緩存到BRAM中,故BRAM的利用率也很高。FF主要用于構(gòu)成移位寄存器。綜上所述,各項(xiàng)資源的利用率都很高,表明此硬件加速器架構(gòu)合理。 表4 各模塊資源占用 該硬件加速器與CPU、GPU的對(duì)比結(jié)果見表6??梢钥闯?,F(xiàn)PGA僅需0.569 ms便可完成對(duì)一張心音特征圖的識(shí)別分類工作,其識(shí)別速度是CPU的29.79倍,然而CPU 表5 資源消耗 表6 CRNN硬件加速器與CPU對(duì)比 的功耗卻是FPGA的5.89倍;該加速器雖然在識(shí)別效率方面稍遜GPU平臺(tái),但性能功耗比約為GPU的20.2倍。綜上所述,基于FPGA的CRNN加速器相比于CPU和GPU,在性能和能耗方面有巨大優(yōu)勢(shì),具有相當(dāng)?shù)膶?shí)際應(yīng)用價(jià)值。 本文以實(shí)現(xiàn)CRNN加速器為目標(biāo),采用模塊化設(shè)計(jì)的方法著重對(duì)計(jì)算量龐大的卷積層和LSTM層提出了加速方案。為了有效地實(shí)現(xiàn)卷積運(yùn)算利用了輸入通道交錯(cuò)緩存操作和滑動(dòng)窗計(jì)算機(jī)制,針對(duì)LSTM層的向量矩陣運(yùn)算提出了分片緩存以達(dá)到分片復(fù)用、并行計(jì)算的目的,并使用PIPELINE指令將循環(huán)外層完全流水最大程度地增加并行度以及提升吞吐量,使用ARRAY_PARTITION指令對(duì)多維數(shù)據(jù)進(jìn)行再分割以提高數(shù)據(jù)帶寬。在Xilinx平臺(tái)上的驗(yàn)證實(shí)驗(yàn)結(jié)果表明,與CPU和GPU相比,該CRNN加速器在性能和功耗兼顧的情況下取得了29.79倍加速效果,以及20.2倍的高能效比優(yōu)勢(shì)。 接下來的研究應(yīng)從以下兩個(gè)方面優(yōu)化: (1)通過剪枝對(duì)權(quán)重矩陣和偏置向量做稀疏化處理,以減少DSP和BRAM資源消耗,并將剪枝后的CRNN模型映射到FPGA上。 (2)將LSTM層加速模塊設(shè)計(jì)為具有高度兼容性的動(dòng)態(tài)可配置架構(gòu)。1.2 LSTM層運(yùn)算理論
2 加速實(shí)現(xiàn)方案
2.1 卷積層加速器設(shè)計(jì)
2.2 LSTM層加速模塊設(shè)計(jì)
3 實(shí)驗(yàn)及結(jié)果分析
3.1 實(shí)驗(yàn)環(huán)境
3.2 測(cè)試數(shù)據(jù)集與網(wǎng)絡(luò)模型
3.3 結(jié)果分析
4 結(jié)束語