Вступление
Сразу сообщу, что пост не имеет никакого отношения к перцептронам, сетям Хопфилда или любым другим формальным нейронным сетям. Мы будем моделировать работу «настоящей», «живой», биологической нейронной сети в которой происходят процессы генерации и распространения нервных импульсов. В англоязычной литературе такие сети, ввиду их отличия от формальных нейронных сетей, называются spiking neural networks, в русскоязычной же литературе нет устоявшегося наименования, кто-то их называет просто нейронными сетям, кто-то импульсными нейронными сетями, кто-то спайковыми, а кто-то вообще нейрональными сетями.
Вероятно большинство читателей слышали о проектах Blue Brain и Human Brain спонсируемых Европейским Союзом, под последний проект правительство ЕС выдало около миллиарда евро, что говорит о наличии большого интереса к этой области. Оба проекта тесно связаны и пересекаются друг с другом, даже руководитель у них общий, Генри Маркрам, что может создать некоторую путаницу в том, чем же они отличаются друг от друга. Если кратко, то конечной целью обоих проектов является разработка модели работы целого
На хабре уже было несколько интересных и информативных статей по нейробиологии, что очень радует.
1. Нейробиология и искусственный интеллект: часть первая — ликбез.
2. Нейробиология и искусственный интеллект: часть вторая – интеллект и представление информации в мозгу.
3. Нейробиология и искусственный интеллект: часть третья – представление данных и память
Но в них не рассматривались вопросы вычислительной нейробиологии, или по-другому вычислительной нейронауки, включающей в себя компьютерное моделирование электрической активности нейронов. Поэтому я решил восполнить этот пробел.
Немного биологии
Рис. 1 — Схематическое изображение строения нейрона.
Прежде чем приступим к моделированию, нам нужно ознакомиться с некоторыми азами нейробиологии. Типичный нейрон состоит из 3-х частей: тела (сомы), дендритов и аксона. Дендриты принимают сигнал от других нейронов (это input нейрона), а аксон передает сигналы от тела нейрона к другим нейронам (output). Место контакта аксона одного нейрона и дендрита другого нейрона называется синапсами. Сигнал принимаемый с дендритов суммируется в теле и если он превышает определённые порог, то генерируется нервный импульс или по-другому, спайк. Тело клетки окружено липидной оболочкой, являющейся хорошим изолятором. Ионные составы цитоплазмы нейрона и межклеточной жидкости различаются. В цитоплазме концентрация ионов калия выше, а концентрация натрия и хлора ниже, в межклеточной же жидкости все наоборот. Это связано с работой ионных насосов, которые постоянно перекачивают определенные типы ионов против градиента концентрации, потребляя при этом энергию, запасенную в молекулах АденозиноТриФосфата (АТФ). Самым известным и изученным из таких насосов является натрий-калиевый насос: он выводит 3 иона натрия в наружу, а внутрь нейрона забирает 2 иона калия. На рисунке 2 изображен ионный состав нейрона и отмечены ионные насосы. Благодаря работе этих насосов в нейроне образуется равновесная разность потенциалов между внутренней стороной мембраны, которая заряжается отрицательно, и внешней, заряженной положительно.
Рис. 2 — Ионный состав нейрона и окружающей среды
Кроме насосов на поверхности нейрона есть ещё ионные каналы, которые при изменении потенциала или при химическом воздействии могут открываться или закрываться, тем самым увеличивая или уменьшая токи определённого типа ионов. Если путем какого-то воздействия мембранный потенциал превышает некоторый порог, открываются натриевые каналы, а так как снаружи больше натрия, то возникает электрический ток направленный внутрь нейрона, что ещё больше увеличивает мембранный потенциал и ещё сильнее открывает натриевые каналы, происходит резкое увеличение мембранного потенциала, физики назовут это положительной обратной связью. Но начиная с какого-то значения потенциала, более высокого чем пороговый потенциал открытия натриевых каналов, открываются и калиевые каналы, благодаря чему ионы калия начинают течь в наружу уменьшая мембранный потенциал, тем самым возвращая его к равновесному значению. Если же первоначальное возбуждение меньше порога открытия натриевых каналов, то нейрон вернётся к своему равновесному состоянию. Что интересно, амплитуда генерируемого импульса слабо зависит от амплитуды возбуждающего тока, либо импульс есть либо его нет, закон «все или ничего». Наглядно это изображено на рисунке 3. Внизу изображен входной ток направленный к внутренней стороне мембраны нейрона, а вверху разность потенциалов между внутренней и внешней стороной мембраны. Поэтому согласно доминирующей ныне концепции в живых нейронных сетях информация кодируется во временах возникновения импульсов, или как сказали бы физики, путем частотной модуляции.
Рис. 3 — Генерация нервного импульса. Внизу изображен подаваемый внутрь клетки ток в пкА, а вверху мембранный потенциал в мВ
Возбудить нейрон можно например воткнув в него микроэлектрод и подав ток внутрь нейрона, но в живом
Математическая модель нейрона
На основе описанных выше динамических механизмов работы нейрона, может быть составлена его математическая модель. На данный момент созданы различные как относительно простые модели, вроде «Inregrate and Fire», в которой нейрон представляется в виде конденсатора и резистора. Так и более сложные, биологически правдоподобные, модели, вроде модели Ходжкина-Хаксли, которая гораздо сложнее как в вычислительном плане так и в плане анализа её динамики, но она гораздо точнее описывает динамику мембранного потенциала нейрона. В данной же статье мы будем использовать модель Ижикевича [1], данная модель представляет из себя некоторый компромисс между вычислительной сложностью и биофизической правдоподобностью. Несмотря на свою вычислительную простоту, в этой модели можно воспроизвести большое количество явлений происходящих в настоящих нейронах. Модель Ижикевича задается в виде системы диференциальных уравнений которые изображены на рисунке 4.
Рис. 4 — Модель Ижикевича
Где a, b, c, d, k, Cm различные параметры нейрона. Vm — это разность потенциалов на внутренней и внешней стороне мембраны, а Um — вспомогательная переменная. I — это внешний постоянный приложенный ток. В данной модели наблюдаются такие характерные для нейронов свойства как: генерация спайка в ответ на одиночный импульса внешнего тока и генерация последовательности спайков с определённой частотой при подаче на нейрон постоянного внешнего тока. Isyn — сумма синаптических токов от всех нейронов с которыми связан этот нейрон.
В случае если на пресинаптическом нейроне генерируется спайк, на постсинаптическом происходит скачок синапического тока, который экспоненциально затухает с характерным временем.
Переходим к кодингу
Итак мы приступаем к самому интересному, пора закодить на компьютере виртуальный кусок нервной ткани. Для этого будем численно решать систему дифференциальных уравнений задающих динамику мембранного потенциала нейрона. Для интегрирования будем использовать метод Эйлера.
Для этого нам понадобятся двумерные массивы Vms, Ums размерности Tsim*Nneur для хранения мембранных потенциалов и вспомогательных переменных каждого нейрона, в каждый момент времени, Tsim это время симуляции в отсчетах, а Nneur количество нейронов в сети.
Связи будем хранить в виде двух массивов pre_con и post_con размерности Ncon, где индексами является номера связей, а значениями являются индексы пресинаптических и постсинаптических нейронов. Ncon — число связей.
Так же нам понадобиться массив для представления переменной модулирующей экспоненциально затухающий постсинаптический ток каждого синапса, для этого создаем массив y размерности Ncon*Tsim.
const float h = .5f; // временной шаг интегрирования
const int Tsim = 1000/.5f; // время симуляции в дискретных отсчетах
const int Nexc = 100; // Количество возбуждающих (excitatory) нейронов
const int Ninh = 25; // Количество тормозных (inhibitory) нейронов
const int Nneur = Nexc + Ninh;
const int Ncon = Nneur*Nneur*0.1f; // Количество сязей, 0.1 это вероятность связи между 2-мя случайными нейронами
float Vms[Nneur][Tsim]; // мембранные потенциалы
float Ums[Nneur][Tsim]; // вспомогательные переменные модели Ижикевича
float Iex[Nneur]; // внешний постоянный ток приложенный к нейрону
float Isyn[Nneur]; // синаптический ток на каждый нейрон
int pre_conns[Ncon]; // индексы пресинаптических нейронов
int post_conns[Ncon]; // индексы постсинаптических нейронов
float weights[Ncon]; // веса связей
float y[Ncon][Tsim]; // переменная модулирующая синаптический ток в зависимости от спайков на пресинапсе
float psc_excxpire_time = 4.0f; // характерное вермя спадания постсинаптического тока, мс
float minWeight = 50.0f; // веса, размерность пкА
float maxWeight = 100.0f;
float Iex_max = 40.0f; // максимальный приложенный к нейрону ток 50 пкА
Как уже было сказано, информация кодируется во временах возникновения импульсов, поэтому создаем массивы для сохранения времен их возникновения и индексов нейронов где они возникли. Далее их можно будет записать в файл, с целью визуализации.
float spike_times[Nneur*Tsim]; // времена возникновения спайков
int spike_neurons[Nneur*Tsim]; // индексы нейронов на которых происходят спайки
int spike_num = 0; // номер спайка
Разбрасываем случайно связи и задаем веса.
void init_connections(){
for (int con_idx = 0; con_idx < Ncon; ){
// случайно выбираем постсипантические и пресинаптические нейроны
pre_conns[con_idx] = rand() % Nneur;
post_conns[con_idx] = rand() % Nneur;
weights[con_idx] = (rand() % ((int)(maxWeight - minWeight)*10))/10.0f + minWeight;
if (pre_conns[con_idx] >= Nexc){
// если пресинаптический нейрон тормозный то вес связи идет со знаком минус
weights[con_idx] = -weights[con_idx];
}
con_idx++;
}
}
Установка начальных условий для нейронов и случайное задание внешнего приложенного тока. Те нейроны для которых внешний ток превысит порог генерации спайков, будут генерировать спайки с постоянной частотой.
void init_neurons(){
for (int neur_idx = 0; neur_idx < Nneur; neur_idx++){
// случайно разбрасываем приложенные токи
Iex[neur_idx] = (rand() % (int) (Iex_max*10))/10.0f;
Vms[neur_idx][0] = -60.0f;
}
}
Основная часть программы с интегрированием модели Ижикевича.
float izhik_Vm(int neuron, int time){
return (0.5f*(Vms[neuron][time] + 60.0f)*(Vms[neuron][time] + 45.0f) - Ums[neuron][time] + Iex[neuron] + Isyn[neuron])/50.0f;
}
float izhik_Um(int neuron, int time){
return 0.02f*(0.5f*(Vms[neuron][time] + 60.0f) - Ums[neuron][time]);
}
int main(){
init_connections();
init_neurons();
float expire_coeff = exp(-h/psc_excxpire_time); // для экспоненциально затухающего тока
for (int t = 1; t < Tsim; t++){
// проходим по всем нейронам
for (int neur = 0; neur < Nneur; neur++){
Vms[neur][t] = Vms[neur][t-1] + h*izhik_Vm(neur, t-1);
Ums[neur][t] = Ums[neur][t-1] + h*izhik_Um(neur, t-1);
Isyn[neur] = 0.0f;
if (Vms[neur][t-1] > Vpeak){
Vms[neur][t] = c;
Ums[neur][t] = Ums[neur][t-1] + d;
spike_times[spike_num] = t*h;
spike_neurons[spike_num] = neur;
spike_num++;
}
}
// проходим по всем связям
for (int con = 0; con < Ncon; con++){
y[con][t] = y[con][t-1]*expire_coeff;
if (Vms[pre_conns[con]][t-1] > Vpeak){
y[con][t] = 1.0f;
}
Isyn[post_conns[con]] += y[con][t]*weights[con];
}
}
save2file();
return 0;
}
Полный текст кода можно скачать тут. Код свободно компилируется и запускается хоть под виндой с Visual Studio 2010 Express Edition или MinGW, хоть под GNU/Linux c GCC. После завершения работы программа сохраняет растр активности, времена и индексы возникновения нервных импульсов, и осциллограммы среднего мембранного потенциала в файлах rastr.csv и oscill.csv, соответственно. Можно их прямо в Exelе и нарисовать. Либо с помощью прикрепленных мною питоновских скриптов, но для их работы нужна библиотека Matplotlib. Для тех у кого GNU/Linux установить из репозиториев пакет python-matplotlib не составит труда, пользователям же Windows придется вручную скачать отюсда последовательно пакеты numpy, scypy, pyparsing, python-dateutil и matplotlib.
Рисование растра активности — plot_rastr.py
Рисование среднего мембранного потенциала — plot_oscill.py
Результаты
Рис. 5 — Активность нейронной сети. Вверху по оси y отложены номера нейронов, а моменты времени когда на нейроне генерируется спайк отмечены точкой. Внизу среднее количество спайков в 1 мс времени.
Рис. 6 — Средний мембранные потенциал, «электроэнцефалограмма».
Вот что получается при моделировании 1 секунды активности 125 нейронов. Мы наблюдаем периодическую активность на частоте ~3 Гц, похожую на дельта-ритм.
[1] E.M. Izhikevich, Dynamical Systems in Neuroscience: The Geometry of Excitability and Bursting, USA, MA, Cambridge: The MIT Press., 2007
Автор: esir_pavel