劉明 曹銀杰 耿相珍 胡衛(wèi)生
摘? 要: 針對微控制器芯片尚未存在使用神經(jīng)網(wǎng)絡處理時序信號的現(xiàn)狀,提出一種可以在微控制器上進行神經(jīng)網(wǎng)絡訓練、預測時序信號的方法。 該方法不基于操作系統(tǒng)運行神經(jīng)網(wǎng)絡程序,無法由操作系統(tǒng)進行棧區(qū)空間大小的調(diào)整以及內(nèi)存的分配問題,為了解決這個問題,更改了初始化棧區(qū)空間的大小,增加了外部擴展SDRAM芯片,使之達到適合神經(jīng)網(wǎng)絡程序運行的大小。在微控制器芯片實現(xiàn)神經(jīng)網(wǎng)絡的方法包括定義了實現(xiàn)神經(jīng)網(wǎng)絡需要的矩陣運算,使用C語言編寫并封裝LSTM循環(huán)神經(jīng)網(wǎng)絡前向傳播函數(shù),反向傳播函數(shù),以及LSTM循環(huán)神經(jīng)網(wǎng)絡的權(quán)重更新函數(shù)。調(diào)用封裝好的LSTM循環(huán)神經(jīng)網(wǎng)絡函數(shù)進行實驗,以時序信號sin x函數(shù)為例,預測信號變化。故使用該方法,可不依賴操作系統(tǒng)在微控制器芯片建立神經(jīng)網(wǎng)絡,具備了穩(wěn)定、實時可靠的優(yōu)點。
關(guān)鍵詞: 微控制器芯片; 神經(jīng)網(wǎng)絡; LSTM; 棧區(qū)空間; 內(nèi)存分配; 時序信號處理
中圖分類號: TN711?34; TP39? ? ? ? ? ? ? ? ? ? ?文獻標識碼: A? ? ? ? ? ? ? ? ? ? ?文章編號: 1004?373X(2020)22?0001?05
Abstract: In allusion to the fact that there is no current situation of using neural network to process timing signals on microcontroller chips, a method of neural network training and predicting timing signals on microcontroller is proposed. In this method, the neural network program is not operated based on the operating system, and the adjustment of the size of the stack space and the memory allocation cannot be performed by the operating system. On this basis, the size of the initial stack area is changed, and the external extended SDRAM chip is added, so as to make the microcontroller chips suitable for the size of the neural network program to run. The method of implementing neural network on microcontroller chip includes the definition of the matrix operation needed to realize the neural network, writing and packaging LSTM (Long Short?Term Memory) recurrent neural network forward propagation function, back propagation function, and weight update function of LSTM recurrent neural network. The encapsulated LSTM recurrent neural network function is called to perform experiments, and the timing signal sin x function is taken as an example to predict the signal changes. In this method, the neural network can be established in the microcontroller chip without operating system, which has the advantages of stability, real?time reliability.
Keywords: microcontroller chip; neural network; LSTM; stack area; memory allocation; timing signal processing
0? 引言
在2018年中國國際嵌入式大會上,何積豐院士提出,人工智能存在向嵌入式系統(tǒng)遷移的趨勢[1]。在嵌入式系統(tǒng)上玩轉(zhuǎn)人工智能,是這個智能化時代前沿的研究。目前嵌入式系統(tǒng)人工智能主要使用Cortex?A系列微處理器芯片,A系列微處理器芯片主要面向手機、平板電腦等民用商品,屬于消費類電子,實現(xiàn)人工智能需要依賴操作系統(tǒng),不具備穩(wěn)定性,不適合應用在軍事、工業(yè)、信號處理等領(lǐng)域。Cortex?C系列微控制器芯片是單一功能的、更加專業(yè)的芯片,具備低功耗、低成本、實時、穩(wěn)定可靠的特性,被廣泛應用在軍事、工業(yè)、信號處理等方面,但目前還未發(fā)現(xiàn)在微控制器芯片上建立神經(jīng)網(wǎng)絡,做人工智能的研究。
循環(huán)神經(jīng)網(wǎng)絡算法是神經(jīng)網(wǎng)絡算法的一種,常用來學習、識別、預測時序信號,若能在Cortex?C系列微控制器芯片上搭建循環(huán)神經(jīng)網(wǎng)絡,只需要輸入信號,用理想輸出作為監(jiān)督學習,多次訓練后,即可進行信號智能處理、信號智能識別、信號智能預測等工作。使用Cortex?C系列微控制器芯片搭建循環(huán)神經(jīng)網(wǎng)絡,處理時序信號,更加智能、穩(wěn)定可靠。搭建循環(huán)神經(jīng)網(wǎng)絡需要進行一系列矩陣運算,Cortex?M系列微控制器芯片已經(jīng)具備DSP指令,所有的DSP指令都可在一個機器周期內(nèi)完成,提高了矩陣運算速度。本文結(jié)合當前的研究現(xiàn)狀提出一種針對Cortex?M系列微控制器芯片建立的循環(huán)神經(jīng)網(wǎng)絡方法,使用循環(huán)神經(jīng)網(wǎng)絡對時序信號進行學習,并預測未來的信號。
1? LSTM循環(huán)神經(jīng)網(wǎng)絡
對于時間信號的預測,常常使用循環(huán)神經(jīng)網(wǎng)絡(Recurrent Neural Network),簡稱RNN神經(jīng)網(wǎng)絡。一個簡單的RNN神經(jīng)網(wǎng)絡可以表示為圖1a)的形式。圖1a)中,[x]表示輸入向量;[O]表示輸出向量;[U]表示輸入層到隱含層的權(quán)重矩陣;[V]表示隱含層到輸出層的權(quán)重矩陣;[S]表示隱含層的值;[W]表示隱含層的值到下一個時刻隱含層的值的權(quán)重矩陣[2]。
為了更好地理解RNN神經(jīng)網(wǎng)絡,將圖1a)按時間展開,如圖1b)所示。其中,[xt-1],[xt],[xt+1]分別表示在t-1,t,t+1時刻的輸入向量;[Ot-1],[Ot],[Ot+1]分別表示在t-1,t,t+1時刻的輸出向量;[St-1],[St],[St+1]表示在t-1,t,t+1時刻的隱含層的值;[V]表示隱含層到輸出層的權(quán)重矩陣;[W]表示隱含層的值到下一個時刻隱含層的值的權(quán)重矩陣。從圖中可以看出,前向傳播公式為:
由式(1)可以看出,當前隱含層的值[St]不僅與當前時刻的輸入相關(guān),并且與之前隱含層的值相關(guān),而輸出[Ot]是[VSt]的函數(shù),所以輸出[Ot]受歷史輸入影響,這就是RNN可以處理時間序列的原因[3]。
RNN神經(jīng)網(wǎng)絡在處理長時間的信號序列時會產(chǎn)生梯度消失或梯度爆炸,為了克服這個缺點,將RNN進行改進,在RNN的基礎(chǔ)上,加入長期狀態(tài)C,用來保存長期狀態(tài),從而達到解決RNN梯度消失和梯度爆炸的缺陷,改進后的RNN神經(jīng)網(wǎng)絡被稱作LSTM(Long Short?Term Memory)神經(jīng)網(wǎng)絡[4]。LSTM中主要使用3個門,分別是遺忘門、輸入門、輸出門以及即時狀態(tài)來控制長期狀態(tài)。遺忘門負責決定之前的長期狀態(tài)對當前的長期狀態(tài)影響程度;輸入門與即時狀態(tài)共同負責決定當前輸入對長期狀態(tài)的影響程度;輸出門決定當前長期狀態(tài)對輸出的影響程度[5]。LSTM神經(jīng)元如圖2所示。
前向傳播過程需要計算遺忘門輸出[ft],輸入門輸出[it],即時狀態(tài)輸出[C′t]以及輸出門輸出[Ot]。長期狀態(tài)[Ct]由遺忘門輸出[ft]、輸入門輸出[Ot]、即時狀態(tài)輸出[C′t]和上一時刻的長期狀態(tài)[Ct-1]共同決定。
2? 實現(xiàn)LSTM循環(huán)神經(jīng)網(wǎng)絡
Cortex?M系列芯片具有穩(wěn)定可靠、實時、低成本、低功耗的優(yōu)點,被廣泛應在工業(yè)控制、軍事、信號處理等領(lǐng)域。由于Cortex?M系列微控制器芯片在建立神經(jīng)網(wǎng)絡時,不能由操作系統(tǒng)自動分配內(nèi)存以及棧區(qū)空間,為了確保神經(jīng)網(wǎng)絡程序能夠正常運行,需要人為擴展內(nèi)存及擴大棧區(qū)空間。
Cortex?M系列芯片一直被定位在低性能端,但是仍然比許多傳統(tǒng)處理器性能強大很多,例如Cortex?M7處理器,最高時鐘頻率可以達到400 MHz。Cortex?M7處理器是針對數(shù)據(jù)處理密集的高性能處理器,具備面向數(shù)字信號處理(DSP)的指令集,支持雙精度浮點運算,并且具備擴展存儲器的功能,使用搭載Cortex?M7處理器的芯片,實現(xiàn)機器學習、人工智能,具備低功耗、低成本、穩(wěn)定可靠的優(yōu)點。
選擇以搭載Cortex?M7處理器的STM32F767IGT6芯片為例實現(xiàn)LSTM循環(huán)神經(jīng)網(wǎng)絡,STM32F7使用Cortex?M7內(nèi)核,在數(shù)字信號處理上增加了DSP指令集,大大提升了芯片的計算速度。ARM公司提供了DSP算法的庫(CMSIS_DSP),具備了部分矩陣運算的功能,減少了開發(fā)的時間以及難度,并使運算速度有了進一步的提升[6]。
2.1? ARM芯片中的矩陣運算
在STM32上實現(xiàn)LSTM,要解決矩陣、向量運算的問題。進行矩陣、向量運算,需要的內(nèi)存空間比較大,所以需要對芯片進行內(nèi)存擴展。LSTM的權(quán)重矩陣需要進行存儲,權(quán)重矩陣的維數(shù)直接關(guān)系到神經(jīng)網(wǎng)絡的學習能力,通過內(nèi)存擴展可以確保權(quán)重矩陣維數(shù)滿足需求,不會使神經(jīng)網(wǎng)絡的學習能力過低。在實現(xiàn)LSTM的過程中,用到很多矩陣運算和向量運算,使用ARM公司提供的CMSIS_DSP庫中的矩陣處理函數(shù),可以解決部分矩陣運算,提高運算速度。CMSIS_DSP庫中,用結(jié)構(gòu)體arm_matrix_instance_f32表示矩陣,結(jié)構(gòu)體的元素numRows表示矩陣的行,numCols表示矩陣的列,pData指向矩陣數(shù)組,矩陣元素為32位無符號float類型,可以滿足數(shù)據(jù)精度要求。
用arm_matrix_instance_f32結(jié)構(gòu)體定義結(jié)構(gòu)體數(shù)組,用來存放張量(由數(shù)組構(gòu)成的數(shù)組),使用張量,來存儲歷史時刻門的輸出值[7]。
CMSIS_DSP庫中有矩陣的基本運算,如矩陣的加法、轉(zhuǎn)置、乘法等,在LSTM神經(jīng)網(wǎng)絡算法中需要用到對矩陣元素的操作,例如矩陣按元素相乘,可以選擇使用for循環(huán)遍歷整個矩陣的方式訪問到每一個矩陣元素。
定義生成隨機矩陣的函數(shù),輸入值為要生成矩陣的行NumRows,列NumCols,以及這個矩陣是否被作為偏置矩陣使用。若生成權(quán)重矩陣,則使用C語言中的隨機數(shù)函數(shù)rand(),遍歷矩陣賦值隨機數(shù);若生成偏置矩陣,則將矩陣所有元素初始化為0。
無論是前向傳播還是反向傳播時,都會用到矩陣按元素相乘,但CMSIS_DSP庫中并沒有矩陣按元素相乘的函數(shù),所以需要定義。定義矩陣按元素相乘的函數(shù)為mul2,它有兩個輸入,即兩個按元素相乘的矩陣,先判斷這2個矩陣的維數(shù)是否相同。因為按元素相乘,要求2個矩陣必須維數(shù)一樣,才能進行運算。使用for遍歷矩陣中的每一個值,讓2個矩陣對應位置上的元素進行相乘,并返回相乘后的新矩陣。此時新矩陣的維數(shù)應該和輸入矩陣的維數(shù)相同。
使用兩個矩陣按元素相乘函數(shù)mul2,去構(gòu)造3個矩陣按元素相乘的函數(shù)mul3。mul3有3個輸入,首先經(jīng)前2個輸入送到mul2中進行按元素相乘,再將結(jié)果與第3個輸入放到mul2中進行計算,這樣可以獲得連續(xù)3個矩陣按元素相乘,同理可以獲得mul4,mul5。
2.2? LSTM循環(huán)神經(jīng)網(wǎng)絡的函數(shù)封裝
LSTM中用到兩個激活函數(shù)Sigmoid()和tanh(),以及它們各自的導數(shù),由于CMSIS_DSP中沒有按元素操作的函數(shù),所以這里只能選擇使用for循環(huán)遍歷矩陣中的每一個數(shù)組。定義函數(shù)SigmoidActivator,它有兩個輸入,輸入矩陣,以及模式選擇,將輸入的矩陣按元素進行計算,若mod為0,則輸出[sigmoid(x)=11-e-x],若mod為1,輸出[y′=sigmoid(x)′=y(1-y)]。同樣,定義函數(shù)TanhActivator,若mod為0,則輸出[tanh(x)=ex-e-xex+e-x],若mod為1,輸出[y′=tanh′(x)=1-y2]。
將遺忘門、輸入門、輸出門以及即時狀態(tài)的計算,封裝為一個函數(shù)calc_gate,這個函數(shù)有6個輸入,分別為輸入向量[x],權(quán)重矩陣[Wx],[Wh],偏置矩陣[b],使用sigmoid激活函數(shù)或tanh激活函數(shù)的標志,以及使用激活函數(shù)本身或使用激活函數(shù)的導數(shù)標志。函數(shù)的輸出為門的輸出或者即時狀態(tài),公式如下:
按照LSTM循環(huán)神經(jīng)網(wǎng)絡計算,在前向傳播、反向傳播過程中,使用由矩陣組成的張量進行表示,并將這些張量定義為全局變量,用來存儲歷史時刻的各個門的值,這需要較大內(nèi)存空間。由于芯片內(nèi)存空間有限,不能由操作系統(tǒng)調(diào)整內(nèi)存,這里的張量存儲門歷史時刻的值,不能設(shè)置為無限大小,根據(jù)自己內(nèi)存大小,定義最多保存N個歷史時刻的值。若存儲時刻數(shù)量已經(jīng)大于N,則將最早的數(shù)據(jù)刪除。在這里刪除最早時刻的歷史值對最后的輸出并不會產(chǎn)生較大的影響,因為最早時刻的值產(chǎn)生的影響,已經(jīng)通過影響之后的時刻,保存了下來。為了確保保存歷史時刻的值不會太少,需要增加內(nèi)存大小。
2.3? 實現(xiàn)LSTM神經(jīng)網(wǎng)絡的前向傳播
利用封裝好的LSTM循環(huán)神經(jīng)網(wǎng)絡函數(shù),實現(xiàn)前向傳播。前向傳播流程如圖3所示。
定義orward函數(shù),輸入為輸入向量,為了記錄前向傳播的次數(shù),使用全局變量times來記錄前向傳播的次數(shù),也就是時刻times。根據(jù)LSTM門的計算理論公式,編寫程序計算遺忘門、輸入門、輸出門以及即時狀態(tài)的輸出,并將輸出的結(jié)果保存到相對應的結(jié)構(gòu)體數(shù)組中的times位置。使用計算所得的遺忘門、輸出門、即時狀態(tài)的輸出以及上一時刻的長期狀態(tài),計算當前時刻的長期狀態(tài):
式中,“[?]”表示按元素相乘。此處使用之前定義好的矩陣,按元素相乘函數(shù)mul2,將[Ot],[tanh(C)]輸入mul2,輸出結(jié)構(gòu)賦值給[ht]。將LSTM神經(jīng)元的輸出[ht]保存在h_list[]中,存放位置為times,即h_list[times]。合理設(shè)置權(quán)重矩陣大小,達到既能滿足使用需求,又不超過產(chǎn)生過擬合的效果[8]。
至此,在微控制器芯片上已經(jīng)實現(xiàn)LSTM循環(huán)神經(jīng)網(wǎng)絡的前向傳播[9]。
2.4? 實現(xiàn)LSTM神經(jīng)網(wǎng)絡的反向傳播
實現(xiàn)反向傳播之前,定義誤差函數(shù)Error_fun,LSTM反向傳播使用BPTT(Back Propagation Through Time)算法,屬于監(jiān)督學習,故誤差函數(shù)有兩個輸入,一個是LSTM神經(jīng)元的輸出,另一個是理想值。CMSIS_DSP庫中有矩陣減法arm_mat_sub_f32,可以實現(xiàn)[y-y] 矩陣相減,arm_mat_scale_f32常數(shù)與矩陣的乘法函數(shù)可以實現(xiàn)[12] 與矩陣相乘。這里還需要矩陣按元素相乘,所以選擇使用for循環(huán)遍歷的方法。定義誤差函數(shù)的返回值為:
反向傳播過程中,計算量較大。程序中,由函數(shù)調(diào)用函數(shù)的情況比較多,臨時變量在函數(shù)進行調(diào)用時,需要暫存到棧區(qū)中,起始文件默認初始化的1 KB的棧區(qū)大小不能滿足使用,程序運行時,會觸發(fā)異常,導致程序不能正常運行。將起始文件中棧區(qū)的大小進行調(diào)整,使棧區(qū)的大小足夠滿足程序運行的需要,可解決這個問題。
3? 實驗與分析
在STM32F7開發(fā)板進行實驗,STM32F767IGT6本身自帶512 KB的SRAM,為滿足LSTM循環(huán)神經(jīng)網(wǎng)絡程序的正常運行,開發(fā)板上外部擴展32 MB的SDRAM芯片W9825G6KH,以及在啟動文件中進行修改,將Stack_Size EQU 0x00000400,更改為Stack_Size EQU 0x00050000,使棧區(qū)空間擴大為5 MB。
以預測sin x函數(shù)為例,在STM32F7芯片上建立LSTM循環(huán)神經(jīng)網(wǎng)絡。
1) 建立樣本集合,設(shè)置時間間隔為[Δt=π5 000],即一個周期內(nèi)取10 000個數(shù)據(jù),將連續(xù)10個點的數(shù)據(jù)作為輸入向量[x],使用10個點的數(shù)據(jù)預測第11個點的值。
2) 將輸入向量輸入到循環(huán)神經(jīng)網(wǎng)絡中進行前向傳播,因使用的BPTT反向傳播算法為監(jiān)督學習,故用sin x函數(shù)的第11個點作為監(jiān)督,與神經(jīng)網(wǎng)絡輸出值進行比對,將誤差傳入LSTM循環(huán)神經(jīng)網(wǎng)絡反向傳播進行計算,并更新權(quán)重值。
3) 將實驗結(jié)果顯示在LCD顯示屏幕上,見圖4。
根據(jù)表1部分誤差點數(shù)據(jù)顯示,預測值與實際值之間存在誤差,誤差較大的點主要集中在sin x函數(shù)的極點附近。由于使用float數(shù)據(jù)類型,只能保留7位有效數(shù)字,訓練時最高精確到小數(shù)點后6位,所以預測結(jié)果存在誤差。經(jīng)過多次實驗得出,提高訓練次數(shù),可降低誤差[12]。
4? 結(jié)? 論
本文對于如何在Cortex?M系列微控制芯片上搭建LSTM神經(jīng)網(wǎng)絡進行了介紹,并且以搭載Cortex?M7處理器的STM32F767IGT6芯片為例,實現(xiàn)了對于時間序列sin x函數(shù)的預測,預測的sin x函數(shù)與實際的sin x函數(shù)重合,由于使用的數(shù)據(jù)類型為float,有效數(shù)字最多為7位,最高精確到小數(shù)點后6位,實驗時存在誤差,可以提高訓練次數(shù),盡可能減小誤差,但誤差不可完全消除。