Running PyNN Simulations on SpiNNaker
author: Raul (Zhou Muyu)
date: 2020.07.20
Introduction
本手冊介紹使用python上的PyNN庫對基于SpiNNaker的神經(jīng)網(wǎng)絡(luò)芯片進(jìn)行開發(fā)的基礎(chǔ)。
除了基本網(wǎng)絡(luò)的搭建和介紹,還結(jié)合個人學(xué)習(xí)經(jīng)歷,盡量幫大家避免踩坑。文中個別不確定的翻譯,選擇用英文原文+個人理解翻譯結(jié)合的方式呈現(xiàn),如果錯誤,還請指正。
Installation
PyNN是一種可在多simulator(如SpiNNaker、BrainScaleS、NEURON、NEST等)上進(jìn)行神經(jīng)網(wǎng)絡(luò)模型搭建的python庫。而sPyNNaker是在PyNN基礎(chǔ)上,針對SpiNNaker板專門進(jìn)行封裝的python庫,其內(nèi)的大多數(shù)功能是對PyNN的調(diào)用,并將適用范圍縮小到SpiNNaker。
安裝可在spynnaker的GitHub官網(wǎng)可以查看到相關(guān)信息(傳送門),庫的安裝指導(dǎo)在這。
本手冊安裝spynnaker8,過程簡述如下:
1.spynnaker只在PyNN的0.9.0-0.9.4版本間運(yùn)行,所以如果電腦里有安裝過PyNN或者直接pip安裝的話,目前版本為0.9.5,需要卸載重裝。
pip install pynn==0.9.4
還需要注意的事,spynnaker在python2.7版本運(yùn)行。2.創(chuàng)建虛擬環(huán)境(如果有,或者直接在主機(jī)上裝,跳過此步)
可以使用Anaconda或Pycharm進(jìn)行環(huán)境創(chuàng)建,而Mac用戶請注意,由于Apple自帶了python2.7,并將其作為framework,所以建議重新創(chuàng)建一個python2.7的環(huán)境。
conda create --name my_name python=2.73.在新建環(huán)境中,依次安裝如下:
pip install pynn==0.9.4
pip install matplotlib
pip install sPyNNaker8
python -m spynnaker8.setup_pynn最后一步是安裝pyNN-SpiNNaker,在這里如果報(bào)錯framework問題,則使用
pythonw -m spynnaker8.setup_pynn解決。4.安裝完成后,需要對配置文件進(jìn)行設(shè)置,SpyNNaker提供了3中連接simulation的方法:直接連板子、IP連接、虛擬機(jī)模擬。這三種方法的選擇,是根據(jù)您根目錄下的“.spynnaker.cfg”文件中的"[Machine]"下的內(nèi)容決定的。
a.如果是直接連接SpiNNaker,設(shè)置如下兩項(xiàng):直連模式
其中,machineName填寫SpiNNaker的IP地址或hostname;version根據(jù)板子芯片數(shù)不同命名不同,例如48芯的對應(yīng)version為5,machineName默認(rèn)為192.168.240.1。
b.如果是IP連接的方法,設(shè)置如下:IP連接
這里為還沒有嘗試過,讀者可自行在文檔中閱讀。
c.虛擬機(jī)連接,設(shè)置如下:虛擬機(jī)連接
首先需將virtual_board設(shè)置為True(三種方式必選其一,否則error),然后對板子的規(guī)格進(jìn)行設(shè)定(這里width,height是否是表示一塊板子上的芯片排列,比如(2,2)就是4個芯片排正方形,關(guān)于這個我也不清楚)。
需要注意的事,模擬器方法無法返回?cái)?shù)據(jù),適用于DEBUG
到此安裝結(jié)束,可以到這里用個例子測試一下。
Spiking Neural Networks
生物神經(jīng)元會突然產(chǎn)生電壓的升高,而Spike就是指這種生物行為,又稱為脈沖或尖峰(下文統(tǒng)稱為脈沖)。脈沖導(dǎo)致了電荷在神經(jīng)元之間通過突觸進(jìn)行轉(zhuǎn)移。突觸連接著發(fā)送電荷的突觸前神經(jīng)元和接受電荷的突觸后神經(jīng)元,當(dāng)突觸后神經(jīng)元累積的電荷超過一定閾值,則會產(chǎn)生一次脈沖。該脈沖沿著神經(jīng)元的軸突進(jìn)行傳遞,經(jīng)過一段延遲delay后到達(dá)神經(jīng)元的突觸,使電荷傳遞到下個神經(jīng)元,以此循環(huán)。

脈沖會導(dǎo)致神經(jīng)元刺激(膜電位升高)或抑制(膜電位降低)。我們需要選擇適當(dāng)?shù)哪P蛠砟M膜電位在一段時間內(nèi)的響應(yīng),這是突觸模型的選擇。
關(guān)于SNN
盡管目前而言,非脈沖的DNN使用可微的非線性激活函數(shù)進(jìn)行堆疊,并由反向傳播進(jìn)行基于梯度的參數(shù)優(yōu)化,先進(jìn)的正則化方法的發(fā)明,再加之大型帶標(biāo)簽數(shù)據(jù)集的發(fā)展和GPU的開發(fā),DNN已擁有十分強(qiáng)大的泛化能力。但其與大腦最顯著的差別在于——信息在單元間傳播的方式,這便催生出了SNN。
在大腦中,神經(jīng)元之間的通信是通過傳播動作電位序列(脈沖序列)來完成的。單獨(dú)脈沖在時間上是稀疏餓的,因此每個脈沖都有很高的信息量,并近似擁有相同均勻的幅值(100mV,脈寬1ms)。因此SNN中的信息是通過脈沖時許川大的,包括延遲和脈沖速率。
SNN在生物學(xué)上更加現(xiàn)實(shí)直觀、更類腦;對于硬件有良好的適用性;節(jié)約能源提高效率,但由其傳遞函數(shù)不可微而無法實(shí)現(xiàn)反向?qū)W習(xí),舉步維艱。
科學(xué)動機(jī)
大腦在嘈雜的環(huán)境中識別復(fù)雜的視覺模式或聽覺目標(biāo)的能力是深層脈沖網(wǎng)絡(luò)中嵌入多個處理階段和多種學(xué)習(xí)機(jī)制的結(jié)果。
工程動機(jī)
DNN需要耗能大的高端圖形卡,脈沖在時間上稀疏的特性可制造低功耗硬件。
一般過程
1.確定編碼方式,將樣本數(shù)據(jù)編碼為脈沖序列
2.將脈沖序列Si(t)輸入SNN得到輸出脈沖序列So(t)
3.將期望輸出序列Sd(t)與So(t)對比,根據(jù)誤差調(diào)整權(quán)重w
難點(diǎn)
1.編碼方式,如何將樣本信息合理地轉(zhuǎn)化為脈沖序列進(jìn)行訓(xùn)練
2.如何設(shè)計(jì)脈沖神經(jīng)元模型,如何模擬脈沖神經(jīng)網(wǎng)絡(luò)
3.如何對序列誤差合理定義
部分解決方案
1.延遲編碼、相位編碼、Time-To-First、Spike編碼、BsA編碼
2.IF模型、LIF模型、IM模型、HH模型
一些算法
SpikeProp算法用于脈沖網(wǎng)絡(luò)誤差反向?qū)W習(xí),為了克服神經(jīng)元內(nèi)部狀態(tài)變量由于脈沖發(fā)放而導(dǎo)致的不連續(xù)性,限制網(wǎng)絡(luò)中所有層神經(jīng)元只能發(fā)放一個脈沖。
Tempotron算法認(rèn)為神經(jīng)元突觸后膜電位是所有與之相連突觸前神經(jīng)元脈沖輸入的加權(quán)和。
突觸可塑性認(rèn)為,如果兩個神經(jīng)元同時興奮,則它們之間的突觸得以增強(qiáng),即在一個時間窗口內(nèi),當(dāng)突觸后神經(jīng)元的脈沖出現(xiàn)在突觸前神經(jīng)元之后(突觸前神經(jīng)元發(fā)放脈沖后,突觸后神經(jīng)元在一定時間內(nèi)也發(fā)放脈沖),那么就會因此長時程的增強(qiáng)(該突觸權(quán)重增加),反之則引起長時程抑制(突觸權(quán)重降低)。
脈沖時序依賴可塑性STDP,強(qiáng)調(diào)發(fā)放時序不對稱的重要性,突觸權(quán)值自適應(yīng)調(diào)整。
監(jiān)督Hebbian算法
遠(yuǎn)程監(jiān)督學(xué)習(xí)ReSuMe算法
基于脈沖序列卷積的監(jiān)督學(xué)習(xí)算法,由于脈沖序列是由神經(jīng)元發(fā)放脈沖時間所構(gòu)成的離散事件集合,而導(dǎo)致函數(shù)不連續(xù),無法求導(dǎo),因此引入核函數(shù)應(yīng)用卷積將序列唯一的轉(zhuǎn)換為一個連續(xù)函數(shù):
The PyNN Neural Network Description Language
PyNN是python上搭建SNN的建模庫,它可以通過將代碼微調(diào),讓網(wǎng)絡(luò)可以在不同的simulator上運(yùn)行?;镜木W(wǎng)絡(luò)創(chuàng)建步驟如下:
1.設(shè)置simulator
2.創(chuàng)建神經(jīng)元集群Population
3.創(chuàng)建Polulation之間的投影projection
4.設(shè)置需要記錄的數(shù)據(jù)
5.運(yùn)行simulator
6.獲取并處理記錄的數(shù)據(jù)
下面通過一個簡單的示例來描述pynn創(chuàng)建網(wǎng)絡(luò)的過程:
import pyNN.spiNNaker as sim
import pyNN.utility.plotting as plot
import matplotlib as plt
sim.setup(timestep = 1.0)
sim.set_number_of_neurons_per_core(sim.IF_curr_exp,100)
pop_1 = sim.Population(1,sim.IF_curr_exp(),label='pop_1')
input = sim.Population(1,sim.SpikeSourceArray(spike_times=[0]),label='input')
input_proj = sim.Projection(input,pop_1,sim.OneToOneConnector(),synapse_type=sim.StaticSynapse(weight=5,delay=1))
pop_1.record(["spikes","v"])
simtime = 10
sim.run(simtime)
neo = pop_1.get_data(variables=["spikes","v"])
spikes = neo.segments[0].spiketrains
print spikes
v = neo.segments[0].filter(name='v')[0]
print v
sim.end()
plot.Figure(plot.Panel(v,ylabel="Membrane potential (mV)",
data_labels=[pop_1.label],yticks=True,xlim=(0,simtime)),
plot.Panel(spikes,yticks=True,markersize=5,xlim=(0,simtime)),title="Simple Example",annotations = "Simulated with {}".format(sim.name()))
plt.show()
簡單來說,該網(wǎng)絡(luò)使用的timestep為1ms,創(chuàng)建了一個單輸入源(SpikeSourceArray)在0時刻向一個單神經(jīng)元(IF_curr_exp)發(fā)放一個脈沖的網(wǎng)絡(luò)。這個連接是weighted的,從突觸前神經(jīng)元向突觸后神經(jīng)元的興奮型突觸發(fā)放一個大小為5nA的固定電流(脈沖),延遲1ms。記錄脈沖和膜電位。使用simulator運(yùn)行10ms,繪制膜電位和產(chǎn)生的脈沖圖。
PoPulation
在PyNN中,神經(jīng)元都是以Population定義的,一個Population中定義一簇具有相同屬性的神經(jīng)元。PyNN提供了大量的標(biāo)準(zhǔn)神經(jīng)元模型,最常用的就是Leaky Integrate and Fire model(LIF),在程序中使用IF_curr_exp來表示。
| 參數(shù) | 默認(rèn)值 | 含義 |
|---|---|---|
| tau_m | 20.0 ms | 膜時間常數(shù);RC電路時間常數(shù) |
| tau_refrac | 0.1 ms | 不應(yīng)期 |
| v_reset | -65.0 mV | 重置膜電位 |
| v_rest | -65.0 mV | 靜息電位 |
| v_thresh | -50.0 mV | 觸發(fā)閾值電壓 |
| tau_syn_E | 5.0 ms | 興奮型突觸時間常數(shù) |
| tau_syn_I | 5.0 ms | 抑制型突觸時間常數(shù) |
| i_offset | 0.0 nA | 偏置電流;每個時間步加入的基本輸入電流 |
| cm | 1.0 nF | 膜電容 |
PyNN支持既支持基于電流的模型,也支持基于電導(dǎo)的模型。電導(dǎo)模型在此暫不展開。神經(jīng)元模型的默認(rèn)值通過initialize函數(shù)即可修改,輸入狀態(tài)變量的名稱和修改值即可。例如(v是膜電位):
pop_1.initialize(v=-70.0)
該模型將神經(jīng)元建模為并聯(lián)的電阻和電容器,當(dāng)電荷被接收時,會在電容器中積累,但同時會通過電阻泄漏。如果沒有累積達(dá)到閾值發(fā)放脈沖,膜電位則會在一定時間后重歸靜息電位;如果累積的膜電位達(dá)到閾值,則發(fā)放一個脈沖,當(dāng)脈沖發(fā)放后,該神經(jīng)元進(jìn)入不應(yīng)期refractory period,一段時間內(nèi)無法再發(fā)送脈沖,不應(yīng)期過后,恢復(fù)正常神經(jīng)元活動。此外,使用接收的輸入電流(上例為5nA)的指數(shù)衰變對突出進(jìn)行建模,即在多個時間步內(nèi)對輸入電流(如果有)進(jìn)行累加,但同時在每一個時間步之間(無論有無輸入電流),電流呈指數(shù)衰減。輸入電流序列相同,衰減率越大,則突觸累積的電荷量越多,這相當(dāng)于減緩了突觸中電荷的泄漏。
除了神經(jīng)元模型,PyNN還有提供了很多可以用來在網(wǎng)絡(luò)中模擬輸入的實(shí)用模型,常見如下兩類:
SpikeSourceArray - 以spike_times為時間間隔發(fā)放脈沖
PyNN讓模型設(shè)為SpikeSourceArray的Population中的每一個神經(jīng)元都在相同的時間發(fā)放脈沖,所以spike_times可以是一組關(guān)于時間的向量。同時,PyNN也支持實(shí)用矩陣(array of arrays)來描述spike_times,每個矩陣定義了每個神經(jīng)元應(yīng)該在哪些時刻發(fā)放脈沖,比如:spike_times = [[0,2,4],[1,3,5]]表示第一個神經(jīng)元分別在第0、2、4時刻發(fā)放脈沖,第二個神經(jīng)元在第1、3、5時刻發(fā)放脈沖。SpikeSourcePoisson - 在隨機(jī)時刻以頻率rate(每個時間單位發(fā)放脈沖數(shù))發(fā)放脈沖。
Projection
Projection用來連接Population中的神經(jīng)元。這是一個定向連接,脈沖從源神經(jīng)元(突觸前神經(jīng)元)發(fā)放到目標(biāo)神經(jīng)元(突觸后神經(jīng)元)。Projection連接的可以是兩個相同的Population(內(nèi)連),或者是不同的(外連)。
創(chuàng)建Projection時需要設(shè)置connector參數(shù),這是用來具體決定神經(jīng)元之間的連接有哪些??梢宰约涸O(shè)置connector的規(guī)則,指定Population_1中的某些神經(jīng)元與Population_2中的某些神經(jīng)元的連接,也可以將其設(shè)置為庫里提供的幾種常用連接方式如下:
- OneToOneConnector - neuron_1_i --> neuron_2_i
- AllToAllConnector - neuron_1_i --> neuron_2_all
- FixedProbabilityConnector - 每一個突觸前神經(jīng)元都以p_connect的概率連接每一個突觸后神經(jīng)元
- FromListConnector - 用conn_list(pre_synaptic_neuron_id,post_synaptic_neuron_id,weight,delay)或(pre_synaptic_neuron_id,post_synaptic_neuron_id)來精確連接。需要注意conn_list的維度必須一致,不能出現(xiàn)比如有的帶weight有的不帶這種情況。如果包含了weight和delay參數(shù),那么將忽略通過Projection的synapse_type提供的參數(shù)。
- FixedTotalNumberConnector - 固定神經(jīng)元連接數(shù)量n_synapses,并從可能的連接中隨機(jī)抽取,并進(jìn)行替換。值得注意的是這里的連接是可以被替代的。
除此之外,在Projection中還必須定義突觸類型,這決定了突觸接收/發(fā)放脈沖的機(jī)制。有三種突觸類型(SynapseType),分別是:
Fixed synaptic weight
1.固定突觸權(quán)重weight和延時delay
synapse_type = pyNN.spiNNaker.StaticSynapse(weight = 0.75, delay = 1.0)2.用一個分布替代權(quán)值
w = pyNN.random.RandomDistribution('gamma',[10, 0.004],rng = pyNN.random.NumpyRNG(seed = 1314)) ,synapse_type = pyNN.spiNNaker.StaticSynapse(weight = w, delay = 0.5)
3.根據(jù)突觸前后神經(jīng)元之間的距離來指定延遲
synapse_type = pyNN.spiNNaker.StaticSynapse(weight = w ,delay = "0.2 + 0.01 * d")
- Short-term synaptic plasticity
pyNN目前針對此類型突觸(促進(jìn)和抑制)提供一種標(biāo)準(zhǔn)模型:depressing_synapse = pyNN.spiNNaker.TsodyksMarkramSynapse(weight = w, dealy = 0.2, U = 0.5, tau_rec = 800.0, tau_facil = 0.0) tau_rec = pyNN.random.RandomDistribution('normal',[100.0,10.0]) facilitating_synapse = pyNN.spiNNaker.TsodyksMarkramSynapse(weight = w, dealy = 0.5, U = 0.04, tau_rec = tau_rec
- Spike-timing-dependent plasticity
STDP是一個依賴于突觸連接的兩個神經(jīng)元的脈沖時間的學(xué)習(xí)方式,它的指定方式與其他模型略有不同,STDP突觸類型由單獨(dú)的權(quán)重和時間依賴組件構(gòu)成,如:stdp = pyNN.spiNNaker.STDPMechanism(weight = 0.02,delay = "0.2 + 0.01*d"\ ,timing_dependence = pyNN.spiNNaker.SpikePairRule(tau_plus=20.0, tau_minus=20.0, A_plus = 0.01, A_minus= 0.012)\ ,weight_dependence = pyNN.spiNNaker.AdditiveWeightDependence(w_min = 0, w_max = 0.04))當(dāng)一個突觸后脈沖緊跟一個突觸前脈沖發(fā)放時,就假設(shè)突觸前神經(jīng)元導(dǎo)致了突觸后神經(jīng)元發(fā)放脈沖,連接兩個神經(jīng)元的突觸權(quán)值變大,這稱為“刺激”。
如果一個突觸后神經(jīng)元在突出前神經(jīng)元發(fā)放脈沖之前發(fā)放脈沖,那么該突觸前神經(jīng)元不可能引發(fā)突觸后神經(jīng)元發(fā)放脈沖,所以此時連接這兩個神經(jīng)元的突觸權(quán)值降低,這被稱為“抑制”。
權(quán)值改變的大小取決于突觸前后神經(jīng)元發(fā)放脈沖的時間,當(dāng)兩個脈沖之間時間間隔變大時,權(quán)值呈指數(shù)倍下降,如下圖所示:
STDP
然而,不同的實(shí)驗(yàn)會根據(jù)情況突出表現(xiàn)不同的突觸行為。有些學(xué)者還提出,突觸前和突觸后脈沖的三重態(tài)和四重態(tài)之間的相關(guān)性會導(dǎo)致突出的刺激或抑制。
Random Parameters
通常而言,使用隨機(jī)權(quán)重和延遲,突觸類型權(quán)重和延遲的值被設(shè)定為RandomDistribution類,之后需要指定FromListConnector為(pre_synaptic_neuron_id,post_synaptic_neuron_id)樣式的元組。具體函數(shù)指定分布的參數(shù)與該分布本身的參數(shù)一致。RandomDistribution還可以用來指定神經(jīng)元參數(shù),初始化狀態(tài)變量等。
Recording Data
在模擬中的所有Population都可以被記錄,可以被記錄的數(shù)據(jù)取決于模擬模型??傮w上,PyNN允許記錄每個神經(jīng)元發(fā)放脈沖的時刻spikes和膜電位v。相反,輸入模型SpikeSourceArray、SpikeSourcePoisson只允許記錄spikes。在SpiNNaker中,模型還額外允許使用gsyn記錄神經(jīng)元輸入。從技術(shù)上說,PyNN允許將其保留為在支持該功能的模型(如IF_cond_exp)中記錄突觸電導(dǎo),同樣也允許在IF_curr_exp之類的模型中記錄突觸電流。
Running the Simulation
當(dāng)模型搭建完成并選擇好需要記錄的數(shù)據(jù)后,可以使用run函數(shù)來開始模擬。run函數(shù)可以依次調(diào)用多次來繼續(xù)運(yùn)行,在每一次run的間隔中,可以更改網(wǎng)絡(luò)參數(shù)。目前,SpiNNaker只支持更改Population的參數(shù)如更改i_offset來調(diào)整輸入的神經(jīng)元。同時也可以取出運(yùn)行之間記錄的數(shù)據(jù)。
還可以調(diào)用reset函數(shù)來將模擬重調(diào)回0時刻,之后可以在SpiNNaker模擬中進(jìn)行更多的更改如增加Population和Prijection等。需要注意的是,這些改動會導(dǎo)致網(wǎng)絡(luò)重新進(jìn)行一遍完整的映射,這將比修改參數(shù)花費(fèi)更多時間。
Retrieving and Plotting Data
一旦運(yùn)行模擬,Population的get_data方法就可以用來取回記錄的數(shù)據(jù),這些數(shù)據(jù)會以一個Neo對象的形式保存。每個Neo對象都會有一個重置段(segment)列表,每個重置運(yùn)行周期一個segment,也就是說如果程序沒有調(diào)用reset函數(shù),則Neo段列表只有一個segment。脈沖數(shù)據(jù)spikes可以通過.segents[i].piketrains屬性來獲取。在Population的每一個神經(jīng)元中都有一個SpikeTrain,每一個SpikeTrain可以是一個描述神經(jīng)元在整個模擬過程中的哪些時刻發(fā)放脈沖的numpy向量。
cell.record("spikes") # record the spikes data
cell_neo = cell.get_data("spikes") # return a Neo object
cell_neo.segments[0].spiketrains # spikes data
其他數(shù)據(jù)可以通過調(diào)用segments[0].filter(name = <signal_name>)的方法獲得,signal_name就是希望獲取的數(shù)據(jù)名,比如膜電位v等。該方法返回一個AnalogSignalArray對象組成的列表,而就SpiNNaker而言,這個列表中只會有一個元素,因?yàn)樗械臄?shù)據(jù)都被組合成一個向量,因此第"0"個總是被使用(如segments[0].filter(name = 'v')[0])。AnalogSignalArray依次包含一個AnalogSignalArray對象列表,每個神經(jīng)元一個。每一個子列表包含一個信號每一個時間步長的值。SpikeTrain和AnalogSingalArray對象都擴(kuò)展了Quanties列表,這意味著它們也隨值的單位一起提供了。SpikeTrain的值都是毫秒為單位,膜電位都是毫伏。這些對象還包含了其他元數(shù)據(jù)。
Neo.segments[0].spiketrains和Neo.segments[0].filter(name = < >)[0]的結(jié)果都可以被傳遞給pyNN.utility.plotting.Panel來做圖。spynnaker8.spynakker_plotting包含了一個SpynakkerPanel對象,它還可以以稍微快一些的速度繪制脈沖時序圖,顯示模擬信號數(shù)據(jù)的heatmap。
Using PyNN with SpiNNaker
當(dāng)使用SpiNNaker時,延遲的范圍在1個時間步(timesteps)到144個時間步之間,因此當(dāng)時間步為1.0ms時,delay的范圍是1.0ms到144.0ms;當(dāng)時間步為0.1ms時,delay的范圍時0.1ms到14.4ms。
SpiNNaker板子上每個核默認(rèn)的神經(jīng)元大小為255個,當(dāng)超過這個大小時,板子會通過軟件自動將其分為255個神經(jīng)元一組的塊。注意核還會用來做其他事,比如輸入資源、延遲拓展(當(dāng)有任意一個delay超過16個時間步)、減少神經(jīng)元可用的核數(shù)。
STDP in PyNN
使用STDP創(chuàng)建網(wǎng)絡(luò)的步驟和上文描述的基本相同,最主要的區(qū)別在于這些Projection需要使用STDPMechanism來描述突觸可塑性。下面是一個使用STDP創(chuàng)建Projection的例子:
timing_rule = pynn.spiNNaker.SpikePairRule(tau_plus = 20.0, tau_minus = 20.0, A_plus = 0.5, A_minus = 0.5)
weight_rule = pynn.spiNNaker.AdditiveWeightDependence(w_max = 5.0, w_min = 0.0)
stdp_model = pynn.spiNNaker.STDPMechanism(timing_dependence = timing_rule, weight_dependence = weight_rule, weight = 0.0, delay = 5.0)
stdp_projection = pynn.spiNNaker.Projection(pre_pop, post_pop, pynn.spiNNaker.OneToOneConnector(), synapse_type = stdp_model)
首先創(chuàng)建時間規(guī)則,本例中采用SpikePairRule規(guī)則,它根據(jù)突觸前后一對神經(jīng)元發(fā)放脈沖的相對時間來更新突觸權(quán)重,它有四個參數(shù),tau_plus和tau_minus描述權(quán)重的大小隨突觸前后神經(jīng)元發(fā)放脈沖的時間的推移呈指數(shù)衰減(這兩個參數(shù)是描述該指數(shù)分布的簡化參數(shù)應(yīng)該),刺激時延遲為tau_plus,抑制時延遲為tau_minus。參數(shù)A_plus和A_minus分別定義了在刺激過程中增加的最大權(quán)重和在抑制過程中減去的最大權(quán)重(描述權(quán)重變化的大?。?。
接下來創(chuàng)建權(quán)重更新規(guī)則,本例中采用AdditiveWeightDependence,它通過簡單的增加電流權(quán)重來更新突觸權(quán)值。w_max和w_min分別定義了突觸權(quán)重的最大值和最小值(描述權(quán)重上下限)。注意,實(shí)際增加或減少的大小是在時間規(guī)則中定義的,因?yàn)檫@要根據(jù)脈沖之間的時間間隔來決定變化量的大小。
除此之外,還支持MultiplicativeWeightDependence,突觸權(quán)值的改變?nèi)Q于當(dāng)前突觸權(quán)重和突觸權(quán)重極限值的差,和w_max的差別用于刺激,和w_min的差別用于抑制,接著用A_plue和A_minus的值分別乘上該差值即可得出最大的權(quán)重變化量。同樣,實(shí)際權(quán)值大小取決于時間規(guī)則和脈沖之間的時間。
時間與權(quán)重規(guī)則和延遲和時間結(jié)合在一起,形成一個描述整個所需機(jī)制的單個STDPMechanism對象。Projection仍需要指定connector策略。該connector還用于描述突觸前后神經(jīng)元之間的整體連通性。初始權(quán)重最好設(shè)置在w_min和w_max之間,如果不在也不會報(bào)錯,但當(dāng)?shù)谝淮螜?quán)重更新時,權(quán)值會自動調(diào)整到該范圍之內(nèi)。
需要注意,盡管在SpiNNaker上可以使用STDP讓很多的Projection指向同一個目標(biāo)Population,但也有一些限制,所有的Projection都必須擁有相同的規(guī)則(參數(shù)一致)。這是由于在每個核上的本地可用限制,從而減少了可為參數(shù)保留的數(shù)據(jù)量。
還需要注意的是,在SpiNNaker上使用STDP,可塑性機(jī)制當(dāng)且僅當(dāng)突觸后神經(jīng)元收到第二個突觸前神經(jīng)元發(fā)放的脈沖時才生效。因此至少擁有兩個突觸前(神經(jīng)元,這里不確定是兩個需要兩個神經(jīng)元,還是一個神經(jīng)元發(fā)放兩次脈沖)脈沖才可以激活該機(jī)制。
Getting Synaptic Data
一個Projection中聲明的權(quán)重和延遲可以通過使用Projection的get方法獲取,指定要獲取的數(shù)據(jù)項(xiàng),包括權(quán)重weight、延遲delay或STDP機(jī)制包括的參數(shù)和它們被使用的格式信息等。支持list格式,返回值由一個被選中值的元祖列表組成;array格式,每個值都以二維矩陣返回,該矩陣由發(fā)送端Population中的源神經(jīng)元和接受端Population中的目標(biāo)神經(jīng)元索引而來。在list的結(jié)果中,每個元組還包含源神經(jīng)元ID和目標(biāo)神經(jīng)元ID,作為元組的第0個和第1個值。在array結(jié)果中,缺失的連接用“NaN”代表,而有多個連接的位置的值則累加表示。
在SpiNNaker上,可以在調(diào)用PyNN的run函數(shù)前檢索投影數(shù)據(jù),但直到調(diào)用完run函數(shù)后才能檢查此數(shù)據(jù)。這是因?yàn)樵谡{(diào)用run函數(shù)前,不會生成單個連接數(shù)據(jù)。



