Модель integrate-and-fire: симуляция спайков
Самая популярная учебная модель нейрона: мембрана как RC-цепь плюс правило «достиг порога — спайк и сброс».
Leaky integrate-and-fire (LIF) — модель, где подпороговый потенциал описывается линейным уравнением с утечкой, а спайк добавляется вручную при достижении порога.
Уравнение модели
Подпороговая динамика мембраны:
$$ \tau_m \frac{dV}{dt} = -\big(V - V_{rest}\big) + R_m\, I $$
Когда $V$ достигает порога $V_{th}$, фиксируем спайк и сбрасываем $V \leftarrow V_{reset}$. Здесь $\tau_m$ — постоянная времени мембраны, $R_m$ — сопротивление, $I$ — входной ток. Чем больше $I$, тем быстрее $V$ доходит до порога и тем выше частота спайков.
Численное интегрирование
Заменяем производную конечной разностью с шагом $\Delta t$: $V_{n+1} = V_n + \frac{\Delta t}{\tau_m}\big(-(V_n - V_{rest}) + R_m I\big)$. Это метод Эйлера.
Как работает под капотом
Симулируем 200 мс при постоянном токе и считаем спайки:
tau = 10.0 # мс
R_m = 10.0 # МОм (условные единицы)
V_rest, V_th, V_reset = -70.0, -50.0, -75.0
dt, I, T_end = 0.1, 2.6, 200.0
V = V_rest
spikes = []
steps = int(T_end / dt)
for i in range(steps):
t = i * dt
V += (-(V - V_rest) + R_m * I) / tau * dt
if V >= V_th:
V = V_reset
spikes.append(round(t, 1))
print("Спайков за 200 мс:", len(spikes))
print("Первые моменты (мс):", spikes[:5])
isi = spikes[1] - spikes[0]
print("Межспайковый интервал:", round(isi, 1), "мс")
print("Частота разрядов:", round(1000.0 / isi), "Гц")
Вывод:
Спайков за 200 мс: 12 Первые моменты (мс): [14.5, 30.9, 47.3, 63.7, 80.1] Межспайковый интервал: 16.4 мс Частота разрядов: 61 Гц
F-I кривая: частота от тока
Главный результат — зависимость частоты от силы тока. Ниже некоторого порога тока нейрон молчит, выше — частота растёт:
def rate(I, tau=10.0, R_m=10.0, dt=0.1, T_end=200.0):
V, V_rest, V_th, V_reset = -70.0, -70.0, -50.0, -75.0
n = 0
for i in range(int(T_end / dt)):
V += (-(V - V_rest) + R_m * I) / tau * dt
if V >= V_th:
V = V_reset
n += 1
return n / (T_end / 1000.0) # спайков в секунду
for I in (1.5, 2.0, 2.5, 3.0, 4.0):
print(f"I={I}: {rate(I):.0f} Гц")
Вывод:
I=1.5: 0 Гц I=2.0: 0 Гц I=2.5: 55 Гц I=3.0: 80 Гц I=4.0: 120 Гц
Виден порог: при $R_m I \le V_{th} - V_{rest} = 20$ мВ (то есть $I \le 2.0$) потенциал не дотягивает до порога — спайков нет. Это прямая иллюстрация принципа «всё или ничего» в численной модели.
Частые ошибки
- Слишком крупный шаг $\Delta t$: метод Эйлера расходится, частота «врёт». Берите $\Delta t \ll \tau_m$.
- Забыть сброс $V \leftarrow V_{reset}$ — нейрон «зависнет» над порогом и будет спайкать каждый шаг.
- Ожидать спайков при подпороговом токе: ниже порога LIF честно молчит.
Итог
- LIF: $\tau_m \dot V = -(V - V_{rest}) + R_m I$ плюс правило порога и сброса.
- Интегрируем методом Эйлера с малым шагом.
- F-I кривая имеет порог по току и далее почти линейно растёт.