徐夢遙
(上海交通大學電子信息與電氣工程學院,上海 200240)
人工神經網絡(artificial neural network,ANN)近年來迅猛發(fā)展并廣泛運用于各行業(yè)[1]。ANN的一個計算單元包括多個加權輸入和一個連續(xù)可求導的激活函數,可求導的激活函數使ANN易于通過沿梯度下降的方法進行訓練[2],這樣的計算單元也被稱為人工神經元。但ANN與生物神經網絡在結構,計算,信息傳遞機制上存在較大差異,且在很多任務場景中仍無法實現更智能的功能。與傳統(tǒng)人工神經元相比,新一代脈沖神經網絡(spiking neural network,SNN)神經元在信息的表達和傳遞上更加接近生物神經元[3-4],因此作為第三代神經網絡,有望處理更復雜的任務、實現更好的性能,因而受到學術界的廣泛研究。此外,對于規(guī)模更大的深度神經網絡(deep neural net?work,DNN),脈沖神經網絡的脈沖特性能夠實現更好的能效比,占用更少的硬件資源。但由于脈沖神經網絡不可求導的激活函數和離散的信息表達方式,現有的基于梯度下降的反向傳播算法難以被用于訓練SNN[5],因此SNN尚且缺乏一個有效的訓練方法,影響了它的廣泛應用。
一個常見的訓練SNN的方法是先訓練ANN,然后將其轉換為SNN并進行權重微調[7-9]。這樣的方法普遍存在的問題是會對ANN產生很多限制,例如不得使用偏差、批量歸一化和平均池化層。Sengupta團隊[9]提出將SNN神經元輸入的最大值設置為激活閾值,但脈沖時間序列的總長度達到2000—2500,導致整個網絡的計算時間非常長。Rueckauer團隊[10]選擇輸入分布的某一個百分位作為閾值,在一定程度上降低了整個網絡的計算延遲并提高了魯棒性,但閾值的選擇缺乏有效的方法。Hu團隊[11]提出的ANN到SNN的轉換算法是目前最成功的轉換方法,但其脈沖時間序列長度非常長,計算效率較低。
另一種訓練SNN的方法是使用反向傳播進行訓練[12-13],最大的挑戰(zhàn)是脈沖神經網絡激活函數和離散脈沖時間序列是不連續(xù)且不可求導的。Wu團隊[14]第一次提出了利用空間和時間域上的反向傳播來訓練SNN,并在MNIST數據集上達到了較好的準確率。該方法的不足在于訓練的計算量非常大,導致其難以被運用在規(guī)模更大的網絡結構上。Zenke 和 Ganguli[15]設計了基于膜電位的模擬梯度函數用于反向傳播,但此方法僅針對單一時刻的脈沖,難以運用在脈沖時間序列上。Shrestha和Orchard團隊[16]使用膜電位和閾值之間的差異計算梯度,但僅在MNIST數據集上訓練了一個較小的淺層網絡,沒有訓練較大規(guī)模的網絡。
總結現有的訓練方法,訓練大型脈沖神經網絡依然存在三個尚未解決的問題:①以脈沖作為輸入和輸出的神經元模型是不可求導的,這阻礙了基于梯度下降的訓練算法的實現。②離散的脈沖時間序列使得反向傳播難以實現。③由于使用類似二進制的脈沖來表示數據,相比較傳統(tǒng)神經網絡,脈沖神經網絡對參數變化更敏感,訓練過程中可能存在難以收斂的問題。本文針對這三個問題,分別提出了解決方案。針對不可求導的脈沖神經元模型,本文設計了一種模擬神經元模型的可求導激活函數,這樣的激活函數可以保證訓練得到合理的激活閾值,對應圖1綠色部分。針對第二個離散時間序列問題,本文提出將時間維度轉換為空間維度方法,即訓練時,在空間維度上處理數據在時間維度中的相互關系。針對第三個問題,本文設計了不同的編碼與解碼層將圖片數據轉換為脈沖數據,對應圖1中藍色部分。同時,筆者開發(fā)了一個基于Pytorch的訓練深度脈沖神經網絡的框架,對應圖1整個訓練階段(Train?ing Stage)。圖1中各部分的標號代表在本文中的詳細介紹章節(jié)。訓練階段結束后會將訓練好的權重和閾值傳給測試階段,激活函數采用原始的脈沖神經元模型進行最終的準確度測試,對應圖1下半部分(Test Stage)。
圖1 論文主要工作和實驗流程
與ANN相似,脈沖神經網絡由相互連接的神經元組成,每一個神經元與上一層的若干個神經元連接,這一層的輸出又作為下一層神經元的輸入。不同于ANN輸入以數值的形式出現,SNN神經元的輸入則是脈沖時間序列,如圖2中的Prespikesx1,x2和x2表示的是一個神經元的三個輸入,他們的脈沖數量都為3,橫坐標為時間,表示每一個序列的三個脈沖都在不同的時刻到達神經元。
圖2 脈沖神經元示意圖
衰減-整合-發(fā)射(leaky-integrate-and-fire,LIF)神經元模型是廣泛用于描述脈沖神經網絡神經元的模型,在此模型中,神經元的行為類比的建模為由電容器和電阻器組成的并聯電路。
其中u是神經元膜電位,τ是膜電位衰減的時間常數。輸入電流It定義為t時刻輸入脈沖的加權總和:
其中,nl表示前一層網絡中與當前神經元相連接的權重數量,wi是前一層的第i個神經元連接到當前神經元的權重。onl-1(t-tk)是第i個神經元在tk時刻的脈沖值,可以用以下公式表示:
圖2中的LIF Neuron展現了LIF神經元的內部機制。每個脈沖oi-1(t-tk)通過相應的權重wi進行放大或縮小,以產生流入神經元的電流。輸入電流累加到神經元的膜電位u中,對應衰減-整合-發(fā)射神經元模型中的整合,但該電位隨時間常數τ隨時間呈指數減弱,對應衰減。當膜電位超過閾值Vth時,神經元會產生輸出脈沖,此時膜電位重置為ureset,否則,神經元接收輸入脈沖后只會更新膜電位,并不會產生輸出脈沖。對應衰減-整合-發(fā)射中的發(fā)射。描述以上脈沖神經元(LIF)模型的差分表達式為:
本文設計的脈沖編碼層是整個SNN的第一層。編碼層采用二進制編碼,將浮點數轉化為固定位數的二進制定點數,將初始數據壓縮至x∈(0,1),將小數點固定在二進制數的最前端,即表示整數的位數為0,所有bit都用于表示小數,例如將浮點數f=0.23224轉換為8位的二進制數0.00111011,將小數點固定在定點數的最左端,相當于把這個二進制數左移8位,得到b=00111011,這個二進制數就是編碼層產生的脈沖序列,t=0時,最高位為0,代表此時沒有脈沖,t=2時,第三高位為1,代表此時有脈沖,注意8位的二進制數意味著T=8。
本文設計的解碼層作為SNN的最后一層。如果解碼層依然采用二進制解碼,在反向傳播過程中,損失函數的導數通過這一個解碼層時,會分別乘以20,21,…,27,導數值通過該層后會有指數倍的方差,使得訓練過程中更新后的權重波動異常大而無法收斂。因此為了避免這一問題,本文在解碼層設計了一個全連接層進行解碼,此過程如圖3所示。這個全連接層有T×1維的權重,且這個權重同其他全連接層一樣,是神經網絡中可訓練的參數。
圖3 全鏈接解碼層
對于單個脈沖神經元,它的激活函數是一個階躍函數:
u是該神經元的膜電位,如圖4所示。
圖4 階躍函數
當膜電位u超過閾值Vth時,神經元便會立刻產生一個脈沖傳遞到下一層的神經元。假設Vth=0,階躍函數是不可導的函數,因此無法運用傳統(tǒng)的沿梯度下降訓練算法,因而設計一種可求導的擬激活函數即可解決上述問題:
此處的c是一個壓縮常數,當c=1,Vth=0時,這個擬激活函數就是Sigmoid函數:
當c=3,Vth=1時,如圖5黑色函數曲線所示,激活函數在x方向上被壓縮。c越大,Θ(u)函數越接近階躍函數,c越小,激活函數越平滑。
圖5 不同壓縮常數下的擬激活函數
在本實驗中,脈沖神經網絡的訓練初期將c的初始值設置為1,隨著迭代次數的增加,將c的值線性緩慢增大,從而無限逼近階躍函數,最終當c=15時,如圖5橘色函數曲線所示,平滑的激活函數已經非常趨近其原始的階躍函數,當模型訓練的損失不再減小時,即得到我們所需的模型參數,包括卷積層的卷積核權重,全鏈接層的權重和閾值Vth。激活函數對輸入u求導得到:
在實驗過程中發(fā)現,如果一層網絡的所有神經元對應不同的閾值,參數的個數會急劇增加,訓練時長也會增大,并且通過實驗結果分析得知,將每一層網絡同一個輸出通道(chanel)的神經元使用相同的閾值時的訓練結果,與使用各不相同的閾值的訓練結果相比,并沒有明顯的準確率下降。因此同一層同一個通道的神經元使用一個共同的閾值Vth。
脈沖神經元傳遞信息的機制可概括為LIF模型,在這個模型中,脈沖時間序列并沒有固定的時間間隔,本文設計的迭代模型改變了LIF的隨機性,加入固定時間步長的概念。并且具有時間維度的信息難以適應現有的神經網絡訓練框架,因此我們設計了LIF模型的迭代表達式,將時間轉變?yōu)閿祿牡谝粋€維度,也就是將時間維度刻畫為空間維度,因而可以很好的適應現有的神經網絡計算框架,例如Pytorch和TensorFlow等。以下是具體的設計思路。
首先對已有LIF模型表達式使用歐拉方法求解一階微分方程,獲得一個迭代表達式:
接下來,將神經元產生輸出脈沖信號和重置的機制加入到公式中,假設ureset=0,得到下面的狀態(tài)轉移公式:
其中,l(n)分別表示第n層的神經元數量,wnij是從第n層的第j個神經元到第n+1層的第i個神經元的權重。Θ(?)是2.2中的激活函數。以上兩個表達式表明,ot,n+1是否產生輸出脈沖會影響下一個狀態(tài)ot+1,n+1。如果神經元在時間t發(fā)出脈沖,在t+1時刻,通過(1-ot,n+1(i))這個系數,將神經元膜電位重置為0,如果t時刻未產生脈沖輸出,則將膜電位衰減成kτut,n+1。設kτut,n+1=0,即上一時刻的膜電位不會衰減后累積到下一時刻,則稱這樣的模型為整合-發(fā)射激活(IF Activa?tion)模型。
如圖6所示,t時刻,神經元沒有產生輸出脈沖,膜電位為u,乘以時間衰減因子0.8之后,累加到下一時刻的膜電位上,并在下一個時刻經過脈沖激活函數,神經元進行下一時刻的脈沖輸出。
圖6 LIF模型的迭代示意圖
在SNN訓練過程中,為了表示時間維t={1,2,…,T},我們將一個特征圖拆分為T個脈沖圖,第t個圖的任意位置(x,y)的值代表t時刻(x,y)位置的脈沖值bt(x,y),bt(x,y)∈{0,1}。如果bt(x,y)=1,則代表(x,y)位置有脈沖,若bt(x,y)=0,則代表沒有脈沖。例如,對同一個(30×30)的特征圖拆分成的T個(30×30)的脈沖圖,在卷積層都讓他們與相同的大小為3×3的卷積核進行卷積操作,stride為1,即卷積核對每一個脈沖圖都進行卷積操作。因此輸出是大小為(28×28)的T個特征圖。
全鏈接層可看為是卷積核為(1×1)的卷積層,因此全鏈接層是卷積層的一種特殊情況,類比于全鏈接層也進行同樣的運算。在Pytorch平臺的具體實現中,將脈沖序列的時間維轉換到批訓練的batch維度,即可完成上述操作。例如原來的ANN訓練中,設batch size=64,而訓練脈沖神經網絡時,同一批數據由于采用脈沖的形式表達,因此batch size=64×T。LIF迭代模型的具體實現框架如圖7所示。在每個時刻t,激活層對一個batch中所有圖的進行迭代的狀態(tài)更新操作。
圖7 LIF神經元擬激活層示意圖
實驗分為兩個階段,在訓練階段,對應圖1中Training Stage,不斷增大壓縮常數直到擬脈沖神經元激活函數趨于階躍函數并且訓練的loss不再下降時,將訓練得到的權重和閾值傳遞給測試階段(Test Stage),則用脈沖神經元LIF模型替代擬脈沖神經元激活函數,對應圖1中下半部分,最終對測試集進行準確度測試。
第一個實驗的神經網絡結構針對手寫數字數據集(MNIST)而設計,首先初始數據輸入后進行編碼,編碼層將浮點數變?yōu)?個時間步長的連續(xù)脈沖時間序列,然后依次與16、32、32和16個大小均為3×3的卷積核卷積,注意每一個卷積層后都經過一個批標準化層,然后再進入LIF激活層。在最后一個全鏈接層之前經過一個2.1中設計的全鏈接解碼層,輸出則恢復為浮點數,然后經過一個全鏈接層直至輸出,最終輸出結果。
3.1.1 訓練結果準確率分析
當設置壓縮常數為2時,圖8展示了整個訓練過程中損失和在驗證集上測試的準確度變化曲線,a圖的橫坐標為網絡訓練迭代次數,縱坐標為損失。由圖中曲線可以看出,在訓練的初始階段,loss下降非常明顯,從2.5下降到了0.5。到第50次迭代以后,訓練的loss開始緩慢的下降,在到達第200次迭代以后,訓練的loss不再明顯下降,收斂到了0.2左右。b圖的橫坐標為epoch,縱坐標為在驗證集上測試的準確度。在第1個epoch之后,準確率就已經達到了94%。在接下來的5個epoch之后,準確率已經達到了98%,最終在20個epoch之后之后,在驗證集上的準確率達到99.1%。
圖8 訓練過程的損失和準確度曲線
為避免訓練初始階段就出現因壓縮常數較大而導致梯度消失的現象,先將壓縮常數設置為較小的數,本實驗初始壓縮常數設置為2。開始訓練后,在loss到達一定的值而不再顯著下降時,再逐步增加壓縮常數的值為4,6,9,直到設置為20時停止增大壓縮常數,此時擬脈沖神經元激活函數已經非常接近LIF模型的階躍函數,在每個壓縮常數下,訓練完成后基于測試集的準確率如圖9所示。隨著壓縮常數的增大準確率呈略微下降的趨勢,但變化不明顯,均在98.7%附近。由此可以得出以下結論,即在MNIST數據集上,使用較小的壓縮常數訓練之后的結果就已經可以達到98%,不需要再使用更大的壓縮常數進行反復的訓練,可以大大降低訓練的時間成本和能耗成本。由此可知本文提出的訓練方法較為高效。
圖9 基于MNIST的脈沖神經網絡在不同壓縮常數時的準確度
將訓練好的網絡參數運用到第二階段上,最終的準確率為98.81%。與其他脈沖神經網絡在MNIST數據集上的結果比較如表2所示。相較于其他的SNN訓練結果,提升了高達8.51%的準確率。
表2 不同SNN在MNIST數據集上的準確率
續(xù)表2
3.1.2 閾值分布分析
閾值的初始值均設置為0,在經過上述不斷增大壓縮常數的訓練過程后,壓縮常數固定在20時,第一、二和四個卷積層后的LIF層閾值分布直方圖如圖10所示,此處為了使圖片顯示分布效果更好,僅展示了三個卷積層后的閾值分布。圖中各層的閾值分布方差較大,由此可以得出網絡經過本文提出的訓練方法訓練過后,各個網絡層的閾值處于一個特定的分布,從而使網絡達到較好的分類結果。
圖10 基于MNIST的脈沖神經網絡各層閾值分布直方圖
實驗二采用的網絡結構是基于CIFAR-10數據集的ResNet20[25]。本實驗在ResNet20網絡結構的框架上,設計的脈沖神經網絡如圖11所示,與原本的ResNet20的差別在于,增加了編碼層作為第一層,每一個block中有兩個卷積層,僅第一個卷積層后采用擬激活函數LIF Activation,后一個卷積層接IF Activation。
圖11 20層殘差脈沖神經網絡結構
每一批有64個樣本,動量(Momentum)設置為0.9,在每一個脈沖神經元激活層之前采用Batch Normalization[26]。從 0.1 的學習率(Learning rate)開始,在損失(Loss)隨著迭代不再顯著下降時將其除以10,并在64000次迭代時終止訓練,數據預處理[27]將原始圖像的四個邊填充4個像素,并且從填充圖像或其水平翻轉中隨機采樣并剪裁為32×32大小的圖片進行訓練。
3.2.1 訓練結果準確率分析
當設置壓縮常數為2時,圖12展示了整個訓練過程中損失和在驗證集上測試的準確度變化曲線。
圖12 基于CIFAR-10的ResNet訓練中的損失和準確度曲線
圖(a)的橫坐標為網絡訓練迭代次數,縱坐標為損失。網絡在每一個epoch完成之后,利用驗證集對網絡模型的效果進行測試,從而可以評估脈沖神經網絡訓練算法的效果。在訓練開始階段損失快速下降,到達500個迭代之后,損失在1.0附近波動。圖(b)橫坐標為epoch,縱坐標為在驗證集上測試的準確度。準確率隨著epoch增加而逐步增大,最后維持在70%附近。
當我們不斷增大壓縮常數,得到的準確率如圖13所示。隨著壓縮常數的增大準確率呈略微下降的趨勢,符合我們的預期,即輸出數據隨著激活函數趨向階躍函數而越接近0或1,從而導致準確率逐漸下降。
圖13 基于CIFAR-10的脈沖殘差神經網絡訓練準確度
3.2.2 閾值分布分析
閾值的初始值均設置為0,在經過上述不斷增大壓縮常數的訓練過程后,壓縮常數固定在13時,第1,3,11,17個卷積層后的LIF層閾值分布直方圖如圖14所示。
圖14 基于CIFAR10的脈沖神經殘差網絡各層閾值分布直方圖
最終訓練完成后,各層的閾值分布方差較大。此處為了使圖片顯示分布效果更好,僅展示了四個卷積層后的閾值分布。各個網絡層的閾值處于一個特定的分布,從而使網絡達到較好的分類結果。
傳統(tǒng)ANN中的浮點數(floating point)乘累加(multiply-accumulate,MAC)操作被SNN中的浮點數加法操作取代。與加法操作(0.9 pJ)相比,乘累加操作的功耗(4.6 pJ)是加法操作的5.1倍[28]。以下方程用于計算ANN中某一層網絡的乘累加操作數量:
其中kw代表卷積核的寬度,kh代表卷積核的高度,cin是輸入通道數,cout是輸出通道數,hout和wout是輸出特征圖的高度和寬度,nin是全鏈接層的輸入神經元個數,nout是全鏈接層輸出的神經元個數。對于相同結構的脈沖神經網絡層,加法操作的數量與脈沖個數#spikes相關:
圖15是脈沖神經網絡和傳統(tǒng)人工神經網絡在相同的網絡結構下,基于上述功耗計算公式而得出的每一層網絡的功耗對比。對于基于MNIST的脈沖卷積網絡,傳統(tǒng)人工神經網絡的能耗為395673.60 nJ,脈沖神經網絡的能耗為307930.5 nJ,與傳統(tǒng)人工神經網絡相比減少了22.18%,對于基于CIFAR-10的脈沖殘差神經網絡,傳統(tǒng)人工神經網絡的能耗為233238.4 nJ,脈沖神經網絡的能耗為173525.39 nJ,傳統(tǒng)人工神經網絡相比減少了25.61%。
圖15 脈沖神經網絡各層能耗與傳統(tǒng)神經網絡對比
脈沖神經網絡使用脈沖時間序列來傳輸數據,而脈沖神經網絡的功耗又與脈沖時間序列的時間長度和脈沖頻率息息相關,脈沖時間序列的時間長度越短,脈沖頻率越低,整個網絡計算的時間和功耗都會有所降低。表3列舉了近年來各種的脈沖神經網絡實現中脈沖時間序列的時間步長,為更公平有效的橫向對比,此處均列舉的是針對CIFAR-10數據集的脈沖神經網絡。
表3 不同SNN的脈沖時間序列長度
從表3中可以看出,本論文提出的訓練算法中,脈沖時間序列的時間步長僅僅為8個時間步長,對比Hunsberger團隊提出的時間序列長度為6000的SNN,本論文提出的SNN僅需要時間長度為8脈沖時間序列,達到了750倍的加速。相較于Garg團隊的實驗結果,即時間步長為48的脈沖時間序步,本文的脈沖時間序列也達到了6倍的加速。假設經過各個網絡的脈沖時間序列頻率相同,則功耗也會以同等比例降低。
本文設計一種新的脈沖神經元信息傳遞模型,實現了一種新的基于梯度下降的脈沖神經網絡訓練算法,提供了一種與Pytoch兼容的訓練框架。在神經網絡的常見訓練集上實現了較高的準確率,同時相較于傳統(tǒng)的人工神經網絡保證了較低的能耗。接下來的工作將會著眼于更高效的編碼和解碼方法設計。