神经元模型#

作者: 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 \frac{dV}{dt} = V_{rest} - V + RI\]

其中 \(\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;

  • methodneurai.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 \frac{dV}{dt} = V_{rest} - V + RI\]

其中 \(\tau\) 为时间常数, \(V_{rest}\) 为静息电位, \(V\) 为膜电位, \(R\) 为膜电阻, \(I\) 为输入电流。

输入电流 \(I\) 中有一个指数衰减项,假设神经元所连接的多个突触指数函数,权重分别为 \(w_i\),对应的脉冲序列为 \(s_i\),电流 \(I\) 的微分方程可以表示为:

\[\frac{dI}{dt} = \frac{-I}{\tau} + \sum_{i=1}^n s_i w_i\]

其中 \(\tau\) 为自身指数衰减的时间常数, \(n\) 为连接的突触数量。

ExpLIF 是按照文献 [3] 实现的带有指数衰减的突触后电流的漏电积分-放电模型,neurai.nn.neuron.exp_lif.ExpLIF 神经元除了继承 neurai.nn.neuron.lif.LIF 的属性之外,还有其特有的参数,

  • tau_syn,float类型,表示突触时间常数,默认为2.0。

使用示例如下:

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 是其中的一种具有脉冲后电流的模型。

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-)。 数学上,该模型的表示如下:

\[C_m \frac{dV_m}{dt} = - (g_{Na}m^3h(V_m -E_{Na}) + g_{K}n^4(V_m-E_{K}) + g_{leak}(V_m - E_{leak})) + I(t)\]
\[\frac{dm}{dt} = \alpha_{m}(V_{m})(1 - m) - \beta_{m}(V_{m})m\]
\[\frac{dh}{dt} = \alpha_{h}(V_{h})(1 - h) - \beta_{h}(V_{h})h\]
\[\frac{dn}{dt} = \alpha_{n}(V_{n})(1 - n) - \beta_{n}(V_{n})n\]

其中 \(\\alpha\)\(\\beta\) 的计算如下:

\[\alpha_{m}(V_{m}) = \frac{0.1 (V_{m} + 40)}{1-\exp(\frac{-(V_{m} + 40)} {10})}\]
\[\beta_{m}(V_{m}) = 4.0 \exp(\frac{-(V_{m} + 65)} {18})\]
\[\alpha_{h}(V_{m}) = 0.07 \exp(\frac{-(V_{m} + 65)} {20})\]
\[\beta_{h}(V_{m}) = \frac{1}{1+\exp(\frac{-(V_{m} + 35)} {10})}\]
\[\alpha_{n}(V_{m}) = \frac{0.01(V_{m} + 55)}{1-\exp(\frac{-(V_{m} + 55)} {10})}\]
\[\beta_{n}(V_{m}) = 0.125 \exp(\frac{-(V_{m} + 65)} {80})\]

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;

  • methodneurai.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#

数学上,该模型的表示如下:

\[\frac{dv_{m}}{dt} = 0.04V_{m}^2 + 5.0V_{m} + 140.0 - u + I\]
\[\frac{du}{dt} = a(bV_{m} - u)\]

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;

  • methodneurai.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 连接方式时, Generatorsize 为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类型,传输的输入数据类型,可选选项为 currentspike,默认为 spike

  • batch_first,bool类型,是否批处理为第一维度,默认为 False;

  • is_spike_binary,bool类型,脉冲值的数据类型,如果数据类型为bool,则设置为True。否则,设置为False。默认为False,正常情况下,这个参数不需要用户输入,使用默认值即可。

使用示例如下:

from neurai import nn

ig = nn.InputTransmitter(size=5)