{ "cells": [ { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "# *(Niebur, et. al, 2009)* Generalized integrate-and-fire model\n", "\n", "[![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/brainpy/examples/blob/main/neurons/Niebur_2009_GIF.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/neurons/Niebur_2009_GIF.ipynb)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "Implementation of the paper: *Mihalaş, Ştefan, and Ernst Niebur. \"A generalized linear integrate-and-fire neural model produces diverse spiking behaviors.\" Neural computation 21.3 (2009): 704-718.*" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import brainpy as bp" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "## Model Overview" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "Generalized integrate-and-fire model is a spiking neuron model, describes single neuron behavior and can generate most kinds of firing patterns by tuning parameters.\n", "\n", "Generalized IF model is originated from Leaky Integrate-and-Fire model (LIF model), yet it's differentiated from LIF model, for it includes internal currents $I_j$ in its expressions." ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "$$\\frac{d I_j}{d t} = -k_j I_j$$\n", "\n", "$$\\tau\\frac{d V}{d t} = - (V - V_{rest}) + R\\sum_{j}I_j + RI$$\n", "\n", "$$\\frac{d V_{th}}{d t} = a(V - V_{rest}) - b(V_{th} - V_{th\\infty})$$\n" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "Generalized IF neuron fire when $V$ meet $V_{th}$:" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "$$I_j \\leftarrow R_j I_j + A_j$$\n", "\n", "$$V \\leftarrow V_{reset}$$\n", "\n", "$$V_{th} \\leftarrow max(V_{th_{reset}}, V_{th}) $$" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "## Different firing patterns" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "These arbitrary number of internal currents $I_j$ can be seen as currents caused by ion channels' dynamics, provides the GeneralizedIF model a flexibility to generate various firing patterns.\n", "\n", "With appropriate parameters, we can reproduce most of the single neuron firing patterns. In the original paper (Mihalaş et al., 2009), the author used two internal currents $I1$ and $I2$." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "def run(model, duration, I_ext):\n", " runner = bp.DSRunner(model,\n", " inputs=('input', I_ext, 'iter'),\n", " monitors=['V', 'V_th'])\n", " runner.run(duration)\n", "\n", " ts = runner.mon.ts\n", " fig, gs = bp.visualize.get_figure(1, 1, 4, 8)\n", " ax1 = fig.add_subplot(gs[0, 0])\n", " #ax1.title.set_text(f'{mode}')\n", "\n", " ax1.plot(ts, runner.mon.V[:, 0], label='V')\n", " ax1.plot(ts, runner.mon.V_th[:, 0], label='V_th')\n", " ax1.set_xlabel('Time (ms)')\n", " ax1.set_ylabel('Membrane potential')\n", " ax1.set_xlim(-0.1, ts[-1] + 0.1)\n", " plt.legend()\n", "\n", " ax2 = ax1.twinx()\n", " ax2.plot(ts, I_ext, color='turquoise', label='input')\n", " ax2.set_xlabel('Time (ms)')\n", " ax2.set_ylabel('External input')\n", " ax2.set_xlim(-0.1, ts[-1] + 0.1)\n", " ax2.set_ylim(-5., 20.)\n", " plt.legend(loc='lower left')\n", " plt.show()" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "Simulate Generalized IF neuron groups to generate different spiking patterns. Here we plot 20 spiking patterns in groups of 4. The plots are labeled with corresponding pattern names above the plots." ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Tonic Spiking" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:jax._src.lib.xla_bridge:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "83a80ae1924c46e7bbc1389f088b7729", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/2000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(1.5, 200.)])\n", "neu = bp.neurons.GIF(1)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Class 1 Excitability" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "7d8f0de534304aa29009cea46edc70cf", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/5000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(1. + 1e-6, 500.)])\n", "neu = bp.neurons.GIF(1)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Spike Frequency Adaptation" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "26b890ef26b9424bbff286b09e8cb991", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/2000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(2., 200.)])\n", "neu = bp.neurons.GIF(1, a=0.005)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Phasic Spiking" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "9edc59e4c6754c07bca26aa71dc7c236", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/5000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(1.5, 500.)])\n", "neu = bp.neurons.GIF(1, a=0.005)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Accomodation" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "b578ffa482b84b2892b3eb2442a4aa4a", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(1.5, 100.),\n", " (0, 500.),\n", " (0.5, 100.),\n", " (1., 100.),\n", " (1.5, 100.),\n", " (0., 100.)])\n", "neu = bp.neurons.GIF(1, a=0.005)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Threshold Variability" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "1415119c1e384bc580f1964cdfbfb12d", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/4000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(1.5, 20.),\n", " (0., 180.),\n", " (-1.5, 20.),\n", " (0., 20.),\n", " (1.5, 20.),\n", " (0., 140.)])\n", "neu = bp.neurons.GIF(1, a=0.005)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Rebound Spiking" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "57ca0081fcfc4b2794df7f2eb4814077", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(0, 50.), (-3.5, 750.), (0., 200.)])\n", "neu = bp.neurons.GIF(1, a=0.005)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Class 2 Excitability" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "50b1028d44b04fc193869b396cef1c8f", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/2000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(2 * (1. + 1e-6), 200.)])\n", "neu = bp.neurons.GIF(1, a=0.005)\n", "neu.V_th[:] = -30.\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Integrator" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "8a0fe85f507d46ed87363c53c0b268d3", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/4000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(1.5, 20.),\n", " (0., 10.),\n", " (1.5, 20.),\n", " (0., 250.),\n", " (1.5, 20.),\n", " (0., 30.),\n", " (1.5, 20.),\n", " (0., 30.)])\n", "neu = bp.neurons.GIF(1, a=0.005)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Input Bistability" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "0c93a05e4732488fb9a3ff2865895459", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(1.5, 100.),\n", " (1.7, 400.),\n", " (1.5, 100.),\n", " (1.7, 400.)])\n", "neu = bp.neurons.GIF(1, a=0.005)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Hyperpolarization-induced Spiking" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "2532cbc59465487f9979f3534f0f5bd2", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/4000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(-1., 400.)])\n", "neu = bp.neurons.GIF(1, V_th_reset=-60., V_th_inf=-120.)\n", "neu.V_th[:] = -50.\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Hyperpolarization-induced Bursting" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c43e06cb53324ddc9e2f63886efa4784", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/4000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(-1., 400.)])\n", "neu = bp.neurons.GIF(1, V_th_reset=-60., V_th_inf=-120., A1=10.,\n", " A2=-0.6)\n", "neu.V_th[:] = -50.\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Tonic Bursting" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "3c73737fce3e4d229e8124c55a85b1a9", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/5000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(2., 500.)])\n", "neu = bp.neurons.GIF(1, a=0.005, A1=10., A2=-0.6)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Phasic Bursting" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "b8db027369244097ba215e87d6554ea3", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/5000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(1.5, 500.)])\n", "neu = bp.neurons.GIF(1, a=0.005, A1=10., A2=-0.6)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Rebound Bursting" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "552551b51eea4e609700b2d0349635b8", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/10000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(0, 100.), (-3.5, 500.), (0., 400.)])\n", "neu = bp.neurons.GIF(1, a=0.005, A1=10., A2=-0.6)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Mixed Mode" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "320db7224b1b433bbc7dfad15b0a80d7", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/5000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(2., 500.)])\n", "neu = bp.neurons.GIF(1, a=0.005, A1=5., A2=-0.3)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Afterpotentials" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "f2f054deabe24472b0584e8b0e107fb5", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/2000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(2., 15.), (0, 185.)])\n", "neu = bp.neurons.GIF(1, a=0.005, A1=5., A2=-0.3)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Basal Bistability" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "357575fe285d422b9bfc8a1b1792a4a2", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/2000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(5., 10.), (0., 90.), (5., 10.), (0., 90.)])\n", "neu = bp.neurons.GIF(1, A1=8., A2=-0.1)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Preferred Frequency" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "4613e1fb22a94f6196ecbcbbf9a7f010", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/8000 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(5., 10.),\n", " (0., 10.),\n", " (4., 10.),\n", " (0., 370.),\n", " (5., 10.),\n", " (0., 90.),\n", " (4., 10.),\n", " (0., 290.)])\n", "neu = bp.neurons.GIF(1, a=0.005, A1=-3., A2=0.5)\n", "run(neu, duration, Iext)" ] }, { "cell_type": "markdown", "metadata": { "pycharm": { "name": "#%% md\n" } }, "source": [ "### Spike Latency" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "fa22a718feb74c298f815facecc58aed", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/500 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "Iext, duration = bp.inputs.constant_input([(8., 2.), (0, 48.)])\n", "neu = bp.neurons.GIF(1, a=-0.08)\n", "run(neu, duration, Iext)" ] } ], "metadata": { "jupytext": { "encoding": "# -*- coding: utf-8 -*-", "formats": "ipynb,py:percent" }, "kernelspec": { "display_name": "brainpy", "language": "python", "name": "brainpy" }, "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": false, "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": 4 }