神经元模型#
作者: MamieZhu
神经元 是神经系统中的基本构成单元,负责接收、处理和传递信息,从而参与大脑的各种计算功能。神经元的工作可以被建模为电信号的传递和处理过程,为了简化神经元的计算和模拟,提出了一系列简化的神经元模型。 本章将重点描述这些神经元的模型,分析和模拟其计算原理。
生物神经元模型#
生物神经元 是对真实神经元的观察和研究所建立的模型。这些模型试图模拟真实神经元的结构和功能,包括神经元的 电生理学 性质和生物化学特征。 这些神经元模型通常包括多个参数,如 膜电位、 阈值电位 等,这些参数根据实验数据进行调整,以使模型的行为尽可能地接近真实神经元的行为。
首先定义一个 neurai.nn.neuron.neuron.Neuron
基类,所有的生物神经元都继承这个基类。如果是自定义神经元,需要用户继承这个类进行神经元模型的扩展。下面是参数说明。
size
,int类型,表示神经元簇中的神经元数量,默认为1;
V_th
,float类型,表示神经元的电压阈值,默认为1;
V_reset
,float类型,表示神经元的复位电压,如果不是 None,则在发出脉冲后,电压将复位为V_reset。如果设置为None,则在发出脉冲后,电压将减去V_th,默认为0;
stdp_tau
,float类型,表示STDP衰减的时间窗口,默认为20;
tau_triplet
,float类型,表示长前突触追踪的时间常数,默认为110;
dendritic_delay
,可以是[int, jnp.ndarray, Initializer, Callable]中的一种类型,表示树突延迟长度,默认为1;
dendritic_delay_spike
,DelaySpike类型,表示一个脉冲延迟处理器,主要通过树突长度的时间步来延迟脉冲信息,默认为None;
dendritic_delay_trace
,DelaySpike类型,表示一个脉冲追踪延迟处理器,主要通过树突长度的时间步来延迟由后神经元脉冲形成的追踪,默认为None;
dendritic_delay_trace_triplet
,DelaySpike类型,表示一个脉冲追踪延迟处理器,主要用于stdp_triplet
类型突触,在后神经元的脉冲追踪上进行延迟处理,默认为None;
stdp_coming
,bool类型,表示是否存在与当前神经元连接的stdp类型突触,默认为False;
is_spike_binary
,bool类型,表示脉冲值的数据类型,如果数据类型为布尔型,则设置为True,否则设置为False,默认为True,这个值一般情况下不需要用户传入,正常情况下生物神经元都为True;
area_name
,str类型,表示当前神经元所属区域的名称,默认为None。
surrogate_grad_fn
,Callable类型,表示当前神经元脉冲计算函数的替代梯度的函数,默认为:class:neurai.grads.surrogate_grad.Sigmoid()
Leaky Integrate and Fire (LIF)#
LIF
是一个漏电积分-放电模型(Leaky Integrate-and-Fire)的实现,其中 膜电位 在每次突触输入到达时会跃升。达到阈值会进入绝对不应期,此时膜电位被锁定在 静息电位 。
默认情况下,在神经元处于不应期时到达的突触输入会被丢弃。突触输入会在不应期结束时被添加到膜电位中,并根据到达时间与不应期结束时间的间隔进行衰减。
其动力学通过精确积分方案 [1] 进行集成。神经元动力学是根据计算步长所确定的时间网格来解决的,传入和发出的脉冲都被迫与该网格对齐。
公式如下:
其中 \(\tau\) 为时间常数, \(V_{rest}\) 为静息电位, \(V\) 为膜电位, \(R\) 为膜电阻, \(I\) 为输入电流。 有关类似神经元模型的更多信息,可以参考文献,在文献 [1] 中有详细描述,文献 [2] 中可以找到流程图。
neurai.nn.neuron.lif.LIF
神经元除了继承 neurai.nn.neuron.neuron.Neuron
的属性之外,还有其特有的参数,并且为了方便用户设置了默认值。
v_init
,可以是[float, Initializer]中的一种类型,表示膜电位的初始值,默认为-70;
I_e
,float类型,表示输入电流,默认为0;
V_rest
,float类型,表示静息膜电位,默认为-70;
V_th
,float类型,表示神经元的电压阈值,默认为-55;
V_reset
,float类型,表示神经元的复位电压,默认为-70;
R
,float类型,表示膜电阻,默认为0.04;
tau
,float类型,表示膜时间常数,默认为10;
tau_ref
,float类型,表示不应期长度,默认为None;
method
,neurai.const.math.SolverMethodODE
类型,求解微分方程的方法,默认为SolverMethodODE.EXP_EULER
;
使用示例如下:
from neurai import nn
from neurai.const.math import SolverMethodODE
lif = nn.LIF(size=1, v_init=-55., V_rest=-60., V_th=-50., V_reset=-60., R=1, tau=20., tau_ref=None, I_e=20.0, method=SolverMethodODE.EXP_EULER)
ExpLIF#
其电压微分公式与 Leaky Integrate and Fire (LIF) 相同,
其中 \(\tau\) 为时间常数, \(V_{rest}\) 为静息电位, \(V\) 为膜电位, \(R\) 为膜电阻, \(I\) 为输入电流。
输入电流 \(I\) 中有一个指数衰减项,假设神经元所连接的多个突触指数函数,权重分别为 \(w_i\),对应的脉冲序列为 \(s_i\),电流 \(I\) 的微分方程可以表示为:
其中 \(\tau\) 为自身指数衰减的时间常数, \(n\) 为连接的突触数量。
ExpLIF
是按照文献 [3] 实现的带有指数衰减的突触后电流的漏电积分-放电模型,neurai.nn.neuron.exp_lif.ExpLIF
神经元除了继承 neurai.nn.neuron.lif.LIF
的属性之外,还有其特有的参数,
tau_syn
,float类型,表示突触时间常数,默认为2.0。
Tsodyks M, Uziel A, Markram H (2000). Synchrony generation in recurrent networks with frequency-dependent synapses. The Journal of Neuroscience, 20,RC50:1-5. URL: https://infoscience.epfl.ch/record/183402
使用示例如下:
from neurai import nn
from neurai.const.math import SolverMethodODE
explif = nn.ExpLIF(size=1, v_init=-55., V_rest=-60., V_th=-50., V_reset=-60., R=1, tau=20., tau_ref=None, I_e=20.0, tau_syn=1.5, method=SolverMethodODE.EXP_EULER)
GLIF3#
GLIF
代表文献 [4] 中的广义泄漏积分-放电模型,传入的脉冲会引起模型的后突触电流发生变化,该电流由一个alpha函数进行建模。 GLIF
是其中的一种具有脉冲后电流的模型。
Teeter C, Iyer R, Menon V. Generalized leaky integrate-and-fire models classify multiple neuron types. Nature communications, 2018, 9(1): 709. DOI: https://doi.org/10.1038/s41467-017-02717-4
neurai.nn.neuron.glif.GLIF3
神经元除了继承 neurai.nn.neuron.neuron.Neuron
的属性之外,还有其特有的参数,并且为了方便用户设置了默认值。
v_init
,可以是[float, Initializer]中的一种类型,膜电位的初始值,默认为-78.85;
I_e
,float类型,输入电流,默认为0;
V_rest
,float类型,静息膜电位,默认为-78.85;
V_reset
,float类型,脉冲后的重置电位,默认为-78.85;
V_th
,float类型,膜电位阈值,默认为0;
th_inf
,float类型,无穷大的阈值,默认为-51.68;
G
,float类型,膜电导, 默认为9.43;
C_m
,float类型,膜电容,默认为58.72;
asc_amps_init
,float或者float组成的数组类型,脉冲后电流幅度的初始值,默认为jnp.asarray([-9.18, -198.94]);
asc_decay_init
,float或者float组成的数组类型,脉冲后电流衰减的初始值,默认为jnp.array([0.003, 0.1]);
asc_r_init
,float或者float组成的数组类型,随着脉冲后电流变化的阻抗的初始值,默认为jnp.asarray([1.0, 1.0]);
tau_ref
,float类型,不应期长度,默认为3.75;
spike_th
,float类型,脉冲相关组成部分的阈值,默认为0;
method
,SolverMethodODE类型,表示求解微分方程的方法,默认为SolverMethod.EXP_EULER。
使用示例如下:
from neurai import nn
glif3 = nn.GLIF3(size=1, v_init=-55., I_e=20.0)
GLIF3PSC
是带有突触后电流处理的广义泄漏积分-放电模型,neurai.nn.neuron.glif_psc.GLIF3PSC
神经元除了继承 neurai.nn.neuron.glif.GLIF3
的属性之外,还有其特有的参数,
tau_syn
,float类型,表示突触时间常数,默认为2.0。
from neurai import nn
glif3psc = nn.GLIF3PSC(size=1, v_init=-65., I_e=10.0, tau_syn=2.0)
HH#
HH
是Hodgkin–Huxley(霍奇金-赫胥黎)在文献 [5] 中提出的神经元模型的简称,该模型包括三种类型的离子通道:钠(Na+)、钾(K+)和氯(Cl-)。
数学上,该模型的表示如下:
其中 \(\\alpha\) 和 \(\\beta\) 的计算如下:
Hodgkin AL and Huxley A F (1952). A quantitative description of membrane current and its application to conduction and excitation in nerve. The Journal of Physiology 117. DOI: https://doi.org/10.1113/jphysiol.1952.sp004764
neurai.nn.neuron.hh.HH
神经元除了继承 neurai.nn.neuron.neuron.Neuron
的属性之外,还有其特有的参数。
v_init
,可以是[float, Initializer]中的一种类型,膜电位的初始值,默认为-65.0;
c_m
,float类型,膜电容,默认为100.0;
g_L
,float类型,漏电导率,默认为30.0;
E_L
,float类型,漏电平衡电位,默认为-54.402;
g_Na
,float类型,钠电导率,默认为12000.0;
E_Na
,float类型,钠电平衡电位,默认为50.0;
g_K
,float类型,钾电导率,默认为3600.0;
E_K
,float类型,钾电平衡电位,默认为-77.0;
V_th
,float类型,阈值电位,默认为0.0;
V_reset
,float类型,脉冲后重置电位,默认为0;
I_e
,float类型,输入电流,默认为0;
tau_ref
,float类型,表示不应期长度,默认为None;
method
,neurai.const.math.SolverMethodODE
类型,求解微分方程的方法,默认为SolverMethodODE.RKF45
。
使用示例如下:
from neurai import nn
hh = nn.HH(size=1, v_init=-65., I_e=10.0)
HHPSC
是带有突触后电流处理的霍奇金-赫胥黎模型,neurai.nn.neuron.hh_psc.HHPSC
神经元除了继承 neurai.nn.neuron.hh.HH
的属性之外,还有其特有的参数,
tau_syn_e
,float类型,表示兴奋性突触的突触时间常数,默认为0.2。
tau_syn_i
,float类型,表示抑制性突触的突触时间常数,默认为2.0。
from neurai import nn
hhpsc = nn.HHPSC(size=1, v_init=-65., I_e=10.0, tau_syn_e=0.2, tau_syn_i=2.0)
Izhikevich#
数学上,该模型的表示如下:
neurai.nn.neuron.izhikevich.Izhikevich
神经元除了继承 neurai.nn.neuron.neuron.Neuron
的属性之外,还有其特有的参数。
v_init
,可以是[float, Initializer]中的一种类型,初始膜电位的值,默认为-65.0;
a
,float类型,恢复变量的时间尺度,默认为0.02;
b
,float类型,恢复变量的敏感度,默认为0.20;
c
,float类型,脉冲后膜电位的重置值,默认为-65;
d
,float类型,脉冲后恢复变量的重置值,默认为8;
V_th
,float类型,阈值电位,默认为30;
V_reset
,float类型,脉冲后的重置电位,默认为0;
I_e
,float类型, 输入电流,默认为0;
method
,neurai.const.math.SolverMethodODE
类型,求解微分方程的方法,默认为SolverMethodODE.EULER
。
使用示例如下:
from neurai import nn
iz = nn.Izhikevich(size=100, v_init=-65., V_th=-60., I_e=10.0)
生成器#
生成器是一种抽象的、数学化的模型,它不是基于生物学实验数据,而是根据数学原理和计算模型设计的。这类模型通常比较简单,参数更少,因此计算效率更高。 它们的设计更注重于实现特定的功能,如符合泊松分布的脉冲生成、特定时间的电流输出等,而不是模拟生物神经元的详细生理特征。
定义一个 neurai.nn.neuron.generator.Generator
基类,所有的生成器模型都继承这个基类。如果是自定义生成器,需要用户继承这个类进行模型的扩展。 Generator
只定义了一个通用参数 size
。
值得注意的是,在使用 Generator
作为前神经元簇进行突触连接时,推荐使用 neurai.nn.conn.connrule.One2One
或者 neurai.nn.conn.connrule.All2All
的连接方式。
使用 One2One
的连接方式时,要求 Generator
的神经元数量和与之相连的后神经元簇的神经元数量一致;使用 All2All
连接方式时, Generator
的 size
为1。
PoissonGenerator#
一个根据泊松过程生成脉冲的模型,其中每个神经元都以给定的频率独立地发放脉冲,由于其中存在随机种子,可能会与其它框架产生的结果有所差异,但脉冲服从泊松规律是不变的。
neurai.nn.neuron.poisson_generator.PoissonGenerator
继承自 neurai.nn.neuron.generator.Generator
,有其自身特有的参数。
rate
,可以是[int, float]中的一个类型,每个神经元的发放率,单位为赫兹,默认值为1000。可以是标量,也可以是形状为(size,)的类数组对象;
rng_col
,str类型,Rng名称,默认为’poisson’;
start
,float类型,脉冲激活的开始时间,默认为0;
stop
,float类型,脉冲激活的停止时间,默认为’inf’;
is_spike_binary
,bool类型,脉冲值的数据类型,如果数据类型为bool,则设置为True。否则,设置为False。默认为False,正常情况下,这个参数不需要用户输入,使用默认值即可。
使用示例如下:
from neurai import nn
pg = nn.PoissonGenerator(size=1, rate=10000)
BernoulliGenerator#
一个服从伯努利分布生成脉冲的模型,其中每个神经元都以给定的概率独立地发放脉冲,由于其中存在随机种子,可能会与其它框架产生的结果有所差异,但脉冲服从伯努利规律是不变的。
neurai.nn.neuron.bernoulli_generator.BernoulliGenerator
继承自 neurai.nn.neuron.generator.Generator
类,有其自身特有的参数。
prob
,可以是[int, float]中的一个类型,每个神经元服从的发放概率,默认值为1。可以是标量,也可以是形状为(size,)的类数组对象;
rng_col
,str类型,Rng名称,默认为’bernoulli’;
start
,float类型,脉冲激活的开始时间,默认为0;
stop
,float类型,脉冲激活的停止时间,默认为’inf’;
is_spike_binary
,bool类型,脉冲值的数据类型,如果数据类型为bool,则设置为True。否则,设置为False。默认为True,正常情况下,这个参数不需要用户输入,使用默认值即可。
使用示例如下:
from neurai import nn
bg = nn.BernoulliGenerator(size=1, prob=0.5)
DCGenerator#
一个提供恒定直流输入的神经元模型,根据给定的时间间隔确定是否激活幅度参数。
neurai.nn.neuron.dc_generator.DCGenerator
继承自 neurai.nn.neuron.generator.Generator
类,有其自身特有的参数。
amplitude
,float类型,每个神经元的电流强度,默认值为1。可以是标量,也可以是形状为(size,)的类数组对象;
start
,float类型,脉冲激活的开始时间,默认为0;
stop
,float类型,脉冲激活的停止时间,默认为’inf’;
is_spike_binary
,bool类型,脉冲值的数据类型,如果数据类型为bool,则设置为True。否则,设置为False。默认为False,正常情况下,这个参数不需要用户输入,使用默认值即可。
使用示例如下:
from neurai import nn
dc = nn.DCGenerator(size=1, amplitude=100, start=5, stop=10)
SpikeGenerator#
一个提供指定时刻脉冲输入的神经元模型,根据给定的时间确定是否激活幅度参数。
neurai.nn.neuron.spike_generator.SpikeGenerator
继承自 neurai.nn.neuron.generator.Generator
类,有其自身特有的参数。
spike_times
,List类型,发放脉冲的时间点列表,可以是单List,也可以是嵌套List,子List的数量为size的数量, 最多嵌套两层,第一维为所连接的目标神经元簇的数量,第二维为脉冲的时间点列表;
multiplicities
,int类型,脉冲多重值,默认值为1;
is_spike_binary
,bool类型,脉冲值的数据类型,如果数据类型为bool,则设置为True。否则,设置为False。默认为False,正常情况下,这个参数不需要用户输入,使用默认值即可。
使用示例如下,表示该生成器的第一个神经元在0.4、0.8和1.0时刻产生脉冲,第二个神经元在0.2和0.5时刻产生脉冲:
from neurai import nn
sg = nn.SpikeGenerator(size=2, spike_times=[[0.4, 0.8, 1.0], [0.2, 0.5]])
CustomGenerator#
一个提供自定义数据作为脉冲输入的神经元模型,根据给定的脉冲数据以及时间间隔确定是否激活脉冲。
neurai.nn.neuron.custom_generator.CustomGenerator
继承自 neurai.nn.neuron.generator.Generator
类,有其自身特有的参数。
datapath
,str类型,脉冲发放数组的文件路径,默认为 None,目前文件格式支持’.dat’;
data
,jnp.ndarray类型, 脉冲发放的数组,默认为 None;
start
,float类型,脉冲激活的开始时间,默认为0;
stop
,float类型,脉冲激活的停止时间,默认为’inf’;
is_spike_binary
,bool类型,脉冲值的数据类型,如果数据类型为bool,则设置为True。否则,设置为False。默认为False,正常情况下,这个参数不需要用户输入,使用默认值即可。
使用示例如下,表示该生成器的两个神经元在前5步可能会有脉冲产生,第一个神经元前5个时刻产生的脉冲分别1,1,0,3,0,第二个神经元产生的脉冲分别是0,2,0,1,3,之后的时刻均不产生脉冲:
from neurai import nn
cg = nn.CustomGenerator(size=2, data=jnp.array([[1, 0], [1, 2], [0, 0], [3, 1], [0, 3]]))
InputTransmitter#
一个接收外部输入的神经元模型。所有的外部输入都会经由这个生成器进行转换,其余神经元模型不直接接收外部输入,且该神经元的数量必须与传入输入的大小保持一致。
可以根据指定的 inputs_type
确定传入的输入数据是作为 current
还是 spike
进行传输。支持输入数据的形状是 (batchsize, time_steps, feature_points) 或 (batchsize, feature_points) 或 (feature_points,)。如果输入数据没有时间步长,则模拟将仅在第一步接收数据。
neurai.nn.neuron.input_transmitter.InputTransmitter
继承自 neurai.nn.neuron.generator.Generator
类,有其自身特有的参数。
inputs_type
,str类型,传输的输入数据类型,可选选项为 current 或 spike,默认为 spike;
batch_first
,bool类型,是否批处理为第一维度,默认为 False;
is_spike_binary
,bool类型,脉冲值的数据类型,如果数据类型为bool,则设置为True。否则,设置为False。默认为False,正常情况下,这个参数不需要用户输入,使用默认值即可。
使用示例如下:
from neurai import nn
ig = nn.InputTransmitter(size=5)