Hi all,
Looking at various examples and documentations on nenge SPA, i see that output probing seems to be done exclusively on the State.output
object, that being a Node
.
I see why this happens when a network is contructed of only SPA objects, but what if you employ a more base nengo approach of bulding a network using only Ensemble
s, which you feed a signal using the spa.Input
and spa.State
objects. The first thing that happens is to connect this to an Ensemble
, which is then further used as the de facto model input. Now, I wonder how I should probe the output Ensemble
of such a model. I see that I could connect it to an spa.State
object. But, given that my model does all its “magic” by means of Ensemble
s (and not spa.State
s) this feels a bit unnecessary.
Below I provide a small example model. I look at different ways to probe the ensemble such that I can use it to compare it to a vocabulary: a Node
, and State,input
, and State.output
objects.
import nengo
import nengo.spa as spa
import numpy as np
import matplotlib.pyplot as plt
dim = 64
rng_vocabs = np.random.RandomState()
vocab = spa.Vocabulary(dim, rng=rng_vocabs)
vocab.parse('DOG')
def input_func(t): # input function visual stimuli
if t > 0 and t < 1:
return "DOG"
elif t > 2 and t < 3:
return "DOG"
else:
return "0"
model = nengo.Network()
with model:
model.stim = spa.State(dim, vocab = vocab)
model.inp = spa.Input(stim = input_func)
model.ens_in = nengo.Ensemble(200, dim)
# connect semantic pointer input to input ensemble
nengo.Connection(model.stim.output, model.ens_in)
# This is the ensemble that I wish to probe, to see
# which semantic pointer its activity represents
model.ens_out = nengo.Ensemble(200, dim)
nengo.Connection(model.ens_in, model.ens_out)
model.output_state = spa.State(dim, vocab=vocab)
nengo.Connection(model.ens_out, model.output_state.input, synapse=0.01)
model.output_node = nengo.Node(None, size_in=dim)
nengo.Connection(model.ens_out, model.output_node, synapse=0.01)
output_state_input_probe = nengo.Probe(model.output_state.input)
output_state_output_probe = nengo.Probe(model.output_state.output)
output_node_probe = nengo.Probe(model.output_node)
sim = nengo.Simulator(model)
sim.run(4)
state_input = sim.data[output_state_input_probe]
state_output = sim.data[output_state_output_probe]
node = sim.data[output_node_probe]
# plotting code
ymin, ymax = -3.5,3.5
plt.figure(figsize=(16, 10))
t = sim.trange()
plt.plot(t, spa.similarity(state_input, vocab)+2, label="state.input (shifted +2)")
plt.plot(t, spa.similarity(state_output, vocab), label="state.output")
plt.plot(t, spa.similarity(node, vocab)-2, label="node (shifted -2)")
plt.title("Similarity to the single vocab item at different probe locations")
plt.xlabel("Time")
plt.xlim(right=t[-1])
plt.ylim(ymin, ymax)
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
When the synapse
parameter for the connections that run form the output ensemble are set to 0, we see the following:
data from the probes (seem to) contain the exact same signal. Not unexpected. state.input and node are both just Node
s to which the output ensemble connects. It also comes as no suprise that we see the same for state.input and state.ouput as spa.State
is described in the documentation as being able to “capable of representing a single vector, with optional memory”.
Changing the synapse
value to 0.01 gives the following:
Again, node and state.input are exactly the same, the additional noise seen at state.ouput is not unexpected, given that State.input
and State.ouput
are connected through Ensemble
s.
My question thus is: If my neural model is constructed of only ensembles, and the SPA (and its nengo implementated objects) are used only to provide input to an input ensemble, which of the three described options is best for me if I wish to probe which semantic pointer (or a number of vocabulary items) the output ensemble best represents?
Thank you,
Chiel