Lec 3 Spiking Neuron Modeling with BrainCog

In this tutorial, I will share with you how to use braincog to build neurons and visualize their dynamic properties. braincog provides a rich set of predefined neuron models, and I will walk you through the relevant modules in braincog by building a new neuron type with you.

Neuron Simulation in BrainCog

Creating neuron class

Import the braincog package.

import torch
from torch import nn
import matplotlib.pyplot as plt
from braincog.base.node.node import BaseNode, LIFNode, IzhNode
from braincog.base.strategy.surrogate import *
from braincog.base.utils.visualization import spike_rate_vis, spike_rate_vis_1d

Defining the class of a new neuron

class TestNode(BaseNode):
    def __init__(self, threshold=1., tau=2., act_fun=QGateGrad, *args, **kwargs):
        super().__init__(threshold, *args, **kwargs)
        self.tau = tau
        if isinstance(act_fun, str):
            act_fun = eval(act_fun)
        self.act_fun = act_fun(alpha=2., requires_grad=False)
    def integral(self, inputs):
        self.mem = self.mem + ((inputs - self.mem) / self.tau) * self.dt
    def calc_spike(self):
        self.spike = self.act_fun(self.mem - self.get_thres())
        self.mem = self.mem * (1 - self.spike.detach())

The neuron model should inherit from BaseNode, and should implement at least three methods: initialize, integral, and calc_spike. This way we have implemented a TestNode class with the same model as the LIF neuron model.

Neuron Simulation and Visualization

BrainCog provides a simple interface and a rich set of visualization tools. You can easily use braincog for neuronal behavior simulation and visualization.

For example, we can easily simulate the TestNode we just designed by.

x = torch.rand(1, 10, 10)
lif = TestNode(threshold=0.3, tau=2.)
## Reset Before use
lif.n_reset()
spike = lif(x)
spike_rate_vis(x)

All neurons need to be reset before use to ensure that the membrane potential of the neuron is at resting potential. The above code allows the visualization of the input currents and pulses of the neuron.

Input Current

Neuron Spikes

BrainCog also supports efficient simulation of neurons on a larger scale and allows easy visualization of the behavior of neurons in terms of spiking rate.


lif = TestNode(threshold=0.5)
x = torch.rand(100, 100)
spike = []

lif.n_reset()
for t in range(50):
spike.append(lif(x))

spike = torch.stack(spike)
spike_rate_vis(spike)

Spiking rate of neurons

BrainCog also supports time-domain analysis of different neurons. The following code implements the time-domain behavior analysis of neurons.

lif = IzhNode(threshold=0.5, tau=2.)
x = torch.rand(100)
spike = []

lif.n_reset()
for t in range(1000):
spike.append(lif(50 * x))

spike = torch.stack(spike)

spike_rate_vis_1d(spike)

Time domain dynamic properties of the Izhikevich model

Of course, we can also use braincog to analyze the behavior of a neuron in detail.


spike_rate_vis_1d(spike)
#%%
lif = IzhNode(threshold=.5)
lif.n_reset()
lif.requires_fp = True

mem = []
spike = []
for t in range(100):
x = torch.tensor(10)
# x = torch.rand(1)
spike.append(lif(x))
mem.append(lif.mem)

mem = torch.stack(mem)
spike = torch.stack(spike)

outputs = torch.max(mem, spike).detach().cpu().numpy()

plt.plot(outputs)
plt.savefig('lif.pdf', bbox_inches='tight')

Time-domain characteristics of the membrane potential of a single neuron

The figure above shows the behavior of a LIF neuron with a constant current input.

Braincog provides an easy-to-use interface for neuron construction, neuron simulation and visualization.