Reusable networks

Networks are an abstraction of a grouping of Nengo objects (i.e., Node, Ensemble, Connection, and Network instances, though usually not Probe instances.) Like most abstractions, this helps with code-reuse and maintainability. You’ll find the documentation for the reusable networks included with Nengo below.

You may also want to build your own reusable networks. Doing so can help encapsulate parts of your model, making your code easier to understand, easier to re-use, and easier to share. The following examples will help you build your own reusable networks:

You may also find the config system documentation useful.

nengo.networks.EnsembleArray An array of ensembles.
nengo.networks.BasalGanglia Winner take all network, typically used for action selection.
nengo.networks.Thalamus Inhibits non-selected actions.
nengo.networks.AssociativeMemory Associative memory network.
nengo.networks.CircularConvolution Compute the circular convolution of two vectors.
nengo.networks.Integrator An ensemble that accumulates input and maintains state.
nengo.networks.Oscillator A two-dimensional ensemble with interacting recurrent connections.
nengo.networks.Product Computes the element-wise product of two equally sized vectors.
nengo.networks.InputGatedMemory Stores a given vector in memory, with input controlled by a gate.
class nengo.networks.EnsembleArray(n_neurons, n_ensembles, ens_dimensions=1, neuron_nodes=False, label=None, seed=None, add_to_container=None, **ens_kwargs)[source]

An array of ensembles.

This acts, in some ways, like a single high-dimensional ensemble, but actually consists of many sub-ensembles, each one representing a separate dimension. This tends to be much faster to create and can be more accurate than having one huge high-dimensional ensemble. However, since the neurons represent different dimensions separately, we cannot compute nonlinear interactions between those dimensions.

Note that in addition to the parameters below, parameters affecting all of the sub-ensembles can be passed to the ensemble array. For example:

ea = nengo.networks.EnsembleArray(20, 2, radius=1.5)

creates an ensemble array with 2 sub-ensembles, each with 20 neurons, and a radius of 1.5.

Parameters:
n_neurons : int

The number of neurons in each sub-ensemble.

n_ensembles : int

The number of sub-ensembles to create.

ens_dimensions : int, optional (Default: 1)

The dimensionality of each sub-ensemble.

neuron_nodes : bool, optional (Default: False)

Whether to create a node that provides access to each individual neuron, typically for the purpose of inhibiting the entire EnsembleArray.

Note

Deprecated in Nengo 2.1.0. Call add_neuron_input or add_neuron_output instead.

label : str, optional (Default: None)

A name to assign this EnsembleArray. Used for visualization and debugging.

seed : int, optional (Default: None)

Random number seed that will be used in the build step.

add_to_container : bool, optional (Default: None)

Determines if this network will be added to the current container. If None, this network will be added to the network at the top of the Network.context stack unless the stack is empty.

Attributes:
dimensions_per_ensemble : int

The dimensionality of each sub-ensemble.

ea_ensembles : list

The sub-ensembles in the ensemble array.

input : Node

A node that provides input to all of the ensembles in the array.

n_ensembles : int

The number of sub-ensembles to create.

n_neurons_per_ensemble : int

The number of neurons in each sub-ensemble.

neuron_input : Node or None

A node that provides input to all the neurons in the ensemble array. None unless created in add_neuron_input.

neuron_output : Node or None

A node that gathers neural output from all the neurons in the ensemble array. None unless created in add_neuron_output.

output : Node

A node that gathers decoded output from all of the ensembles in the array.

dimensions

(int) Dimensionality of the ensemble array.

add_neuron_input()[source]

Adds a node that provides input to the neurons of all ensembles.

Direct neuron input is useful for inhibiting the activity of all neurons in the ensemble array.

This node is accessible through the ‘neuron_input’ attribute of this ensemble array.

add_neuron_output()[source]

Adds a node that collects the neural output of all ensembles.

Direct neuron output is useful for plotting the spike raster of all neurons in the ensemble array.

This node is accessible through the ‘neuron_output’ attribute of this ensemble array.

add_output(name, function, synapse=None, **conn_kwargs)[source]

Adds a node that collects the decoded output of all ensembles.

By default, this is called once in __init__ with function=None. However, this can be called multiple times with different functions, similar to the way in which an ensemble can be connected to many downstream ensembles with different functions.

Note that in addition to the parameters below, parameters affecting all of the connections from the sub-ensembles to the new node can be passed to this function. For example:

ea.add_output('output', None, solver=nengo.solers.Lstsq())

creates a new output with the decoders of each connection solved for with the Lstsq solver.

Parameters:
name : str

The name of the output. This will also be the name of the attribute set on the ensemble array.

function : callable or iterable of callables

The function to compute across the connection from sub-ensembles to the new output node. If function is an iterable, it must be an iterable consisting of one function for each sub-ensemble.

synapse : Synapse, optional (Default: None)

The synapse model with which to filter the connections from sub-ensembles to the new output node. This is kept separate from the other conn_kwargs because this defaults to None rather than the default synapse model. In almost all cases the synapse should stay as None, and synaptic filtering should be performed in the connection from the output node.

nengo.networks.BasalGanglia(dimensions, n_neurons_per_ensemble=100, output_weight=-3.0, input_bias=0.0, ampa_config=None, gaba_config=None, net=None)[source]

Winner take all network, typically used for action selection.

The basal ganglia network outputs approximately 0 at the dimension with the largest value, and is negative elsewhere.

While the basal ganglia is primarily defined by its winner-take-all function, it is also organized to match the organization of the human basal ganglia. It consists of five ensembles:

  • Striatal D1 dopamine-receptor neurons (strD1)
  • Striatal D2 dopamine-receptor neurons (strD2)
  • Subthalamic nucleus (stn)
  • Globus pallidus internus / substantia nigra reticulata (gpi)
  • Globus pallidus externus (gpe)

Interconnections between these areas are also based on known neuroanatomical connections. See [1] for more details, and [2] for the original non-spiking basal ganglia model by Gurney, Prescott & Redgrave that this model is based on.

Note

The default Solver for the basal ganglia is NnlsL2nz, which requires SciPy. If SciPy is not installed, the global default solver will be used instead.

Parameters:
dimensions : int

Number of dimensions (i.e., actions).

n_neurons_per_ensemble : int, optional (Default: 100)

Number of neurons in each ensemble in the network.

output_weight : float, optional (Default: -3.)

A scaling factor on the output of the basal ganglia (specifically on the connection out of the GPi).

input_bias : float, optional (Default: 0.)

An amount by which to bias all dimensions of the input node. Biasing the input node is important for ensuring that all input dimensions are positive and easily comparable.

ampa_config : config, optional (Default: None)

Configuration for connections corresponding to biological connections to AMPA receptors (i.e., connections from STN to to GPi and GPe). If None, a default configuration using a 2 ms lowpass synapse will be used.

gaba_config : config, optional (Default: None)

Configuration for connections corresponding to biological connections to GABA receptors (i.e., connections from StrD1 to GPi, StrD2 to GPe, and GPe to GPi and STN). If None, a default configuration using an 8 ms lowpass synapse will be used.

net : Network, optional (Default: None)

A network in which the network components will be built. This is typically used to provide a custom set of Nengo object defaults through modifying net.config.

Returns:
net : Network

The newly built basal ganglia network, or the provided net.

References

[1](1, 2) Stewart, T. C., Choo, X., & Eliasmith, C. (2010). Dynamic behaviour of a spiking model of action selection in the basal ganglia. In Proceedings of the 10th international conference on cognitive modeling (pp. 235-40).
[2](1, 2) Gurney, K., Prescott, T., & Redgrave, P. (2001). A computational model of action selection in the basal ganglia. Biological Cybernetics 84, 401-423.
Attributes:
net.bias_input : Node or None

If input_bias is non-zero, this node will be created to bias all of the dimensions of the input signal.

net.gpe : EnsembleArray

Globus pallidus externus ensembles.

net.gpi : EnsembleArray

Globus pallidus internus ensembles.

net.input : Node

Accepts the input signal.

net.output : Node

Provides the output signal.

net.stn : EnsembleArray

Subthalamic nucleus ensembles.

net.strD1 : EnsembleArray

Striatal D1 ensembles.

net.strD2 : EnsembleArray

Striatal D2 ensembles.

nengo.networks.Thalamus(dimensions, n_neurons_per_ensemble=50, mutual_inhib=1.0, threshold=0.0, net=None)[source]

Inhibits non-selected actions.

The thalamus is intended to work in tandem with a basal ganglia network. It converts basal ganglia output into a signal with (approximately) 1 for the selected action and 0 elsewhere.

In order to suppress low responses and strengthen high responses, a constant bias is added to each dimension (i.e., action), and dimensions mutually inhibit each other. Additionally, the ensemble representing each dimension is created with positive encoders and can be assigned positive x-intercepts to threshold low responses.

Parameters:
dimensions : int

Number of dimensions (i.e., actions).

n_neurons_per_ensemble : int, optional (Default: 50)

Number of neurons in each ensemble in the network.

mutual_inhib : float, optional (Default: 1.)

Strength of the mutual inhibition between actions.

threshold : float, optional (Default: 0.)

The threshold below which values will not be represented.

net : Network, optional (Default: None)

A network in which the network components will be built. This is typically used to provide a custom set of Nengo object defaults through modifying net.config.

Returns:
net : Network

The newly built thalamus network, or the provided net.

Attributes:
net.actions : EnsembleArray

Each ensemble represents one dimension (action).

net.bias : Node

The constant bias injected in each actions ensemble.

net.input : Node

Input to the actions ensembles.

net.output : Node

Output from the actions ensembles.

class nengo.networks.AssociativeMemory(input_vectors, output_vectors=None, n_neurons=50, threshold=0.3, input_scales=1.0, inhibitable=False, label=None, seed=None, add_to_container=None)[source]

Associative memory network.

Parameters:
input_vectors: array_like

The list of vectors to be compared against.

output_vectors: array_like, optional (Default: None)

The list of vectors to be produced for each match. If None, the associative memory will be autoassociative (cleanup memory).

n_neurons: int, optional (Default: 50)

The number of neurons for each of the ensemble (where each ensemble represents each item in the input_vectors list).

threshold: float, optional (Default: 0.3)

The association activation threshold.

input_scales: float or array_like, optional (Default: 1.0)

Scaling factor to apply on each of the input vectors. Note that it is possible to scale each vector independently.

inhibitable: bool, optional (Default: False)

Flag to indicate if the entire associative memory module is inhibitable (entire thing can be shut off). The input gain into the inhibitory connection is 1.5.

label : str, optional (Default: None)

A name for the ensemble. Used for debugging and visualization.

seed : int, optional (Default: None)

The seed used for random number generation.

add_to_container : bool, optional (Default: None)

Determines if the network will be added to the current container. If None, will be true if currently within a Network.

am_ens_config

(Config) Defaults for associative memory ensemble creation.

default_ens_config

(Config) Defaults for other ensemble creation.

thresh_ens_config

(Config) Defaults for threshold ensemble creation.

add_input_mapping(name, input_vectors, input_scales=1.0)[source]

Adds a set of input vectors to the associative memory network.

Creates a transform with the given input vectors between the a named input node and associative memory element input to enable the inputs to be mapped onto ensembles of the Associative Memory.

Parameters:
name: str

Name to use for the input node. This name will be used as the name of the attribute for the associative memory network.

input_vectors: array_like

The list of vectors to be compared against.

input_scales: float or array_like, optional (Default: 1.0)

Scaling factor to apply on each of the input vectors. Note that it is possible to scale each vector independently.

add_output_mapping(name, output_vectors)[source]

Adds another output to the associative memory network.

Creates a transform with the given output vectors between the associative memory element output and a named output node to enable the selection of output vectors by the associative memory.

Parameters:
name: str

Name to use for the output node. This name will be used as the name of the attribute for the associative memory network.

output_vectors: array_like

The list of vectors to be produced for each match.

add_default_output_vector(output_vector, output_name='output', n_neurons=50, min_activation_value=0.5)[source]

Adds a default output vector to the associative memory network.

The default output vector is chosen if the input matches none of the given input vectors.

Parameters:
output_vector: array_like

The vector to be produced if the input value matches none of the vectors in the input vector list.

output_name: str, optional (Default: ‘output’)

The name of the input to which the default output vector should be applied.

n_neurons: int, optional (Default: 50)

Number of neurons to use for the default output vector ensemble.

min_activation_value: float, optional (Default: 0.5)

Minimum activation value (i.e. threshold) to use to disable the default output vector.

add_wta_network(inhibit_scale=1.5, inhibit_synapse=0.005)[source]

Add a winner-take-all (WTA) network to associative memory output.

Parameters:
inhibit_scale: float, optional (Default: 1.5)

Mutual inhibition scaling factor.

inhibit_synapse: float, optional (Default: 0.005)

Mutual inhibition synapse time constant.

add_threshold_to_outputs(n_neurons=50, inhibit_scale=10)[source]

Adds a thresholded output to the associative memory.

Parameters:
n_neurons: int, optional (Default: 50)

Number of neurons to use for the default output vector ensemble.

inhibit_scale: float, optional (Default: 10)

Mutual inhibition scaling factor.

nengo.networks.CircularConvolution(n_neurons, dimensions, invert_a=False, invert_b=False, input_magnitude=1.0, net=None, **kwargs)[source]

Compute the circular convolution of two vectors.

The circular convolution \(c\) of vectors \(a\) and \(b\) is given by

\[c[i] = \sum_j a[j] b[i - j]\]

where negative indices on \(b\) wrap around to the end of the vector.

This computation can also be done in the Fourier domain,

\[c = DFT^{-1} ( DFT(a) DFT(b) )\]

where \(DFT\) is the Discrete Fourier Transform operator, and \(DFT^{-1}\) is its inverse. This network uses this method.

Parameters:
n_neurons : int

Number of neurons to use in each product computation

dimensions : int

The number of dimensions of the input and output vectors.

invert_a, invert_b : bool, optional (Default: False, False)

Whether to reverse the order of elements in either the first input (invert_a) or the second input (invert_b). Flipping the second input will make the network perform circular correlation instead of circular convolution.

input_magnitude : float, optional (Default: 1.0)

The expected magnitude of the vectors to be convolved. This value is used to determine the radius of the ensembles computing the element-wise product.

kwargs

Keyword arguments passed through to nengo.Network.

Returns:
net : Network

The newly built product network, or the provided net.

Notes

The network maps the input vectors \(a\) and \(b\) of length N into the Fourier domain and aligns them for complex multiplication. Letting \(F = DFT(a)\) and \(G = DFT(b)\), this is given by:

[ F[i].real ]     [ G[i].real ]     [ w[i] ]
[ F[i].imag ]  *  [ G[i].imag ]  =  [ x[i] ]
[ F[i].real ]     [ G[i].imag ]     [ y[i] ]
[ F[i].imag ]     [ G[i].real ]     [ z[i] ]

where \(i\) only ranges over the lower half of the spectrum, since the upper half of the spectrum is the flipped complex conjugate of the lower half, and therefore redundant. The input transforms are used to perform the DFT on the inputs and align them correctly for complex multiplication.

The complex product \(H = F * G\) is then

\[H[i] = (w[i] - x[i]) + (y[i] + z[i]) I\]

where \(I = \sqrt{-1}\). We can perform this addition along with the inverse DFT \(c = DFT^{-1}(H)\) in a single output transform, finding only the real part of \(c\) since the imaginary part is analytically zero.

Examples

A basic example computing the circular convolution of two 10-dimensional vectors represented by ensemble arrays:

A = EnsembleArray(50, n_ensembles=10)
B = EnsembleArray(50, n_ensembles=10)
C = EnsembleArray(50, n_ensembles=10)
cconv = nengo.networks.CircularConvolution(50, dimensions=10)
nengo.Connection(A.output, cconv.input_a)
nengo.Connection(B.output, cconv.input_b)
nengo.Connection(cconv.output, C.input)
Attributes:
net.input_a : Node

The first vector to be convolved.

net.input_b : Node

The second vector to be convolved.

net.product : Network

Network created with Product to do the element-wise product of the \(DFT\) components.

net.output : Node

The resulting convolved vector.

nengo.networks.Integrator(recurrent_tau, n_neurons, dimensions, net=None, **kwargs)[source]

An ensemble that accumulates input and maintains state.

This is accomplished through scaling the input signal and recurrently connecting an ensemble to itself to maintain state.

Parameters:
recurrent_tau : float

Time constant on the recurrent connection.

n_neurons : int

Number of neurons in the recurrently connected ensemble.

dimensions : int

Dimensionality of the input signal and ensemble.

kwargs

Keyword arguments passed through to nengo.Network.

Returns:
net : Network

The newly built product network, or the provided net.

Attributes:
net.ensemble : Ensemble

The recurrently connected ensemble.

net.input : Node

Provides the input signal.

nengo.networks.Oscillator(recurrent_tau, frequency, n_neurons, net=None, **kwargs)[source]

A two-dimensional ensemble with interacting recurrent connections.

The ensemble connects to itself in a manner similar to the integrator; however, here the two dimensions interact with each other to implement a cyclic oscillator.

Parameters:
recurrent_tau : float

Time constant on the recurrent connection.

frequency : float

Desired frequency, in Hz, of the cyclic oscillation.

n_neurons : int

Number of neurons in the recurrently connected ensemble.

kwargs

Keyword arguments passed through to nengo.Network.

Returns:
net : Network

The newly built product network, or the provided net.

Attributes:
net.ensemble : Ensemble

The recurrently connected oscillatory ensemble.

net.input : Node

Provides the input signal.

nengo.networks.Product(n_neurons, dimensions, input_magnitude=1.0, net=None, **kwargs)[source]

Computes the element-wise product of two equally sized vectors.

The network used to calculate the product is described in Gosmann, 2015. A simpler version of this network can be found in the Multiplication example.

Note that this network is optimized under the assumption that both input values (or both values for each input dimensions of the input vectors) are uniformly and independently distributed. Visualized in a joint 2D space, this would give a square of equal probabilities for pairs of input values. This assumption is violated with non-uniform input value distributions (for example, if the input values follow a Gaussian or cosine similarity distribution). In that case, no square of equal probabilities is obtained, but a probability landscape with circular equi-probability lines. To obtain the optimal network accuracy, scale the input_magnitude by a factor of 1 / sqrt(2).

Parameters:
n_neurons : int

Number of neurons per dimension in the vector.

Note

These neurons will be distributed evenly across two ensembles. If an odd number of neurons is specified, the extra neuron will not be used.

dimensions : int

Number of dimensions in each of the vectors to be multiplied.

input_magnitude : float, optional (Default: 1.)

The expected magnitude of the vectors to be multiplied. This value is used to determine the radius of the ensembles computing the element-wise product.

kwargs

Keyword arguments passed through to nengo.Network.

Returns:
net : Network

The newly built product network, or the provided net.

Attributes:
net.input_a : Node

The first vector to be multiplied.

net.input_b : Node

The second vector to be multiplied.

net.output : Node

The resulting product.

net.sq1 : EnsembleArray

Represents the first squared term. See Gosmann, 2015 for details.

net.sq2 : EnsembleArray

Represents the second squared term. See Gosmann, 2015 for details.

nengo.networks.InputGatedMemory(n_neurons, dimensions, feedback=1.0, difference_gain=1.0, recurrent_synapse=0.1, difference_synapse=None, net=None, **kwargs)[source]

Stores a given vector in memory, with input controlled by a gate.

Parameters:
n_neurons : int

Number of neurons per dimension in the vector.

dimensions : int

Dimensionality of the vector.

feedback : float, optional (Default: 1.0)

Strength of the recurrent connection from the memory to itself.

difference_gain : float, optional (Default: 1.0)

Strength of the connection from the difference ensembles to the memory ensembles.

recurrent_synapse : float, optional (Default: 0.1)
difference_synapse : Synapse (Default: None)

If None, …

kwargs

Keyword arguments passed through to nengo.Network.

Returns:
net : Network

The newly built memory network, or the provided net.

Attributes:
net.diff : EnsembleArray

Represents the difference between the desired vector and the current vector represented by mem.

net.gate : Node

With input of 0, the network is not gated, and mem will be updated to minimize diff. With input greater than 0, the network will be increasingly gated such that mem will retain its current value, and diff will be inhibited.

net.input : Node

The desired vector.

net.mem : EnsembleArray

Integrative population that stores the vector.

net.output : Node

The vector currently represented by mem.

net.reset : Node

With positive input, the mem population will be inhibited, effectively wiping out the vector currently being remembered.