The Semantic Pointer Architecture provides an approach to building cognitive models implemented with large-scale spiking neural networks.
Nengo includes a nengo.spa
module that provides
a simple interface for building models with
the Semantic Pointer Architecture.
See the following examples for demonstrations
of how nengo.spa
works.
nengo.spa.
SPA
(label=None, seed=None, add_to_container=None, vocabs=None)[source]¶Base class for SPA models.
This expands the standard Network
system to support structured
connections that use Semantic Pointers and associated vocabularies
in their definitions.
To build a SPA model, you can either use with
or create a subclass
of this SPA class.
If you use the with
statement, any attribute added to the SPA network
will be accessible for SPA connections.
If you chose to create a subclass, any Module
object that
is assigned to a member variable will automatically be accessible by the
SPA connection system.
As an example, the following code will build three modules
(two buffers and a memory) that can be referred to as a
, b
,
and c
, respectively.
First, the example with a with
statement:
example = spa.Spa()
with example:
example.a = spa.Buffer(dimensions=8)
example.b = spa.Buffer(dimensions=16)
example.c = spa.Memory(dimensions=8)
Now, the example with a subclass:
class Example(spa.SPA):
def __init__(self):
with self:
self.a = spa.Buffer(dimensions=8)
self.b = spa.Buffer(dimensions=16)
self.c = spa.Memory(dimensions=8)
These names can be used by special modules that are aware of these
names. As an example, the Cortical
module allows you to form connections
between these modules in ways that are aware of semantic pointers:
with example:
example.a = spa.Buffer(dimensions=8)
example.b = spa.Buffer(dimensions=16)
example.c = spa.Memory(dimensions=8)
example.cortical = spa.Cortical(spa.Actions(
'b=a*CAT', 'c=b*~CAT'))
For complex cognitive control, the key modules are the spa.BasalGanglia
and the spa.Thalamus
. Together, these allow us to define complex actions
using the spa.Action
syntax:
class SequenceExample(spa.SPA):
def __init__(self):
self.state = spa.Memory(dimensions=32)
actions = spa.Actions('dot(state, A) --> state=B',
'dot(state, B) --> state=C',
'dot(state, C) --> state=D',
'dot(state, D) --> state=E',
'dot(state, E) --> state=A')
self.bg = spa.BasalGanglia(actions=actions)
self.thal = spa.Thalamus(self.bg)
get_default_vocab
(dimensions)[source]¶Return a Vocabulary with the desired dimensions.
This will create a new default Vocabulary if one doesn’t exist.
get_module_input
(name)[source]¶Return the object to connect into for the given name.
The name will be either the same as a module, or of the form
<module_name>_<input_name>
.
get_module_output
(name)[source]¶Return the object to connect into for the given name.
The name will be either the same as a module, or of the form
<module_name>_<output_name>
.
similarity
(data, probe, vocab=None)[source]¶Return the similarity between the probed data and vocab
.
If no vocabulary is provided, the vocabulary associated with
probe.target
will be used.
Parameters: |
|
---|
nengo.spa.
enable_spa_params
(model)[source]¶Enables the SPA specific parameters on a model.
Parameters: |
|
---|
nengo.spa.
SemanticPointer
(data, rng=None)[source]¶A Semantic Pointer, based on Holographic Reduced Representations.
Operators are overloaded so that +
and -
are addition,
*
is circular convolution, and ~
is the inversion operator.
compare
(other)[source]¶Return the similarity between two SemanticPointers.
This is the normalized dotproduct, or (equivalently), the cosine of the angle between the two vectors.
nengo.spa.
Vocabulary
(dimensions, randomize=True, unitary=False, max_similarity=0.1, include_pairs=False, rng=None)[source]¶A collection of semantic pointers, each with their own text label.
The Vocabulary can also act as a dictionary, with keys as the names
of the semantic pointers and values as the SemanticPointer
objects
themselves. If it is asked for a pointer that does not exist, one will
be automatically created.
Parameters: |
|
---|---|
Attributes: |
|
create_pointer
(attempts=100, unitary=False)[source]¶Create a new semantic pointer.
This will take into account the randomize and max_similarity parameters from self. If a pointer satisfying max_similarity is not generated after the specified number of attempts, the candidate pointer with lowest maximum cosine with all existing pointers is returned.
add
(key, p)[source]¶Add a new semantic pointer to the vocabulary.
The pointer value can be a SemanticPointer
or a vector.
parse
(text)[source]¶Evaluate a text string and return the corresponding SemanticPointer.
This uses the Python eval()
function, so any Python operators that
have been defined for SemanticPointers are valid (+
, -
, *
,
~
, ()
). Any terms do not exist in the vocabulary will be
automatically generated. Valid semantic pointer terms must start
with a capital letter.
If the expression returns a scalar (int or float), a scaled version of the identity SemanticPointer will be returned.
identity
¶Return the identity vector.
text
(v, minimum_count=1, maximum_count=None, threshold=0.1, join=';', terms=None, normalize=False)[source]¶Return a human-readable text version of the provided vector.
This is meant to give a quick text version of a vector for display purposes. To do this, compute the dot product between the vector and all the terms in the vocabulary. The top few vectors are chosen for inclusion in the text. It will try to only return terms with a match above the threshold, but will always return at least minimum_count and at most maximum_count terms. Terms are sorted from most to least similar.
Parameters: |
|
---|
dot
(v)[source]¶Returns the dot product with all terms in the Vocabulary.
Input parameter can either be a SemanticPointer
or a vector.
dot_pairs
(v)[source]¶Returns the dot product with all pairs of terms in the Vocabulary.
Input parameter can either be a SemanticPointer
or a vector.
transform_to
(other, keys=None)[source]¶Create a linear transform from one Vocabulary to another.
This is simply the sum of the outer products of the corresponding terms in each Vocabulary.
Parameters: |
|
---|
prob_cleanup
(similarity, vocab_size, steps=10000)[source]¶Estimate the chance of successful cleanup.
This returns the chance that, out of vocab_size randomly chosen
vectors, at least one of them will be closer to a particular
vector than the value given by compare. To use this, compare
your noisy vector with the ideal vector, pass that value in as
the similarity parameter, and set vocab_size
to be the number of
competing vectors.
The steps parameter sets the accuracy of the approximate integral needed to compute this.
The basic principle used here is that the probability of two random
vectors in a D-dimensional space being a given angle apart is
proportional to sin(angle)**(D-2)
. So we integrate this value
to get a probability of one vector being farther away than the
desired angle, and then raise that to vocab_size to get the
probability that all of them are farther away.
extend
(keys, unitary=False)[source]¶Extends the vocabulary with additional keys.
Creates and adds the semantic pointers listed in keys to the vocabulary.
Parameters: |
|
---|
nengo.spa.
similarity
(data, vocab, normalize=False)[source]¶Return the similarity between some data and the vocabulary.
Computes the dot products between all data vectors and each
vocabulary vector. If normalize=True
, normalizes all vectors
to compute the cosine similarity.
Parameters: |
|
---|
nengo.spa.
Actions
(*args, **kwargs)[source]¶A collection of Action objects.
The *args
and **kwargs
are treated as unnamed and named actions,
respectively. The list of actions are only generated once
process
is called, since it needs access to the list of
module inputs and outputs from the SPA object. The **kwargs
are sorted
alphabetically before being processed.
count
¶Return the number of actions.
nengo.spa.actions.
Action
(sources, sinks, action, name)[source]¶A single action.
Consists of a conditional Expression
(optional) and an Effect
.
Parameters: |
|
---|
nengo.spa.actions.
Expression
(sources, expression)[source]¶Parses an Action expression given a set of module outputs.
Parameters: |
|
---|
nengo.spa.actions.
Effect
(sources, sinks, effect)[source]¶Parses an action effect given a set of module outputs.
The following, in an Action
string, are valid effects:
"motor=A"
"motor=A*B, memory=vision+DOG"
"motor=0.5*(memory*A + vision*B)"
Parameters: |
|
---|
nengo.spa.action_objects.
Symbol
(symbol)[source]¶A set of semantic pointer symbols and associated math.
This is an abstract semantic pointer (not associated with a particular
vocabulary or dimension). It is just meant for keeping track of the
desired manipulations until such time as it is parsed with a particular
Vocabulary
.
Its contents are a single string, and this string is manipulated via
standard mathematical operators (+ - * ~
) for SemanticPointers.
The result will always be able to be passed to Vocabulary.parse
to get a valid SemanticPointer
.
This is used by the spa.Actions
parsing system.
nengo.spa.action_objects.
Source
(name, transform=<nengo.spa.action_objects.Symbol object>, inverted=False)[source]¶A particular source of a vector for the action system.
This will always refer to a particular named output from a
spa.module.Module
. It also tracks a single Symbol
which represents
a desired transformation from that output. For example,
Source('vision') * Symbol('VISION')
will result in a Source
object
for 'vision'
, but with transform set to the Symbol('VISION')
.
This is used by the spa.Actions
parsing system.
nengo.spa.action_objects.
DotProduct
(item1, item2, scale=1.0)[source]¶The dot product of a Source and a Source or a Source and a Symbol.
This represents a similarity measure for computing the utility of
an action. It also maintains a scaling factor on the result,
so that the 0.5 in "0.5*DotProduct(Source('vision'), Symbol('DOG'))"
can be correctly tracked.
This class is meant to be used with an eval-based parsing system in the
Condition
class, so that the above DotProduct
can also be created
with "0.5*dot(vision, 'DOG')"
.
nengo.spa.module.
Module
(label=None, seed=None, add_to_container=None)[source]¶Base class for SPA Modules.
Modules are networks that also have a list of inputs and outputs,
each with an associated Vocabulary
(or a desired dimensionality for
the vocabulary).
The inputs and outputs are dictionaries that map a name to an
(object, Vocabulary) pair. The object can be a Node
or an Ensemble
.
on_add
(spa)[source]¶Called when this is assigned to a variable in the SPA network.
Overload this when you want processing to be delayed until after the module is attached to the SPA network. This is usually for modules that connect to other things in the SPA model (such as the basal ganglia or thalamus).
nengo.spa.
AssociativeMemory
(input_vocab, output_vocab=None, input_keys=None, output_keys=None, default_output_key=None, threshold=0.3, inhibitable=False, wta_output=False, wta_inhibit_scale=3.0, wta_synapse=0.005, threshold_output=False, label=None, seed=None, add_to_container=None)[source]¶Associative memory module.
See Associative memory for an introduction and examples.
Parameters: |
|
---|
nengo.spa.
BasalGanglia
(actions, input_synapse=0.002, label=None, seed=None, add_to_container=None)[source]¶A basal ganglia, performing action selection on a set of given actions.
See networks.BasalGanglia
for more details.
Parameters: |
|
---|
bias
¶Create a bias node, when needed.
on_add
(spa)[source]¶Form the connections into the BG to compute the utilty values.
Each action’s condition variable contains the set of computations needed for that action’s utility value, which is the input to the basal ganglia.
add_bias_input
(index, value)[source]¶Make an input that is just a fixed scalar value.
Parameters: |
|
---|
add_compare_input
(index, source1, source2, scale)[source]¶Make an input that is the dot product of two different sources.
This would be used for an input action such as dot(vision, memory)
.
Each source might be transformed before being compared. If the
two sources have different vocabularies, we use the vocabulary of
the first one for comparison.
Parameters: |
|
---|
add_dot_input
(index, source, symbol, scale)[source]¶Make an input that is the dot product of a Source and a Symbol.
This would be used for an input action such as dot(vision, A)
.
The source may have a transformation applied first.
Parameters: |
|
---|
nengo.spa.
Bind
(dimensions, vocab=None, n_neurons=200, invert_a=False, invert_b=False, input_magnitude=1.0, label=None, seed=None, add_to_container=None)[source]¶A module for binding together two inputs.
Binding is done with circular convolution. For more details on how
this is computed, see the underlying CircularConvolution
network.
Parameters: |
|
---|
nengo.spa.
Buffer
(dimensions, subdimensions=16, neurons_per_dimension=50, vocab=None, direct=False, label=None, seed=None, add_to_container=None)[source]¶A module capable of representing a single vector, with no memory.
This is a minimal SPA module, useful for passing data along (for example, visual input).
Note
Deprecated in Nengo 2.1.0. Use spa.State
instead.
Parameters: |
|
---|
nengo.spa.
Compare
(dimensions, vocab=None, neurons_per_multiply=200, input_magnitude=1.0, label=None, seed=None, add_to_container=None)[source]¶A module for computing the dot product of two inputs.
Parameters: |
|
---|
nengo.spa.
Cortical
(actions, synapse=0.01, neurons_cconv=200, label=None, seed=None, add_to_container=None)[source]¶A SPA module for forming connections between other modules.
Parameters: |
|
---|
add_direct_effect
(target_name, value)[source]¶Make a fixed constant input to a module.
Parameters: |
|
---|
add_route_effect
(target_name, source_name, transform, inverted)[source]¶Connect a module output to a module input.
Parameters: |
|
---|
nengo.spa.
Input
(label=None, seed=None, add_to_container=None, **kwargs)[source]¶A SPA module for providing external inputs to other modules.
The parameters passed to this module indicate the module input name and the function to execute to generate inputs to that module. The functions should always return strings, which will then be parsed by the relevant vocabulary. For example:
def input1(t):
if t < 0.1:
return 'A'
else:
return '0'
spa_net.input = spa.Input(vision=input1, task='X')
will create two inputs:
vision
module, which for the first 0.1 seconds
is the value associated with the 'A'
semantic pointer and then
a vector of all zeros, andtask
module which is always the value associated
with the 'X'
semantic pointer.Parameters: |
|
---|
nengo.spa.
Memory
(dimensions, subdimensions=16, neurons_per_dimension=50, synapse=0.01, vocab=None, tau=None, direct=False, label=None, seed=None, add_to_container=None)[source]¶A SPA module capable of storing a vector over time.
Parameters are the same as spa.Buffer
, with the addition of
synapse
and tau
.
Note
Deprecated in Nengo 2.1.0. Use spa.State
instead.
Parameters: |
|
---|
nengo.spa.
State
(dimensions, subdimensions=16, neurons_per_dimension=50, feedback=0.0, feedback_synapse=0.1, vocab=None, label=None, seed=None, add_to_container=None)[source]¶A module capable of representing a single vector, with optional memory.
This is a minimal SPA module, useful for passing data along (for example, visual input).
Parameters: |
|
---|
nengo.spa.
Thalamus
(bg, neurons_action=50, threshold_action=0.2, mutual_inhibit=1.0, route_inhibit=3.0, synapse_inhibit=0.008, synapse_bg=0.008, synapse_direct=0.01, neurons_channel_dim=50, subdim_channel=16, synapse_channel=0.01, neurons_cconv=200, neurons_gate=40, threshold_gate=0.3, synapse_to_gate=0.002, label=None, seed=None, add_to_container=None)[source]¶A thalamus, implementing the effects for an associated basal ganglia.
See spa.BasalGanglia
for information on the basal ganglia, and
networks.Thalamus
for details on the underlying network.
Parameters: |
|
---|
add_direct_effect
(index, target_name, value)[source]¶Cause an action to drive a particular module input to value.
Parameters: |
|
---|
get_gate
(index, target_name)[source]¶Return the gate for an action.
The gate will be created if it does not already exist. The gate neurons have no activity when the action is selected, but are active when the action is not selected. This makes the gate useful for inhibiting ensembles that should only be active when this action is active.
add_route_effect
(index, target_name, source_name, transform, inverted)[source]¶Set an action to send source to target with the given transform.
Parameters: |
|
---|
add_conv_effect
(index, target_name, effect)[source]¶Set an action to combine two sources and send to target.
Parameters: |
|
---|