Skip to content
Arpit Shah edited this page Dec 8, 2018 · 2 revisions

In this first example, we create a Spiking Neural Network on Loihi with 1 pre-synaptic neuron and 1 post-synaptic neuron. We will also have one Astrocyte listening for spikes from the pre-synaptic neuron and influencing the post-synaptic neuron.

Import the dependencies

import os
import matplotlib as mpl
haveDisplay = "DISPLAY" in os.environ
if not haveDisplay:
    mpl.use('Agg')
import sys
sys.path.append('../')
import matplotlib.pyplot as plt
import nxsdk.api.n2a as nx
from nxsdk.utils.plotutils import plotRaster
import combra_loihi.api as combra

import numpy as np

def gen_rand_spikes(num_neurons: int, sim_time: int, firing_rate: float):
    """ Generate a random array of shape `(num_neurons, sim_time)` to specify spikes for input.

    :param num_neurons: The number of input neurons
    :param sim_time: Number of millisecond timesteps
    :param firing_rate: General firing rate in Hz (i.e. 10 --> 10 Hz)

    :return: 2D array of binary spike values
    """
    random_spikes = np.random.rand(num_neurons, sim_time) < (firing_rate / 1000.)
    random_spikes = [
        np.where(random_spikes[num, :])[0].tolist()
        for num in range(num_neurons)
    ]
    return random_spikes

Create the input pre-synaptic neuron

# to see consistent results from run-to-run
np.random.seed(0)

net = nx.NxNet()
sim_time = 6000

pre_neuron_cnt = 1
post_neuron_cnt = 1

# Create pre-synaptic neuron (spike generator)
pre_synaptic_neurons = net.createSpikeGenProcess(pre_neuron_cnt)
input_spike_times = gen_rand_spikes(pre_neuron_cnt, sim_time, 10)
pre_synaptic_neurons.addSpikes(
    spikeInputPortNodeIds=[num for num in range(pre_neuron_cnt)],
    spikeTimes=input_spike_times)

Create the post-synaptic neuron

# Create post-synaptic neuron
post_neuron_proto = nx.CompartmentPrototype(
    vThMant=10,
    compartmentCurrentDecay=int(1/10*2**12),
    compartmentVoltageDecay=int(1/4*2**12),
    functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE)
post_neurons = net.createCompartmentGroup(
    size=post_neuron_cnt, prototype=post_neuron_proto)

Connect the input to the post-synaptic neuron

# Create a connection from the pre to post-synaptic neuron
conn_proto = nx.ConnectionPrototype()
conn_mask = np.ones(1)
weight = 10 * conn_mask
conn = pre_synaptic_neurons.connect(post_neurons,
                                    prototype=conn_proto,
                                    connectionMask=conn_mask,
                                    weight=weight)

Create an Astrocyte

Here we create an Astrocyte instance with a voltage threshold of 2500 for the IP3 Integrator unit given there is only 1 pre-synaptic neuron and we are simulating just 6 seconds.

# Create Astrocyte and establish connections
astrocyte = combra.Astrocyte(net, ip3VThMant=2500)

Next, we specify the input and output for the Astrocyte so we know which neurons the spikes should be coming from and which neurons the Astrocyte should trigger spikes in.

We set the weight of the connection from the pre-synaptic neuron to the Astrocyte (default=10) to 100.

The weight of the connection from the Astrocyte to the post-synaptic neuron is set to 5 to influence the amount of control the Astrocyte has on triggering spikes in the post-synaptic neuron.

astrocyte.connectInputNeurons(pre_synaptic_neurons, pre_neuron_cnt, weight=100)
astrocyte.connectOutputNeurons(post_neurons, post_neuron_cnt, weight=5)

Create the probes

# Create probes for plots
probes = dict()
probes['post_spikes'] = post_neurons.probe(nx.ProbeParameter.SPIKE)[0]
probes['astro_sr_spikes'] = astrocyte.probe(combra.ASTRO_SPIKE_RECEIVER_PROBE.SPIKE)
probes['astro_ip3_voltage'] = astrocyte.probe(combra.ASTRO_IP3_INTEGRATOR_PROBE.COMPARTMENT_VOLTAGE)
probes['astro_sic_voltage'] = astrocyte.probe(combra.ASTRO_SIC_GENERATOR_PROBE.COMPARTMENT_VOLTAGE)
probes['astro_sg_spikes'] = astrocyte.probe(combra.ASTRO_SPIKE_GENERATOR_PROBE.SPIKE)

Run the network

net.run(sim_time)
net.disconnect()

Plot the results

# Plots

fig = plt.figure(1, figsize=(18, 28))
ax0 = plt.subplot(7, 1, 1)
ax0.set_xlim(0, sim_time)
plotRaster(input_spike_times)
plt.ylabel('neuron index')
plt.xlabel('time (ms)')
plt.title('Presynaptic neurons poisson spikes')

ax1 = plt.subplot(7, 1, 2)
ax1.set_xlim(0, sim_time)
probes['astro_sr_spikes'].plot()
plt.xlabel('time (ms)')
plt.title('Astrocyte compartment 1: Spike receiver spikes')

ax2 = plt.subplot(7, 1, 3)
ax2.set_xlim(0, sim_time)
probes['astro_ip3_voltage'].plot()
plt.xlabel('time (ms)')
plt.title('Astrocyte compartment 2: IP3 integrator voltage')

ax3 = plt.subplot(7, 1, 4)
ax3.set_xlim(0, sim_time)
probes['astro_sic_voltage'].plot()
plt.xlabel('time (ms)')
plt.title('Astrocyte compartment 3: SIC generator voltage')

ax4 = plt.subplot(7, 1, 5)
ax4.set_xlim(0, sim_time)
probes['astro_sg_spikes'].plot()
plt.xlabel('time (ms)')
plt.title('Astrocyte compartment 4: Spike generator spikes')

ax5 = plt.subplot(7, 1, 6)
ax5.set_xlim(0, sim_time)
probes['post_spikes'].plot()

plt.tight_layout()
fileName = "example1_output.svg"
print("No display available, saving to file " + fileName + ".")
fig.savefig(fileName)

Plotting the firing rate for the post-synaptic neuron

We have a utility function for plotting the firing rate of a neuron. The function requires:

  • name for the plot
  • directory to store the output file in
  • Numpy ndarray containing the spike data from a probe
  • output format for the image
combra.FiringRatePlot('Example 1: Post-Synaptic Neuron Firing Rate', './', probes['post_spikes'].data, 'svg')

Results of example 1

Dynamics of compartments in NAN

example 1

Postsynaptic neuron firing rate

example 1 post fr

Clone this wiki locally