【问题标题】:Implementing the Izhikevich neuron model实现 Izhikevich 神经元模型
【发布时间】:2017-06-04 20:10:59
【问题描述】:

我正在尝试实现 Izhikevich 模型的尖峰神经元。这类神经元的公式很简单:

v[n+1] = 0.04*v[n]^2 + 5*v[n] + 140 - u[n] + I

u[n+1] = a*(b*v[n] - u[n])

其中 v 是膜电位,u 是恢复变量。

如果 v 超过 30,则重置为 c 并且 u 重置为 u + d .

鉴于这样一个简单的等式,我预计不会有任何问题。但是,虽然图表应该看起来像 ,但我得到的只是:

我完全不知道自己做错了什么,因为几乎没有什么可做的。我一直在寻找其他实现,但我正在寻找的代码总是隐藏在某个 dll 中。但是我很确定我所做的正是作者 (2) 的 Matlab 代码正在做的事情。这是我的完整 R 代码:

v = -70
u = 0
a = 0.02
b = 0.2
c = -65
d = 6
history <- c()

for (i in 1:100) {
  if (v >= 30) {
    v = c
    u = u + d
  }
  v = 0.04*v^2 + 5*v + 140 - u + 0
  u=a*(b*v-u); 
  history <- c(history, v)
}

plot(history, type = "l")

对于曾经实施过 Izhikevich 模型的任何人,我错过了什么?

有用的链接: (1)http://www.opensourcebrain.org/projects/izhikevichmodel/wiki (2)http://www.izhikevich.org/publications/spikes.pdf

回答

原来我读错了公式。显然 v' 表示新 v = v + 0.04*v^2 + 5*v + 140 - u + I。我的老师会写成 v' = 0.04 *v^2 + 6*v + 140 - u + I。非常感谢您帮助我指出这一点。

【问题讨论】:

  • 我见过这个方程一次...不是 v' 而不是 v[n+1] 吗?所以方程可能看起来像 v + 0.04*v^2 + 5*v + 140 - u 。我尝试实现这个模型,但我遇到了问题,因为微分方程的系数与神经元输入的相互作用很差,所以只有很少的尖峰。然后我应用了泄漏集成和火灾模型。
  • 同一事物的不同表示法。 v' 和 v[n+1] 都表示“v 的新值”,v 和 v[n] 都表示“v 的旧值”。
  • 没有。 v[n+1] 表示 v 的新值。 v' 表示 v 值的变化。您将 v 替换为方程式结果,但您需要将方程式结果添加到 v。
  • 我认为@viceriel 是对的。如果您查看原始论文中的实现,作者似乎首先将长度为 1000 的向量 v 初始化为 -65,然后在循环 v=v+0.5*(0.04*v.^2+5*v+140-u+I) 内初始化。
  • 我发现了两个问题。方程的错误转录(与u相同)和神经元膜上的电压受外部输入(I)刺激,你是0。

标签: r neural-network biological-neural-network


【解决方案1】:

看看下面在 R 中实现 Izhikevich 模型的代码。它会产生以下 R 图:

常规尖峰细胞:

喋喋不休的细胞:

还有R代码:

# Simulation parameters
dt = 0.01 # ms
simtime = 500 # ms
t = 0

# Injection current
I = 15
delay = 100 # ms

# Model parameters (RS)
a = 0.02
b = 0.2
c = -65
d = 8

# Params for chattering cell (CH)
# c = -50
# d = 2

# Initial conditions
v = -80 # mv
u = 0

# Input current equation
current = function()
{
  if(t >= delay)
  {
    return(I)
  }

  return (0)
}

# Model state equations
deltaV = function()
{
  return (0.04*v*v+5*v+140-u+current())
}

deltaU = function()
{
  return (a*(b*v-u))
}

updateState = function()
{
  v <<- v + deltaV()*dt
  u <<- u + deltaU()*dt

  if(v >= 30) 
  {
    v <<- c
    u <<- u + d
  }
}

# Simulation code
runsim = function()
{
  steps = simtime / dt
  resultT = rep(NA, steps)
  resultV = rep(NA, steps)

  for (i in seq(steps))
  {
    updateState()
    t <<- dt*(i-1)

    resultT[i] = t
    resultV[i] = v
  }

  plot(resultT, resultV, 
       type="l", xlab = "Time (ms)", ylab = "Membrane Potential (mV)")
}

runsim()

一些注意事项:

  • 我从Izhikevich's site 中选择了“Regular Spiking (RS)”单元格的参数。您可以从该页面右上角的两个图中选择其他参数。取消注释 CH 参数以获得“Chattering”类型单元格的图。
  • 正如评论者所建议的,问题中的前两个方程是错误地实现的微分方程。实现第一个的正确方法是:“v[n+1] = v[n] + (0.04*v[n]^2 + 5*v[n] + 140 - u[n] + I) * dt"。例如,请参见上面的代码。 dt 是指用户指定的时间步长积分变量,通常 dt
  • 在问题的for循环中,状态变量u和v应该先更新,然后再检查条件。
  • 正如其他人所指出的,这两种细胞类型都需要电流源。我使用了来自this page on the author's site 的 15 个(我相信这些是 pico amps)(屏幕截图中 I 的底部值)。我还实现了当前开始的延迟(100 ms 参数)。
  • 模拟代码应该实现某种时间跟踪,以便更容易知道结果图中何时出现尖峰。上面的代码实现了这一点,并运行了 500 毫秒的模拟。

【讨论】:

  • 非常感谢您。我很确定我的教授一直使用 v' 来表示“v 的新值”而不是“delta V”,所以这就是问题所在。我也想知道什么时候应该检查条件(它只影响图表,但它仍然很重要)。我应该提到我故意将电流设置为 0(我期待一条平坦的线并从那里构建)。
  • 很高兴我能帮上忙。请记住,上面的代码只是对 diff eqs 进行数值积分的一种方法。还有其他更准确的方法。
  • 哦,我还有一个问题,要明确一点:似乎当您计算 delta U 时,您已经在使用 v(或“新”v)的更新值?或者
  • 一般情况下,赋值运算符右边的语句首先被求值,结果值被赋予左边的变量。这是一个家庭作业问题吗?如果是这样,您应该添加作业标签
  • 这不是家庭作业,我正在为明年的论文做一些研究。我只是对 R 不太熟悉(我的主要编程语言是 Java)。所以我想知道为什么在这种情况下你使用
猜你喜欢
  • 1970-01-01
  • 2016-12-23
  • 1970-01-01
  • 2023-03-10
  • 2020-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多