PyNN on SpiNNaker 中文簡版指導(dǎo)手冊

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.7

3.在新建環(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)。

神經(jīng)元結(jié)構(gòu)

脈沖會導(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ù):
    S^*(t)=S(t)*k(t)=\sum_{f=1}^{F}{k(t-t^f)}

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有的不帶這種情況。如果包含了weightdelay參數(shù),那么將忽略通過Projectionsynapse_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。相反,輸入模型SpikeSourceArraySpikeSourcePoisson只允許記錄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)行更多的更改如增加PopulationPrijection等。需要注意的是,這些改動會導(dǎo)致網(wǎng)絡(luò)重新進(jìn)行一遍完整的映射,這將比修改參數(shù)花費(fèi)更多時間。

Retrieving and Plotting Data

一旦運(yùn)行模擬,Populationget_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].spiketrainsNeo.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_plustau_minus描述權(quán)重的大小隨突觸前后神經(jīng)元發(fā)放脈沖的時間的推移呈指數(shù)衰減(這兩個參數(shù)是描述該指數(shù)分布的簡化參數(shù)應(yīng)該),刺激時延遲為tau_plus,抑制時延遲為tau_minus。參數(shù)A_plusA_minus分別定義了在刺激過程中增加的最大權(quán)重和在抑制過程中減去的最大權(quán)重(描述權(quán)重變化的大?。?。

接下來創(chuàng)建權(quán)重更新規(guī)則,本例中采用AdditiveWeightDependence,它通過簡單的增加電流權(quán)重來更新突觸權(quán)值。w_maxw_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_plueA_minus的值分別乘上該差值即可得出最大的權(quán)重變化量。同樣,實(shí)際權(quán)值大小取決于時間規(guī)則和脈沖之間的時間。

時間與權(quán)重規(guī)則和延遲和時間結(jié)合在一起,形成一個描述整個所需機(jī)制的單個STDPMechanism對象。Projection仍需要指定connector策略。該connector還用于描述突觸前后神經(jīng)元之間的整體連通性。初始權(quán)重最好設(shè)置在w_minw_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)重和延遲可以通過使用Projectionget方法獲取,指定要獲取的數(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ù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容