参考书目:《神经计算建模实战——基于brainpy》 吴思
神经网络概述
前面的笔记介绍了神经元建模和突触建模,用突触将神经元连接起来便形成了神经网络,可以完成更高级的任务。
神经网络的模型一般分为脉冲神经网络(spiking neural networks,SNNs)和发放率神经网络(firing-rate neural networks)。
脉冲神经网络建模的思路是模拟网络中所有神经元的活动,然后再考察它们在宏观上有怎样的统计规律和行为。它的优点是可以模拟每一个神经元的活性和它们发放的每一个脉冲,重现神经元的活动和交互,通过改变参数来考察网络的整体性质。其缺点在于计算消耗较大,需要建模单个神经元和神经连接。
发放率神经网络建模的思路是关心网络计算的基本原理而不是细节,将一个神经元群简化为单个发放单元,用一群神经元的平均发放率来代替这个发放单元的活动强度。大部分情况下,发放率神经网络得到的模拟结果与同一尺度下脉冲神经网络的结果相似。
1 兴奋-抑制平衡网络的定义
大量实验发现,即使是在同样的外部刺激重复呈现的条件下,大脑皮层的神经元每次产生的脉冲序列都不同。但是如果单独对皮层切片施加恒定刺激,则神经元的发放是规律的。这说明大脑中神经元的不规律发放源自于神经网络的内部性质。
Vreeswijk和Sompolinsky认为,神经网络中应当同时存在兴奋性和抑制性神经元,使得单个神经元接收到的输入的均值维持在一个很小的值而方差足够显著,促使神经元无规律发放。兴奋-抑制平衡网络(E-I balanced network)由此被提出,该网络包含两个神经元群,神经元群之间通过突触连接,一共有E2E/E2I/I2E/I2I四种情况,对网络还有如下要求:①神经元之间的连接稀疏,不同神经元接收到内部输入统计相关性很小,宏观上表现出不规律性;②一个神经元接收到的兴奋性输入与抑制性输入相抵消,使得网络中传递的兴奋和抑制电流呈现动态平衡;③ 网络内部神经元之间的连接强度相对较强,使得整个网络的活动不是被外部输入而是被网络内部突触连接产生的电流主导。其结构图如下:
2 E-I网络编程实现
用brainpy搭建E-I平衡网络,其中网络动力学系统需要继承brainpy.dyn.Network类,采用内置的LIF模型建模神经元,ExpCOBA模型建模突触,设置兴奋性神经元和抑制性神经元的比为4:1,编写代码如下:
import brainpy as bp
import brainpy.math as bm
import matplotlib.pyplot as plt
import numpy as np
class EINet(bp.dyn.Network): #网络动力学系统需继承bp.dyn.Network
def __init__(self,num_exc,num_inh,method='exp_auto',**kwargs):
super(EINet,self).__init__(**kwargs)
#搭建神经元
pars = dict(V_rest = -60.,V_th=-50.,V_reset = -60.,tau=20.,tau_ref=5.)#神经元模型所需参数
self.E = bp.neurons.LIF(num_exc,**pars,method=method)#**pars:传入神经元模型的参数
self.I = bp.neurons.LIF(num_inh,**pars,method=method)
self.E.V.value = bm.random.randn(num_exc)*4. - 60.
self.I.V.value = bm.random.randn(num_inh)*4. - 60.#随机初始化膜电位
#搭建神经元连接
E_pars = dict(g_max=0.3,tau=5.,method=method)
I_pars = dict(g_max=3.7,tau=10.,method=method)
self.E2E = bp.synapses.Exponential(self.E,self.E,bp.conn.FixedProb(prob=0.02),
output=bp.synouts.COBA(0.),**E_pars)
self.E2I = bp.synapses.Exponential(self.E,self.I,bp.conn.FixedProb(prob=0.02),
output=bp.synouts.COBA(0.),**E_pars)
self.I2I = bp.synapses.Exponential(self.I, self.I, bp.conn.FixedProb(prob=0.02),
output=bp.synouts.COBA(-80.), **I_pars)
self.I2E = bp.synapses.Exponential(self.I, self.E, bp.conn.FixedProb(prob=0.02),
output=bp.synouts.COBA(-80.), **I_pars)#将gmax tau等参数传入
定义突触后,采用brainpy.conn.FixedProb类来生成随机连接,模拟计算平均发放率r:
net = EINet(3200,800)#输入num_exc与num_inh
runner = bp.dyn.DSRunner(net,monitors=['E.spike','I.spike','E.input','I.input','E.V'],
inputs=[('E.input',12.),('I.input',12.)])
runner(200.)
#定义可视化脉冲发放的函数
def raster_plot(spikes,title):
t,neu_index = np.where(spikes) #脉冲发放位置
t = t * bm.get_dt()
plt.scatter(t,neu_index,s=0.5,c='k')
plt.title(title)
plt.ylabel('neuron index')
#定义可视化平均发放速率的函数
def fr_plot(t,spikes):
rate = bp.measure.firing_rate(spikes,5.) #计算神经元组中的平均放电率
plt.plot(t,rate)
plt.ylabel('firing rate')
plt.xlabel('t(ms)')
fig,gs = plt.subplots(2,2,gridspec_kw={'height_ratios':[3,1]},figsize=(12,8),sharex='all')
plt.sca(gs[0,0])
raster_plot(runner.mon['E.spike'],'Spike of Excitatory Neurons')
plt.sca(gs[0,1])
raster_plot(runner.mon['I.spike'],'Spikes of Inhibitory Neurons')
plt.sca(gs[1,0])
fr_plot(runner.mon.ts,runner.mon['E.spike'])
plt.sca(gs[1,1])
fr_plot(runner.mon.ts,runner.mon['I.spike'])
plt.show()
模拟结果如下:
刚开始的时候,所有神经元受到外部电流的影响同时产生发放,发放率突增。之后由于内部电流占主导,神经元受到兴奋与抑制大致平衡的输入,呈现不规律发放的模式,发放率出现波动。
3 E-I网络的计算功能
3.1 对外部刺激呈现线性反应
E-I网络的发放率随着外部电流的输入线性变化,可以认为外部刺激的强度被线性编码在网络的发放率中。下面利用scikit-learn中线性分析工具,对发放率和外部输入强度的关系进行考察:
import sklearn
from sklearn import linear_model
#构造分段电流
dur_per_I = 5000.
Is = np.array([5.,10.,15.,20.,25.,30.,35.,40.,45.,50.,55.,60.,65.,70.,75.,80.,])
inputs,total_dur = bp.inputs.constant_input([(Is[0],dur_per_I),(Is[1],dur_per_I),(Is[2],dur_per_I),(Is[3],dur_per_I),
(Is[4],dur_per_I),(Is[5],dur_per_I),(Is[6],dur_per_I),(Is[7],dur_per_I),
(Is[8],dur_per_I),(Is[9],dur_per_I),(Is[10],dur_per_I),(Is[11],dur_per_I),
(Is[12],dur_per_I),(Is[13],dur_per_I),(Is[14],dur_per_I),(Is[15],dur_per_I),
])
net = EINet(3200,800)
runner = bp.dyn.DSRunner(net,monitors=['E.spike','I.spike'],
inputs=[('E.input',inputs,'iter'),('I.input',inputs,'iter')])
runner(total_dur)
def fit_fr(neuron_type,color):
#计算各个电流下网络稳定后的发放率
firing_rates=[]
for i in range(16):
start = int((i*dur_per_I+100)/bm.get_dt()) #从每一阶段的第100ms开始算
end = start+int(400/bm.get_dt())#共选取400ms
firing_rates.append(np.mean(runner.mon[neuron_type+'.spike'][start:end]))#计算平均发放率
firing_rates = np.asarray(firing_rates)
plt.scatter(Is,firing_rates,color=color,alpha=0.7)
#使用sklearn线性回归工具进行线性拟合
model = linear_model.LinearRegression() #线性拟合
model.fit(Is.reshape(-1,1),firing_rates.reshape(-1,1))
#reshape(-1,1)表示将数组转为n行1列的矩阵
x = np.array([0.,85.])
y = model.coef_[0]*x+model.intercept_[0]
plt.plot(x,y,color=color,label=neuron_type+' neurons')
fit_fr('E','r')
fit_fr('I','b')
plt.xlabel('external input')
plt.ylabel('Mean firing rate')
plt.legend()
plt.show()
得到E神经元和I神经元的发放率随外部刺激变化的图像如下:
根据拟合结果,E-神经元和I-神经元发放率随外部电流输入线性增加。
3.2 更快速地跟踪外部刺激的变化
对于单神经元而言,外部刺激增强,其发放率会升高,但受神经元时间常数的限制,膜电位的上升需要时间,神经元表现出的对外部刺激的跟踪速度较慢。然而,在兴奋-抑制平衡网络中,每一时刻总有一些神经元的膜电位处于阈值边缘,外部电流的微小增加就能让它们产生发放,从而将这一变化反映到整个网络中。这种快速跟踪外部信号的特点很可能被大脑利用,以完成对外界的快速反应和识别。此外,另一些研究也发现,这样的网络也可以支持信息传递,在合理的参数设置下,信息可以在这样的噪声中完成多级传递。