{ "cells": [ { "cell_type": "markdown", "id": "1a486573", "metadata": {}, "source": [ "# *(Brette, et, al., 2007)* COBA-HH\n", "\n", "[![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/brainpy/examples/blob/main/ei_nets/Brette_2007_COBAHH.ipynb)\n", "[![Open in Kaggle](https://kaggle.com/static/images/open-in-kaggle.svg)](https://kaggle.com/kernels/welcome?src=https://github.com/brainpy/examples/blob/main/ei_nets/Brette_2007_COBAHH.ipynb)" ] }, { "cell_type": "markdown", "id": "b2e404b3", "metadata": { "lines_to_next_cell": 0 }, "source": [ "Implementation of the paper:\n", "\n", "- Brette, R., Rudolph, M., Carnevale, T., Hines, M., Beeman, D., Bower, J. M., et al. (2007), Simulation of networks of spiking neurons: a review of tools and strategies., J. Comput. Neurosci., 23, 3, 349–98\n", "\n", "which is based on the balanced network proposed by:\n", "\n", "- Vogels, T. P. and Abbott, L. F. (2005), Signal propagation and logic gating in networks of integrate-and-fire neurons., J. Neurosci., 25, 46, 10786–95\n", "\n", "\n", "\n", "\n", "Authors:\n", "\n", "- [Chaoming Wang](https://github.com/chaoming0625)\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "b3812ad3", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:03.418257500Z", "start_time": "2023-08-27T08:10:01.991025300Z" } }, "outputs": [], "source": [ "import brainpy as bp\n", "import brainpy.math as bm\n", "import numpy as np\n", "\n", "bp.math.set_platform('cpu')" ] }, { "cell_type": "code", "execution_count": 2, "id": "70f044b58dd7c849", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:03.434483700Z", "start_time": "2023-08-27T08:10:03.419260100Z" }, "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'2.4.4.post1'" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bp.__version__" ] }, { "cell_type": "markdown", "id": "9fbb2a89", "metadata": {}, "source": [ "## Parameters" ] }, { "cell_type": "code", "execution_count": 3, "id": "75ad83ce", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:03.435980300Z", "start_time": "2023-08-27T08:10:03.427406600Z" } }, "outputs": [], "source": [ "num_exc = 3200\n", "num_inh = 800\n", "Cm = 200 # Membrane Capacitance [pF]\n", "\n", "gl = 10. # Leak Conductance [nS]\n", "g_Na = 20. * 1000\n", "g_Kd = 6. * 1000 # K Conductance [nS]\n", "El = -60. # Resting Potential [mV]\n", "ENa = 50. # reversal potential (Sodium) [mV]\n", "EK = -90. # reversal potential (Potassium) [mV]\n", "VT = -63.\n", "V_th = -20.\n", "\n", "# Time constants\n", "taue = 5. # Excitatory synaptic time constant [ms]\n", "taui = 10. # Inhibitory synaptic time constant [ms]\n", "\n", "# Reversal potentials\n", "Ee = 0. # Excitatory reversal potential (mV)\n", "Ei = -80. # Inhibitory reversal potential (Potassium) [mV]\n", "\n", "# excitatory synaptic weight\n", "we = 6. # excitatory synaptic conductance [nS]\n", "\n", "# inhibitory synaptic weight\n", "wi = 67. # inhibitory synaptic conductance [nS]" ] }, { "cell_type": "markdown", "id": "e0d201a5", "metadata": {}, "source": [ "## Implementation 1" ] }, { "cell_type": "code", "execution_count": 4, "id": "def19732", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:03.861058200Z", "start_time": "2023-08-27T08:10:03.839826Z" }, "lines_to_next_cell": 1 }, "outputs": [], "source": [ "class HH(bp.dyn.NeuDyn):\n", " def __init__(self, size, method='exp_auto'):\n", " super(HH, self).__init__(size)\n", "\n", " # variables\n", " self.V = bm.Variable(El + (bm.random.randn(self.num) * 5 - 5))\n", " self.m = bm.Variable(bm.zeros(self.num))\n", " self.n = bm.Variable(bm.zeros(self.num))\n", " self.h = bm.Variable(bm.zeros(self.num))\n", " self.spike = bm.Variable(bm.zeros(self.num, dtype=bool))\n", " self.input = bm.Variable(bm.zeros(size))\n", "\n", " def dV(V, t, m, h, n, Isyn):\n", " gna = g_Na * (m * m * m) * h\n", " gkd = g_Kd * (n * n * n * n)\n", " dVdt = (-gl * (V - El) - gna * (V - ENa) - gkd * (V - EK) + Isyn) / Cm\n", " return dVdt\n", "\n", " def dm(m, t, V, ):\n", " m_alpha = 0.32 * (13 - V + VT) / (bm.exp((13 - V + VT) / 4) - 1.)\n", " m_beta = 0.28 * (V - VT - 40) / (bm.exp((V - VT - 40) / 5) - 1)\n", " dmdt = (m_alpha * (1 - m) - m_beta * m)\n", " return dmdt\n", "\n", " def dh(h, t, V):\n", " h_alpha = 0.128 * bm.exp((17 - V + VT) / 18)\n", " h_beta = 4. / (1 + bm.exp(-(V - VT - 40) / 5))\n", " dhdt = (h_alpha * (1 - h) - h_beta * h)\n", " return dhdt\n", "\n", " def dn(n, t, V):\n", " c = 15 - V + VT\n", " n_alpha = 0.032 * c / (bm.exp(c / 5) - 1.)\n", " n_beta = .5 * bm.exp((10 - V + VT) / 40)\n", " dndt = (n_alpha * (1 - n) - n_beta * n)\n", " return dndt\n", "\n", " # functions\n", " self.integral = bp.odeint(bp.JointEq([dV, dm, dh, dn]), method=method)\n", "\n", " def update(self):\n", " tdi = bp.share.get_shargs()\n", " V, m, h, n = self.integral(self.V, self.m, self.h, self.n, tdi.t, Isyn=self.input, dt=tdi.dt)\n", " self.spike.value = bm.logical_and(self.V < V_th, V >= V_th)\n", " self.m.value = m\n", " self.h.value = h\n", " self.n.value = n\n", " self.V.value = V\n", " self.input[:] = 0." ] }, { "cell_type": "code", "execution_count": 5, "id": "f1323b0a", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:04.273924400Z", "start_time": "2023-08-27T08:10:04.259424300Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "d:\\codes\\projects\\brainpy\\brainpy\\_src\\deprecations.py:86: DeprecationWarning: brainpy.TwoEndConn is deprecated. Use brainpy.synapses.TwoEndConn instead.\n", " _deprecate(message)\n" ] } ], "source": [ "class ExpCOBA(bp.synapses.TwoEndConn):\n", " def __init__(self, pre, post, conn, g_max=1., delay=0., tau=8.0, E=0.,\n", " method='exp_auto'):\n", " super(ExpCOBA, self).__init__(pre=pre, post=post, conn=conn)\n", " self.check_pre_attrs('spike')\n", " self.check_post_attrs('input', 'V')\n", "\n", " # parameters\n", " self.E = E\n", " self.tau = tau\n", " self.delay = delay\n", " self.g_max = g_max\n", " self.pre2post = self.conn.require('pre2post')\n", "\n", " # variables\n", " self.g = bm.Variable(bm.zeros(self.post.num))\n", "\n", " # function\n", " self.integral = bp.odeint(lambda g, t: -g / self.tau, method=method)\n", "\n", " def update(self):\n", " self.g.value = self.integral(self.g, bp.share['t'], dt=bp.share['dt'])\n", " post_sps = bm.pre2post_event_sum(self.pre.spike, self.pre2post, self.post.num, self.g_max)\n", " self.g.value += post_sps\n", " self.post.input += self.g * (self.E - self.post.V)" ] }, { "cell_type": "code", "execution_count": 6, "id": "bd361753", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:04.715966200Z", "start_time": "2023-08-27T08:10:04.694643400Z" } }, "outputs": [], "source": [ "class COBAHH(bp.Network):\n", " def __init__(self, scale=1., method='exp_auto'):\n", " num_exc = int(3200 * scale)\n", " num_inh = int(800 * scale)\n", " E = HH(num_exc, method=method)\n", " I = HH(num_inh, method=method)\n", " E2E = ExpCOBA(pre=E, post=E, conn=bp.conn.FixedProb(prob=0.02),\n", " E=Ee, g_max=we / scale, tau=taue, method=method)\n", " E2I = ExpCOBA(pre=E, post=I, conn=bp.conn.FixedProb(prob=0.02),\n", " E=Ee, g_max=we / scale, tau=taue, method=method)\n", " I2E = ExpCOBA(pre=I, post=E, conn=bp.conn.FixedProb(prob=0.02),\n", " E=Ei, g_max=wi / scale, tau=taui, method=method)\n", " I2I = ExpCOBA(pre=I, post=I, conn=bp.conn.FixedProb(prob=0.02),\n", " E=Ei, g_max=wi / scale, tau=taui, method=method)\n", "\n", " super(COBAHH, self).__init__(E2E, E2I, I2I, I2E, E=E, I=I)" ] }, { "cell_type": "code", "execution_count": 7, "id": "3b88bf8b", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:09.844468400Z", "start_time": "2023-08-27T08:10:05.325429Z" } }, "outputs": [], "source": [ "net = COBAHH()" ] }, { "cell_type": "code", "execution_count": 8, "id": "ae13d947", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:12.077131300Z", "start_time": "2023-08-27T08:10:09.846966100Z" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "96a00c8167c54784a7fae84168afddca", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/1000 [00:00" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "bp.visualize.raster_plot(runner.mon.ts, runner.mon['E.spike'], show=True)" ] }, { "cell_type": "markdown", "id": "e092064e7f0d859b", "metadata": { "collapsed": false }, "source": [ "## Implementation 2" ] }, { "cell_type": "code", "execution_count": 10, "id": "923bbfbaa6eac2fa", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:12.516040800Z", "start_time": "2023-08-27T08:10:12.497261700Z" }, "collapsed": false }, "outputs": [], "source": [ "class HH2(bp.dyn.CondNeuGroupLTC):\n", " def __init__(self, size):\n", " super(HH2, self).__init__(size)\n", " self.INa = bp.channels.INa_TM1991(size, g_max=100., V_sh=-63.)\n", " self.IK = bp.channels.IK_TM1991(size, g_max=30., V_sh=-63.)\n", " self.IL = bp.channels.IL(size, E=-60., g_max=0.05)" ] }, { "cell_type": "code", "execution_count": 11, "id": "d3a16c81bf59c780", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:12.516040800Z", "start_time": "2023-08-27T08:10:12.506953500Z" }, "collapsed": false }, "outputs": [], "source": [ "class EINet_v2(bp.DynSysGroup):\n", " def __init__(self, scale=1.):\n", " super(EINet_v2, self).__init__()\n", "\n", " prob = 0.02\n", " self.num_exc = int(3200 * scale)\n", " self.num_inh = int(800 * scale)\n", "\n", " self.N = HH2(self.num_exc + self.num_inh)\n", " self.Esyn = bp.synapses.Exponential(self.N[:self.num_exc],\n", " self.N,\n", " bp.conn.FixedProb(prob),\n", " g_max=0.03 / scale, tau=5,\n", " output=bp.synouts.COBA(E=0.))\n", " self.Isyn = bp.synapses.Exponential(self.N[self.num_exc:],\n", " self.N,\n", " bp.conn.FixedProb(prob),\n", " g_max=0.335 / scale, tau=10.,\n", " output=bp.synouts.COBA(E=-80))" ] }, { "cell_type": "code", "execution_count": 12, "id": "452899ddd239b01e", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:14.701692800Z", "start_time": "2023-08-27T08:10:12.511462900Z" }, "collapsed": false }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e8de6b0e7e2440de8e15a8f963c92118", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/1000 [00:00" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "net = EINet_v2(scale=1)\n", "runner = bp.DSRunner(net, monitors={'spikes': net.N.spike})\n", "runner.run(100.)\n", "bp.visualize.raster_plot(runner.mon.ts, runner.mon['spikes'], show=True)" ] }, { "cell_type": "markdown", "id": "3cd9e0499b3272b2", "metadata": { "collapsed": false }, "source": [ "## New version (brainpy>=2.4.0)" ] }, { "cell_type": "code", "execution_count": 13, "id": "b0afa6e67fbd25", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:14.717049100Z", "start_time": "2023-08-27T08:10:14.701692800Z" }, "collapsed": false }, "outputs": [], "source": [ "class ExponCOBA(bp.Projection):\n", " def __init__(self, num_pre, post, prob, g_max, tau, E):\n", " super().__init__()\n", " \n", " self.proj = bp.dyn.ProjAlignPostMg1(\n", " comm=bp.dnn.EventCSRLinear(bp.conn.FixedProb(prob, pre=num_pre, post=post.num), g_max),\n", " syn=bp.dyn.Expon.desc(size=post.num, tau=tau),\n", " out=bp.dyn.COBA.desc(E=E),\n", " post=post\n", " )\n", " \n", " def update(self, sps):\n", " return self.proj(sps)\n", " " ] }, { "cell_type": "code", "execution_count": 14, "id": "3b47e563fbf1547f", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:14.718011600Z", "start_time": "2023-08-27T08:10:14.708447900Z" }, "collapsed": false }, "outputs": [], "source": [ "class EINet_v3(bp.DynSysGroup):\n", " def __init__(self, scale=1.):\n", " super().__init__()\n", "\n", " self.num_exc = int(3200 * scale)\n", " self.num_inh = int(800 * scale)\n", "\n", " self.N = HH2(self.num_exc + self.num_inh)\n", " self.Esyn = ExponCOBA(self.num_exc, self.N, 0.02, g_max=0.03 / scale, tau=5, E=0.)\n", " self.Isyn = ExponCOBA(self.num_inh, self.N, 0.02, g_max=0.335 / scale, tau=10., E=-80)\n", " \n", " def update(self):\n", " # update E inputs\n", " e_sps = self.N.spike[:self.num_exc]\n", " self.Esyn(e_sps)\n", " \n", " # update I inputs\n", " i_sps = self.N.spike[self.num_exc:]\n", " self.Isyn(i_sps)\n", " \n", " # update neurons\n", " self.N()\n", " \n", " # monitor\n", " return self.N.spike" ] }, { "cell_type": "code", "execution_count": 15, "id": "9e988f6fece4c64a", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T08:10:18.601587500Z", "start_time": "2023-08-27T08:10:16.840831Z" }, "collapsed": false }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e56ce9ff24634d71b0016413717cab17", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/1000 [00:00" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "net = EINet_v3(scale=1)\n", "indices = np.arange(1000) # 100 ms\n", "sps = bm.for_loop(net.step_run, indices, progress_bar=True)\n", "bp.visualize.raster_plot(indices * bm.get_dt(), sps, show=True)" ] }, { "cell_type": "code", "execution_count": 35, "id": "b61a03c3695df6cb", "metadata": { "ExecuteTime": { "end_time": "2023-08-27T07:53:42.892199Z", "start_time": "2023-08-27T07:53:42.814002100Z" }, "collapsed": false }, "outputs": [], "source": [] } ], "metadata": { "jupytext": { "encoding": "# -*- coding: utf-8 -*-", "formats": "ipynb,py:percent" }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.12" }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, "autocomplete": true, "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 1, "hotkeys": { "equation": "Ctrl-E", "itemize": "Ctrl-I" }, "labels_anchors": false, "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 5 }