我正在研究的模型有一个神经元(由霍奇金 - 赫胥黎方程建模),神经元本身接收来自其他神经元的一串突触输入,因为它在网络中。对输入进行建模的标准方法是使用尖峰序列,该峰值序列由一组以指定速率到达的delta函数脉冲组成,作为泊松过程。一些脉冲对神经元提供兴奋反应,一些提供抑制脉冲。因此突触电流应如下所示:
这里,Ne是兴奋性神经元的数量,Ni是抑制性的,h是0或1(1,概率为p)表示是否成功传输了尖峰,而delta是$ t_k ^ l $ function是第k个神经元第l个尖峰的放电时间(对于$ t_m ^ n $也是如此)。因此,我们尝试编码的基本思想是假设首先我有100个神经元向我的HH神经元提供脉冲(其中80个是兴奋性的,其中20个是抑制性的)。然后我们形成了一个阵列,其中一列列举了神经元(因此神经元#0-79是兴奋性的,#80-99是抑制性的)。然后我们检查是否在某个时间间隔内有一个尖峰,如果有,请选择0-1之间的随机数,如果它低于我指定的概率p,则为其分配数字1,否则将其设为0。然后将电压绘制为时间的函数,以查看神经元何时出现峰值。
我认为代码有效,但问题是,只要我在网络中添加更多神经元(一篇论文声称他们使用了5000个总神经元),就需要永远运行,这对于进行数值模拟来说是不可行的。我的问题是:有没有更好的方法来模拟尖峰列车脉冲进入神经元,以便网络中的大量神经元的计算速度更快?这是我们尝试的代码:(它有点长,因为HH方程非常详细):
import scipy as sp
import numpy as np
import pylab as plt
#Constants
C_m = 1.0 #membrane capacitance, in uF/cm^2"""
g_Na = 120.0 #Sodium (Na) maximum conductances, in mS/cm^2""
g_K = 36.0 #Postassium (K) maximum conductances, in mS/cm^2"""
g_L = 0.3 #Leak maximum conductances, in mS/cm^2"""
E_Na = 50.0 #Sodium (Na) Nernst reversal potentials, in mV"""
E_K = -77.0 #Postassium (K) Nernst reversal potentials, in mV"""
E_L = -54.387 #Leak Nernst reversal potentials, in mV"""
def poisson_spikes(t, N=100, rate=1.0 ):
spks = []
dt = t[1] - t[0]
for n in range(N):
spkt = t[np.random.rand(len(t)) < rate*dt/1000.] #Determine list of times of spikes
idx = [n]*len(spkt) #Create vector for neuron ID number the same length as time
spkn = np.concatenate([[idx], [spkt]], axis=0).T #Combine tw lists
if len(spkn)>0:
spks.append(spkn)
spks = np.concatenate(spks, axis=0)
return spks
N = 100
N_ex = 80 #(0..79)
N_in = 20 #(80..99)
G_ex = 1.0
K = 4
dt = 0.01
t = sp.arange(0.0, 300.0, dt) #The time to integrate over """
ic = [-65, 0.05, 0.6, 0.32]
spks = poisson_spikes(t, N, rate=10.)
def alpha_m(V):
return 0.1*(V+40.0)/(1.0 - sp.exp(-(V+40.0) / 10.0))
def beta_m(V):
return 4.0*sp.exp(-(V+65.0) / 18.0)
def alpha_h(V):
return 0.07*sp.exp(-(V+65.0) / 20.0)
def beta_h(V):
return 1.0/(1.0 + sp.exp(-(V+35.0) / 10.0))
def alpha_n(V):
return 0.01*(V+55.0)/(1.0 - sp.exp(-(V+55.0) / 10.0))
def beta_n(V):
return 0.125*sp.exp(-(V+65) / 80.0)
def I_Na(V, m, h):
return g_Na * m**3 * h * (V - E_Na)
def I_K(V, n):
return g_K * n**4 * (V - E_K)
def I_L(V):
return g_L * (V - E_L)
def I_app(t):
return 3
def I_syn(spks, t):
"""
Synaptic current
spks = [[synid, t],]
"""
exspk = spks[spks[:,0]<N_ex] # Check for all excitatory spikes
delta_k = exspk[:,1] == t # Delta function
if sum(delta_k) > 0:
h_k = np.random.rand(len(delta_k)) < 0.5 # p = 0.5
else:
h_k = 0
inspk = spks[spks[:,0] >= N_ex] #Check remaining neurons for inhibitory spikes
delta_m = inspk[:,1] == t #Delta function for inhibitory neurons
if sum(delta_m) > 0:
h_m = np.random.rand(len(delta_m)) < 0.5 #p =0.5
else:
h_m = 0
isyn = C_m*G_ex*(np.sum(h_k*delta_k) - K*np.sum(h_m*delta_m))
return isyn
def dALLdt(X, t):
V, m, h, n = X
dVdt = (I_app(t)+I_syn(spks,t)-I_Na(V, m, h) - I_K(V, n) - I_L(V)) / C_m
dmdt = alpha_m(V)*(1.0-m) - beta_m(V)*m
dhdt = alpha_h(V)*(1.0-h) - beta_h(V)*h
dndt = alpha_n(V)*(1.0-n) - beta_n(V)*n
return np.array([dVdt, dmdt, dhdt, dndt])
X = [ic]
for i in t[1:]:
dx = (dALLdt(X[-1],i))
x = X[-1]+dt*dx
X.append(x)
X = np.array(X)
V = X[:,0]
m = X[:,1]
h = X[:,2]
n = X[:,3]
ina = I_Na(V, m, h)
ik = I_K(V, n)
il = I_L(V)
plt.figure()
plt.subplot(3,1,1)
plt.title('Hodgkin-Huxley Neuron')
plt.plot(t, V, 'k')
plt.ylabel('V (mV)')
plt.subplot(3,1,2)
plt.plot(t, ina, 'c', label='$I_{Na}$')
plt.plot(t, ik, 'y', label='$I_{K}$')
plt.plot(t, il, 'm', label='$I_{L}$')
plt.ylabel('Current')
plt.legend()
plt.subplot(3,1,3)
plt.plot(t, m, 'r', label='m')
plt.plot(t, h, 'g', label='h')
plt.plot(t, n, 'b', label='n')
plt.ylabel('Gating Value')
plt.legend()
plt.show()
我不熟悉专门为神经网络设计的其他软件包,但我想自己编写,主要是因为我打算进行随机分析,这需要相当多的数学细节,我不知道那些包提供了这样的细节。
答案 0 :(得分:1)
分析表明,大部分时间都用在这两行中:
if sum(delta_k) > 0:
和
if sum(delta_m) > 0:
将其中的每一项更改为:
if np.any(...)
将所有内容提高10倍。如果您想要进行更多的逐行分析,请查看kernprof: https://github.com/rkern/line_profiler
答案 1 :(得分:1)
作为对welch的回答的补充,您可以使用scipy.integrate.odeint
来加速集成:替换
X = [ic]
for i in t[1:]:
dx = (dALLdt(X[-1],i))
x = X[-1]+dt*dx
X.append(x)
通过
from scipy.integrate import odeint
X=odeint(dALLdt,ic,t)
在我的电脑上将计算速度提高了10倍以上。
答案 2 :(得分:0)
如果您有NVidia grpahics板,则可以使用numba / numbapro来加速python代码,并达到每个具有128个突触前神经元的实时4K神经元。