Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example of how to detect if a SPA memory is empty #18

Open
Seanny123 opened this issue Jun 14, 2018 · 1 comment
Open

Example of how to detect if a SPA memory is empty #18

Seanny123 opened this issue Jun 14, 2018 · 1 comment

Comments

@Seanny123
Copy link
Collaborator

import nengo_spa as spa
import nengo
import numpy as np

D = 32

sym_keys = {'ONE', 'TWO', 'THREE', 'FOUR'}
vocab = spa.Vocabulary(D)
vocab.populate(";".join(sym_keys))

with spa.Network() as model:

    in_state = spa.State(vocab, represent_identity=False, label="input")
    mem = spa.State(vocab, subdimensions=1,
                    represent_identity=False, feedback=1, label="mem")

    in_state >> mem

    with nengo.presets.ThresholdingEnsembles(0.09):
        ens = nengo.Ensemble(300, 1, radius=1)

    def sum_dims(x):
        return np.sum(np.abs(x)) / (D/2)

    for mem_ens in mem.all_ensembles:
        nengo.Connection(mem_ens, ens, function=sum_dims)
@xchoo
Copy link
Member

xchoo commented Jun 14, 2018

For anyone that wants to have this functionality, note that the code above is sensitive to the dimensionality of the semantic pointers used (i.e. the output of the detection ensemble ens is not consistent for different dimensionalities). The code below can be used across a wider range of dimensionalities without having to tweak it too much (at the expense of some slightly more complex [or obscure] code)

import numpy as np
import matplotlib.pyplot as plt

import nengo
import nengo_spa as spa


D = 64

sym_keys = {'A', 'B', 'C', 'D'}
vocab = spa.Vocabulary(D)
vocab.populate(";".join(sym_keys))


# The function used to generate the semantic pointer stimulus
def stim_func(t):
    if t < 0.3:
        # Start at the NULL / NONE / 0 semantic pointer
        return vocab.parse('0').v
    elif t < 0.6:
        # Present the 'A' semantic pointer for 0.3s
        return vocab.parse('A').v
    elif t < 0.9:
        # Go back to the NULL semantic pointer to demonstrate the memory
        # network storing the value
        return vocab.parse('0').v
    elif t < 1.05:
        # Present the semantic pointer '-A' for 0.15s to erase the 'A'
        # stored in memory.
        return vocab.parse('-A').v
    else:
        # Go back to 0
        return vocab.parse('0').v


with spa.Network() as model:
    # --- Stimulus input node ---
    stim = nengo.Node(stim_func)

    # --- Stimulus input node (GUI version) ---
    # in_state = spa.State(vocab, represent_identity=False, label="input")

    # --- SPA memory network. Note that subdimensions == 1 for improved
    #     performance.
    mem = spa.State(vocab, subdimensions=1,
                    represent_identity=False, feedback=1, label="mem")

    # --- Connect stimulus to SPA memory network
    nengo.Connection(stim, mem.input, synapse=None)

    # --- Connect stimulus to SPA memory network (GUI version)
    # in_state >> mem

    # --- Add a new output (sqr) to the ensemble array in the SPA memory net
    #     This output computes the square (** 2) of each element of the
    #     semantic pointer
    mem.state_ensembles.add_output('sqr', lambda x: x ** 2)

    # --- The output detection ensemble. If nothing is detected in memory,
    #     the output of this ensemble will be 0
    with nengo.presets.ThresholdingEnsembles(0.5):
        ens = nengo.Ensemble(50, 1, radius=1)

    # --- Connect the 'sqr' output of the memory network to the detection
    #     ensemble. Note that the transform computes the sum across all
    #     dimensions.
    nengo.Connection(mem.state_ensembles.sqr, ens, transform=np.ones((1, D)))

    # --- Non-GUI version probes
    pi = nengo.Probe(stim)
    po = nengo.Probe(mem.output, synapse=0.01)
    pd = nengo.Probe(ens, synapse=0.01)

# --- Non-GUI version simulator object
with nengo.Simulator(model) as sim:
    sim.run(1.25)

# --- Non-GUI version plots
plt.figure()
plt.plot(sim.trange(), spa.similarity(sim.data[pi], vocab))
plt.figure()
plt.plot(sim.trange(), spa.similarity(sim.data[po], vocab))
plt.figure()
plt.plot(sim.trange(), sim.data[pd])
plt.show()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants