コード例 #1
0
def test_unbind(Simulator, algebra, side, seed):
    rng = np.random.RandomState(seed)
    vocab = spa.Vocabulary(64, pointer_gen=rng, algebra=algebra)
    vocab.populate('A; B')

    with spa.Network(seed=seed) as model:
        model.bind = spa.Bind(vocab,
                              unbind_left=(side == 'left'),
                              unbind_right=(side == 'right'))

        if side == 'left':
            spa.sym.B >> model.bind.input_left
            spa.sym.B * spa.sym.A >> model.bind.input_right
        elif side == 'right':
            spa.sym.A * spa.sym.B >> model.bind.input_left
            spa.sym.B >> model.bind.input_right
        else:
            raise ValueError("Invalid 'side' value.")

    with model:
        p = nengo.Probe(model.bind.output, synapse=0.03)

    with Simulator(model) as sim:
        sim.run(0.2)

    assert_sp_close(sim.trange(),
                    sim.data[p],
                    vocab.parse('A * B * ~B'),
                    skip=0.15,
                    atol=0.3)
コード例 #2
0
def test_run(Simulator, algebra, seed):
    rng = np.random.RandomState(seed)
    vocab = spa.Vocabulary(16, pointer_gen=rng, algebra=algebra)
    vocab.populate('A; B')

    with spa.Network(seed=seed) as model:
        model.bind = spa.Bind(vocab)

        def inputA(t):
            if 0 <= t < 0.1:
                return 'A'
            else:
                return 'B'

        model.input = spa.Transcode(inputA, output_vocab=vocab)
        model.input >> model.bind.input_left
        spa.sym.A >> model.bind.input_right

    with model:
        p = nengo.Probe(model.bind.output, synapse=0.03)

    with Simulator(model) as sim:
        sim.run(0.2)

    error = rmse(vocab.parse("(B*A).normalized()").v, sim.data[p][-1])
    assert error < 0.15

    error = rmse(vocab.parse("(A*A).normalized()").v, sim.data[p][100])
    assert error < 0.15
コード例 #3
0
ファイル: ose.py プロジェクト: ctn-archive/cue-model
    def __init__(self, vocab=Default, gamma=0.9775, **kwargs):
        kwargs.setdefault('label', 'OSE')
        super(OSE, self).__init__(**kwargs)

        self.vocab = vocab

        with self:
            self.input_item = nengo.Node(size_in=self.vocab.dimensions)
            self.input_pos = nengo.Node(size_in=self.vocab.dimensions)
            self.input_store = nengo.Node(size_in=1)

            self.bind = spa.Bind(self.vocab)
            nengo.Connection(self.input_item, self.bind.input_a)
            nengo.Connection(self.input_pos, self.bind.input_b)

            with nengo.Config(spa.State) as cfg:
                cfg[spa.State].neurons_per_dimension = 150
                cfg[spa.State].subdimensions = 4

                self.combine = GatedMemory(vocab)
                nengo.Connection(self.bind.output, self.combine.input)

                self.mem = GatedMemory(vocab)
                nengo.Connection(self.combine.output, self.mem.input)
                nengo.Connection(self.mem.output,
                                 self.combine.input,
                                 transform=gamma)

            nengo.Connection(self.input_store, self.combine.input_store)
            nengo.Connection(self.input_store,
                             self.mem.input_store,
                             transform=-1)
            self.bias = nengo.Node(1.)
            nengo.Connection(self.bias, self.mem.input_store)

            self.recall = spa.Bind(self.vocab, invert_a=True)
            nengo.Connection(self.input_pos, self.recall.input_a)
            nengo.Connection(self.mem.output, self.recall.input_b)
            self.output = self.recall.output

        self.inputs = dict(input_item=(self.input_item, self.vocab),
                           input_pos=(self.input_pos, self.vocab),
                           input_store=(self.input_store, None))
        self.outputs = dict(default=(self.output, self.vocab))
コード例 #4
0
def test_basic():
    with spa.Network():
        bind = spa.Bind(vocab=16)

    # all inputs and outputs should share the same vocab
    vocab_a = spa.Network.get_input_vocab(bind.input_left)
    vocab_b = spa.Network.get_input_vocab(bind.input_right)
    assert vocab_a is vocab_b
    assert vocab_a.dimensions == 16
    assert vocab_b.dimensions == 16
コード例 #5
0
    def __init__(self,
                 vocab,
                 label,
                 n_neurons_per_dim,
                 rng,
                 BG_bias,
                 BG_thr,
                 feedback,
                 sender=True,
                 receiver=True,
                 **kwargs):

        super(ADDProcessor, self).__init__(input_vocab=vocab,
                                           output_vocab=vocab,
                                           label=label,
                                           n_neurons_per_dim=n_neurons_per_dim,
                                           mapping=['D2', 'D4', 'D6', 'D8'],
                                           threshold=0,
                                           feedback=feedback,
                                           sender=sender,
                                           receiver=receiver,
                                           **kwargs)

        with self:
            # Domain specific processing
            self.bind = spa.Bind(vocab, n_neurons_per_dim['Bind'])

            with spa.Network() as self.result_controller:
                self.result_controller.labels = []
                with spa.ActionSelection() as self.result_controller.AS:
                    self.result_controller.labels.append("D0 -> D8")
                    spa.ifmax(self.result_controller.labels[-1],
                              BG_bias + spa.dot(s.D0, self.bind.output),
                              s.D8 >> self.AM.input)
                    self.result_controller.labels.append("D10 -> D2")
                    spa.ifmax(self.result_controller.labels[-1],
                              BG_bias + spa.dot(s.D10, self.bind.output),
                              s.D2 >> self.AM.input)
                    self.result_controller.labels.append("no cycle")
                    spa.ifmax(self.result_controller.labels[-1],
                              BG_bias + BG_thr, self.bind >> self.AM.input)

            nengo.Connection(self.input.output, self.bind.input_left)
コード例 #6
0
def test_non_default_input_and_output(Simulator, rng):
    vocab = spa.Vocabulary(32, pointer_gen=rng)
    vocab.populate("A; B")

    with spa.Network() as model:
        a = spa.Transcode("A", output_vocab=vocab)
        b = spa.Transcode("B", output_vocab=vocab)
        bind = spa.Bind(vocab)
        a.output >> bind.input_left
        b.output >> bind.input_right
        p = nengo.Probe(bind.output, synapse=0.03)

    with Simulator(model) as sim:
        sim.run(0.5)

    assert_sp_close(sim.trange(),
                    sim.data[p],
                    vocab.parse("A*B"),
                    skip=0.3,
                    atol=0.3)
コード例 #7
0
    def __init__(
            self, protocol, task_vocabs, beta, gamma=0.9775, ose_thr=0.2,
            ordinal_prob=0.2, recall_noise=0., min_evidence=0.025,
            decay=1., extensions=None, **kwargs):
        kwargs.setdefault('label', 'CUE')
        super(CUE, self).__init__(**kwargs)

        if extensions is None:
            extensions = set()

        self.task_vocabs = task_vocabs

        with self:
            self.config[spa.State].represent_identity = False

            self.bias = nengo.Node(1.)
            self.ctrl = Control(protocol, self.task_vocabs.items)

            # TCM
            self.tcm = TCM(
                self.task_vocabs, beta, extensions=extensions, decay=decay)
            nengo.Connection(self.ctrl.output_stimulus, self.tcm.input)
            nengo.Connection(self.ctrl.output_lr, self.tcm.input_scale)

            # position counter
            self.pos = OneHotCounter(len(self.task_vocabs.positions))
            nengo.Connection(
                self.ctrl.output_no_pos_count, self.pos.rising_edge_gate,
                transform=-1.)
            nengo.Connection(nengo.Node(lambda t: t < 0.3), self.pos.input[0])

            # Short term memory
            self.ose = OSE(self.task_vocabs.items, gamma)
            nengo.Connection(self.ctrl.output_stimulus, self.ose.input_item)

            # primacy effect
            def primacy(t):
                epoch_t = t % protocol.epoch_duration
                if epoch_t < protocol.pres_phase_duration:
                    return -np.exp(-epoch_t)
                else:
                    return 0.
            nengo.Connection(
                nengo.Node(primacy), self.tcm.net_m_tf.compare.threshold)

            self.serial_recall_phase = nengo.Ensemble(50, 1)
            nengo.Connection(
                self.ctrl.output_serial_recall, self.serial_recall_phase)
            nengo.Connection(
                self.ctrl.output_pres_phase, self.serial_recall_phase,
                transform=-1.)
            nengo.Connection(
                self.ctrl.output_free_recall, self.serial_recall_phase.neurons,
                transform=-3. * np.ones(
                    (self.serial_recall_phase.n_neurons, 1)))

            # Use irrelevant position vector to bind distractors
            self.in_pos_gate = spa.State(self.task_vocabs.positions)

            nengo.Connection(self.pos.output, self.in_pos_gate.input,
                             transform=self.task_vocabs.positions.vectors.T)

            nengo.Connection(self.in_pos_gate.output, self.ose.input_pos)
            if 'no_pos_input' not in extensions:
                nengo.Connection(self.in_pos_gate.output, self.tcm.input_pos)
                inhibit_net(self.ctrl.output_no_learn, self.in_pos_gate, strength=10.)

            self.irrelevant_pos_gate = spa.State(self.task_vocabs.positions)
            self.irrelevant_pos = nengo.Node(
                self.task_vocabs.positions.create_pointer().v)
            nengo.Connection(self.irrelevant_pos,
                             self.irrelevant_pos_gate.input)
            nengo.Connection(
                self.irrelevant_pos_gate.output, self.ose.input_pos)

            with nengo.presets.ThresholdingEnsembles(0.):
                self.in_pos_gate_inhibit = nengo.Ensemble(25, 1)
            inhibit_net(self.in_pos_gate_inhibit, self.in_pos_gate)
            nengo.Connection(
                self.ctrl.output_no_learn, self.in_pos_gate_inhibit)
            nengo.Connection(
                self.ctrl.output_recall_phase, self.in_pos_gate_inhibit,
                transform=-1)
            inhibit_net(self.ctrl.output_learn, self.irrelevant_pos_gate)
            inhibit_net(
                self.ctrl.output_recall_phase, self.irrelevant_pos_gate)
            inhibit_net(self.ctrl.bias, self.irrelevant_pos_gate)
            if 'no_pos_input' not in extensions:
                nengo.Connection(self.irrelevant_pos_gate.output, self.tcm.input_pos)
                inhibit_net(self.ctrl.output_no_learn, self.irrelevant_pos_gate, strength=10.)

            # Reset of position
            # Happens only in serial recall and a certain fraction of free
            # recalls.
            with nengo.presets.ThresholdingEnsembles(0.):
                self.start_of_free_recall = nengo.Ensemble(50, 1)
                self.start_of_serial_recall = nengo.Ensemble(50, 1)
                self.start_of_pres_phase = nengo.Ensemble(50, 1)
            nengo.Connection(
                self.ctrl.output_recall_phase, self.start_of_free_recall,
                synapse=0.05, transform=-1)
            nengo.Connection(
                self.ctrl.output_recall_phase, self.start_of_free_recall,
                synapse=0.005)
            nengo.Connection(
                self.ctrl.output_recall_phase, self.start_of_serial_recall,
                synapse=0.05, transform=-1)
            nengo.Connection(
                self.ctrl.output_recall_phase, self.start_of_serial_recall,
                synapse=0.005)
            nengo.Connection(
                self.ctrl.output_pres_phase, self.start_of_pres_phase,
                synapse=0.05, transform=-1)
            nengo.Connection(
                self.ctrl.output_pres_phase, self.start_of_pres_phase,
                synapse=0.005)
            tr = -9 * np.ones((self.pos.input.size_in, 1))
            tr[0, 0] = 3.
            nengo.Connection(
                self.start_of_serial_recall, self.pos.input, transform=tr,
                synapse=0.1)
            if 'recognition' not in extensions:
                nengo.Connection(
                    self.start_of_serial_recall, self.tcm.input_pos,
                    transform=np.atleast_2d(
                        self.task_vocabs.positions.vectors[0]).T,
                    synapse=0.1)

            inhibit_net(self.start_of_free_recall, self.pos, strength=10.)

            nengo.Connection(
                self.start_of_pres_phase, self.pos.input, transform=tr,
                synapse=0.1)
            if 'recognition' not in extensions:
                nengo.Connection(
                    self.start_of_pres_phase, self.tcm.input_pos,
                    transform=np.atleast_2d(
                        self.task_vocabs.positions.vectors[0]).T,
                    synapse=0.1)

            # Certain fraction of recalls use ordinal strategy
            if np.random.rand() >= ordinal_prob:
                nengo.Connection(
                    self.ctrl.output_free_recall, self.start_of_serial_recall,
                    transform=-5.)
                nengo.Connection(
                    self.ctrl.output_serial_recall, self.start_of_free_recall,
                    transform=-5.)
            else:
                nengo.Connection(
                    self.ctrl.output_free_recall, self.start_of_free_recall,
                    transform=-5.)
                nengo.Connection(
                    self.ctrl.output_serial_recall, self.start_of_free_recall,
                    transform=-5.)

            # Determining update progress
            self.last_item = spa.State(self.task_vocabs.items, feedback=1.)
            self.sim_th = SimilarityThreshold(self.task_vocabs.items)
            nengo.Connection(
                self.ctrl.output_stimulus, self.last_item.input, transform=1.,
                synapse=0.1)
            nengo.Connection(self.ctrl.output_stimulus, self.sim_th.input_a)
            nengo.Connection(self.last_item.output, self.sim_th.input_b)

            if 'forward-assoc' in extensions:
                self.cc = spa.Bind(self.task_vocabs.items)
                nengo.Connection(
                    self.pos.output_prev, self.cc.input_b,
                    transform=self.task_vocabs.positions.vectors.T)
                nengo.Connection(
                    self.cc.output, self.tcm.forward_assoc.input_cue)

                self.stage_a = GatedMemory(self.task_vocabs.items)
                self.stage_b = GatedMemory(self.task_vocabs.items)
                nengo.Connection(self.ctrl.output_stimulus, self.stage_a.input)
                nengo.Connection(self.stage_a.output, self.stage_b.input)
                nengo.Connection(self.stage_b.output, self.cc.input_a)
                inhibit_net(self.ctrl.output_recall_phase, self.stage_a)
                inhibit_net(self.ctrl.output_recall_phase, self.stage_b)
                nengo.Connection(self.sim_th.output, self.stage_b.input_store)
                nengo.Connection(
                    nengo.Node(1.), self.stage_a.input_store, synapse=None)
                nengo.Connection(
                    self.sim_th.output, self.stage_a.input_store,
                    transform=-1.)

                self.sim_th2 = SimilarityThreshold(self.task_vocabs.items)
                nengo.Connection(self.stage_a.output, self.sim_th2.input_a)
                nengo.Connection(
                    self.ctrl.output_stimulus, self.sim_th2.input_b)
                nengo.Connection(
                    self.sim_th2.output, self.stage_a.input_store, synapse=0.1)

            with nengo.Config(nengo.Ensemble) as cfg:
                cfg[nengo.Ensemble].eval_points = nengo.dists.Uniform(0, 1)
                cfg[nengo.Ensemble].intercepts = nengo.dists.Uniform(0, 1)
                self.sim_th_pos = nengo.Ensemble(50, 1)
                self.sim_th_neg = nengo.Ensemble(50, 1)
            nengo.Connection(self.sim_th.output, self.sim_th_pos)
            nengo.Connection(self.sim_th.output, self.sim_th_neg)
            nengo.Connection(self.ctrl.output_pres_phase, self.sim_th_pos.neurons, transform=-3. * np.ones((self.sim_th_pos.n_neurons, 1)))
            nengo.Connection(self.ctrl.output_recall_phase, self.sim_th_neg.neurons, transform=-3. * np.ones((self.sim_th_neg.n_neurons, 1)))
            nengo.Connection(self.sim_th_pos, self.pos.input_inc)
            nengo.Connection(self.sim_th_neg, self.pos.input_inc, transform=-1)

            nengo.Connection(self.ctrl.output_pres_phase, self.tcm.input_update_context)
            nengo.Connection(
                self.sim_th_neg, self.tcm.input_update_context,
                transform=-1.)  # FIXME ?
            nengo.Connection(
                self.sim_th_pos, self.tcm.input_update_context,
                transform=1.)  # FIXME ?

            # nengo.Connection(
                # self.sim_th.output, self.pos.input_inc, transform=-1)
            nengo.Connection(self.sim_th.output, self.ose.input_store)

            nengo.Connection(self.bias, self.tcm.input_no_learn)
            nengo.Connection(
                self.sim_th.output, self.tcm.input_no_learn, transform=-1)
            nengo.Connection(
                self.ctrl.output_no_learn, self.tcm.input_no_learn,
                transform=2.)

            # Recall networks
            self.recall = NeuralAccumulatorDecisionProcess(
                self.task_vocabs.items.create_subset(protocol.get_all_items()),
                noise=recall_noise, min_evidence=min_evidence, n_inputs=2)
            self.recalled_gate = spa.State(self.task_vocabs.items)
            if 'recognition' not in extensions:
                nengo.Connection(self.recalled_gate.output, self.tcm.input)

            self.pos_recall = NeuralAccumulatorDecisionProcess(
                self.task_vocabs.positions, noise=recall_noise,
                min_evidence=min_evidence)

            self.tcm_recall_gate = spa.State(self.task_vocabs.items)
            if 'disable_ltm_recall' not in extensions:
                nengo.Connection(
                    self.tcm.output_recalled_item, self.tcm_recall_gate.input)
            inhibit_net(self.ctrl.output_pres_phase, self.tcm_recall_gate)

            inhibit_net(
                self.ctrl.output_serial_recall, self.recalled_gate, strength=6)
            nengo.Connection(self.recall.output, self.recalled_gate.input)
            for recall_net in (self.recall, self.pos_recall):
                nengo.Connection(
                    self.tcm_recall_gate.output, recall_net.input_list[0])

                inhibit_net(self.ctrl.output_pres_phase, recall_net.state)
                inhibit_net(
                    self.ctrl.output_pres_phase, recall_net.buf.mem,
                    strength=6)
                inhibit_net(self.ctrl.output_pres_phase, recall_net.inhibit)

            if 'forward-assoc' in extensions:
                nengo.Connection(self.recall.output, self.cc.input_a)

            nengo.Connection(
                self.recall.output, self.sim_th.input_a, transform=1.2)
            nengo.Connection(
                self.recall.output, self.last_item.input, transform=0.1,
                synapse=0.1)

            nengo.Connection(
                self.bias, self.recall.out_inhibit_gate.input_store)
            nengo.Connection(
                self.sim_th.output, self.recall.out_inhibit_gate.input_store,
                transform=-1)

            # on failed recall increment pos and update context
            nengo.Connection(
                self.recall.failed_recall_heaviside, self.pos.input_inc,
                transform=50., synapse=0.1)
            nengo.Connection(
                self.recall.failed_recall_heaviside,
                self.tcm.input_update_context, transform=20.)

            # Set position from recalled positions
            self.pos_gate = nengo.networks.EnsembleArray(
                30, len(self.task_vocabs.positions))
            nengo.Connection(
                self.pos_recall.buf.output, self.pos_gate.input,
                transform=1.3 * self.task_vocabs.positions.vectors)
            nengo.Connection(
                self.bias, self.pos_gate.input,
                transform=-np.ones((self.pos_gate.input.size_in, 1)))
            nengo.Connection(
                self.pos_gate.output, self.pos.input, transform=10.,
                synapse=0.1)
            self.invert = nengo.Ensemble(30, 1)
            nengo.Connection(self.bias, self.invert)
            nengo.Connection(
                self.pos_recall.buf.mem.state_ensembles.add_output(
                    'square', lambda x: x * x),
                self.invert,
                transform=-np.ones((1, self.task_vocabs.positions.dimensions)))
            inhibit_net(self.invert, self.pos_gate)
            inhibit_net(self.ctrl.output_serial_recall, self.pos_gate)
            inhibit_net(self.ctrl.output_serial_recall, self.pos_recall.buf)

            # Short term recall
            self.ose_recall_gate = spa.State(self.task_vocabs.items)
            if 'disable_stm_recall' not in extensions:
                nengo.Connection(
                    self.ose.output, self.ose_recall_gate.input, transform=0.5)
            nengo.Connection(
                self.ose_recall_gate.output, self.recall.input_list[1])
            self.ose_recall_threshold = nengo.Node(ose_thr)
            nengo.Connection(
                self.ose_recall_threshold, self.recall.inp_thrs[1].input,
                transform=-np.ones(
                    (self.recall.inp_thrs[1].input.size_in, 1)))
            inhibit_net(self.ctrl.output_pres_phase, self.ose_recall_gate)
            inhibit_net(self.start_of_serial_recall, self.ose_recall_gate)
            inhibit_net(self.start_of_serial_recall, self.tcm.current_ctx.old.mem,
                        synapse=0.1, strength=5)
            nengo.Connection(
                self.start_of_serial_recall, self.tcm.input_update_context,
                synapse=0.1, transform=5)

            self.output = self.recall.output
            self.output_pos = self.pos.output

        self.outputs = dict(
            default=(self.output, self.task_vocabs.items),
            output_pos=(self.output_pos, self.task_vocabs.positions))
コード例 #8
0
                D1 * (GET_V) +\
                D2 * (GET_ADD + SET_ADD) +\
                D3 * (GET_COM + SET_COM) + \
                D4 * (SET_M) \
            ',
                                       output_vocab=vocab)
    POS = WM(100, vocab)
    clean_POS = spa.WTAAssocMem(threshold=.2,
                                input_vocab=POS.vocab,
                                mapping=['D1', 'D2', 'D3', 'D4'],
                                n_neurons=50,
                                function=lambda x: x > 0)
    nengo.Connection(POS.output, clean_POS.input)
    INCREMENT = WM(100, vocab)

    PRIM = spa.Bind(neurons_per_dimension=200, vocab=vocab, unbind_right=True)
    GET_PRIM = spa.WTAAssocMem(threshold=.5,
                               input_vocab=PRIM.vocab,
                               mapping=['GET_V', 'GET_COM', 'GET_ADD'],
                               n_neurons=50,
                               function=lambda x: x > 0)
    SET_PRIM = spa.WTAAssocMem(threshold=.5,
                               input_vocab=PRIM.vocab,
                               mapping=['SET_COM', 'SET_ADD', 'SET_M'],
                               n_neurons=50,
                               function=lambda x: x > 0)
    PRIM >> GET_PRIM
    PRIM >> SET_PRIM

    input_INSTRUCTIONS >> PRIM.input_left
    spa.translate(clean_POS, vocab) >> PRIM.input_right
コード例 #9
0
with nengo.Network() as model:

    # utility_in = nengo.Node([0])
    # utility = spa.Scalar()
    # nengo.Connection(utility_in, utility.input)

    # tst = TwoStepsTrigger(vocab)

    # POS = SP_WM(50, vocab)

    INSTRUCTIONS = spa.Transcode(input_vocab=vocab, output_vocab=vocab)
    vocab.parse('D0*A + D1*B + D2*C') >> INSTRUCTIONS
    for i in range(n_digits):
        digit = vocab.parse('D' + str(i))
        digit * digit >> INSTRUCTIONS
    PRIM = spa.Bind(vocab=vocab, unbind_right=True)
    INSTRUCTIONS >> PRIM.input_left
    POS >> PRIM.input_right

    # AM = spa.WTAAssocMem(
    #     0,
    #     vocab,
    #     mapping=dict(list({'D'+str(i):'D'+str(i+1) for i in range(n_digits-1)}.items()) + list({'D'+str(n_digits-1):'D0'}.items())),
    #     function=lambda x: x>0
    # )
    # nengo.Connection(POS.output, AM.input)

    # ADD = SP_WM(50, vocab)
    # nengo.Connection(AM.output, ADD.input)
    # nengo.Connection(ADD.output, POS.input)
コード例 #10
0
    def construct_network(self):
        self.send_n_neurons_per_dim()
        s = spa.sym
        net = self.network

        # temporary parameters
        self.crosstalk = False
        self.crosstalk_lr = 5e-12

        with net:

            net.input_net = spa.Network(label='inputs', seed=self.seed)

            with net.input_net:
                net.input_net.RETINA_input = spa.Transcode(
                    self.experiment.RETINA_input,
                    input_vocab=self.vocabs['GW'],
                    output_vocab=self.vocabs['GW'])

            net.V = DirectProcessor(
                self.vocabs['GW'],
                self.vocabs['GW'],
                'V',
                receiver=False,  # V only sends info to GW
                seed=self.seed,
                prediction_out=self.crosstalk,
                n_neurons_per_dim=self.n_neurons_per_dim)
            nengo.Connection(net.input_net.RETINA_input.output,
                             net.V.input.input,
                             synapse=None)

            net.FIXATE_detector = nengo.Node(size_in=1,
                                             label='FIXATE detector')
            nengo.Connection(
                net.V.input.output,
                net.FIXATE_detector,
                transform=net.V.output_vocab.parse('FIXATE').v[None, :],
                synapse=.05
            )  # some synaptic delay is necessary to ensure the stimulus has time to enter GW
            net.declare_output(net.FIXATE_detector, None)

            net.M = DirectProcessor(
                self.vocabs['GW'],
                self.vocabs['GW'],
                'M',
                sender=False,  # M only receives info from GW
                seed=self.seed,
                n_neurons_per_dim=self.n_neurons_per_dim)

            net.BTN = nengo.Node(Button(
                SP_vectors=[
                    self.vocabs['GW'].parse('LESS').v,
                    self.vocabs['GW'].parse('MORE').v
                ],
                trial_length=self.experiment.trial_length,
                wait_length=self.experiment.t_start),
                                 label='button',
                                 size_in=self.vocabs['GW'].dimensions)
            nengo.Connection(
                net.M.output.output, net.BTN
            )  # Connect output of M to BTN that records behavioral response

            net.ADD = ADDProcessor(self.vocabs['GW'],
                                   'ADD',
                                   self.n_neurons_per_dim,
                                   self.rng,
                                   self.BG_bias,
                                   self.BG_thr,
                                   feedback=self.proc_feedback,
                                   seed=self.seed)
            with net.input_net:
                net.input_net.ADDEND = spa.Transcode(
                    self.experiment.ADDEND_input,
                    input_vocab=self.vocabs['GW'],
                    output_vocab=self.vocabs['GW'],
                    label='ADDEND')
            nengo.Connection(net.input_net.ADDEND.output,
                             net.ADD.bind.input_right,
                             synapse=None)

            if self.compare_tau != 0:
                net.COM = CompareProcessor(
                    self.vocabs['GW'],
                    self.vocabs['GW'],
                    'COM',
                    self.experiment.trial_length,
                    self.experiment.t_start if self.integrator_reset else 0,
                    self.n_neurons_per_dim,
                    self.rng,
                    self.n_samples,
                    tau=self.compare_tau,
                    seed=self.seed,
                    prediction_in=self.crosstalk)
            else:
                net.COM = AMProcessor(self.vocabs['GW'],
                                      self.vocabs['GW'],
                                      'COM', {
                                          'D2': 'LESS',
                                          'D4': 'LESS',
                                          'D6': 'MORE',
                                          'D8': 'MORE'
                                      },
                                      n_neurons_per_dim=self.n_neurons_per_dim,
                                      seed=self.seed,
                                      prediction_in=self.crosstalk)

            self.processors = [net.V, net.COM, net.M, net.ADD]

            if self.crosstalk:
                net.crosstalk = Prediction(net.V,
                                           net.COM,
                                           rate=self.crosstalk_lr)

            net.GW = GlobalWorkspace(self.vocabs['GW'],
                                     mappings={
                                         net.V:
                                         ['D2', 'D4', 'D6', 'D8', 'FIXATE'],
                                         net.ADD: ['D2', 'D4', 'D6', 'D8'],
                                         net.COM: ['MORE', 'LESS'],
                                     },
                                     n_neurons=self.n_neurons_per_dim['AM'],
                                     seed=self.seed)
            for detector in net.GW.detectors.values():
                net.declare_output(detector, None)

            net.POS = WM(200, self.vocabs['PRIM'])
            net.clean_POS = spa.WTAAssocMem(
                threshold=0,
                input_vocab=net.POS.vocab,
                mapping=['D1', 'D2', 'D3', 'D4'],
                n_neurons=self.n_neurons_per_dim['AM'],
                function=lambda x: x > 0)
            nengo.Connection(net.POS.output, net.clean_POS.input)

            net.INCREMENT = WM(200, self.vocabs['PRIM'])

            nengo.Connection(
                net.clean_POS.output,
                net.INCREMENT.input,
                transform=net.POS.vocab.parse('D1').get_binding_matrix())
            nengo.Connection(net.INCREMENT.output, net.POS.input)

            with net.input_net:
                net.input_net.INSTRUCTIONS = spa.Transcode(
                    self.experiment.INSTRUCTIONS_input,
                    input_vocab=self.vocabs['PRIM'],
                    output_vocab=self.vocabs['PRIM'],
                    label='INSTRUCTIONS')

            net.PRIM = spa.Bind(
                neurons_per_dimension=self.n_neurons_per_dim['Bind'],
                vocab=self.vocabs['PRIM'],
                unbind_right=True)

            net.input_net.INSTRUCTIONS >> net.PRIM.input_left
            net.clean_POS >> net.PRIM.input_right

            # GET selector
            with spa.Network(label='GET selector',
                             seed=self.seed) as net.GET_selector:
                net.GET_selector.labels = []
                with spa.ActionSelection() as net.GET_selector.AS:

                    net.GET_selector.labels.append("GET V (FIXATE)")
                    spa.ifmax(net.GET_selector.labels[-1],
                              self.BG_bias + net.FIXATE_detector,
                              net.V.preconscious >> net.GW.AMs[net.V].input,
                              s.D1 >> net.POS.input, 1 >> net.INCREMENT.reset)

                    net.GET_selector.labels.append("GET ADD")
                    spa.ifmax(
                        net.GET_selector.labels[-1],
                        self.BG_bias + spa.dot(net.PRIM, s.GET_ADD) *
                        (1 - net.GW.detectors[net.ADD]),
                        net.ADD.preconscious >> net.GW.AMs[net.ADD].input,
                        1 >> net.POS.gate,
                    )

                    net.GET_selector.labels.append("GET COM")
                    spa.ifmax(
                        net.GET_selector.labels[-1],
                        self.BG_bias + spa.dot(net.PRIM, s.GET_COM) *
                        (1 - net.GW.detectors[net.COM]),
                        net.COM.preconscious >> net.GW.AMs[net.COM].input,
                        1 >> net.POS.gate,
                    )

                    net.GET_selector.labels.append("Thresholder")
                    spa.ifmax(
                        net.GET_selector.labels[-1],
                        self.BG_bias + self.BG_thr,
                        1 >> net.INCREMENT.gate,
                    )

            # SET selector
            with spa.Network(label='SET selector',
                             seed=self.seed) as net.SET_selector:
                net.SET_selector.labels = []
                with spa.ActionSelection() as net.SET_selector.AS:

                    net.SET_selector.labels.append("SET ADD")
                    spa.ifmax(
                        net.SET_selector.labels[-1],
                        self.BG_bias + spa.dot(net.PRIM, s.SET_ADD) *
                        (1 - net.GW.detectors[net.ADD]),
                        net.GW.AMs[net.COM] >> net.ADD.broadcast,
                        net.GW.AMs[net.V] >> net.ADD.broadcast,
                    )

                    net.SET_selector.labels.append("SET COM")
                    spa.ifmax(
                        net.SET_selector.labels[-1],
                        self.BG_bias + spa.dot(net.PRIM, s.SET_COM) *
                        (1 - net.GW.detectors[net.COM]),
                        net.GW.AMs[net.ADD] >> net.COM.broadcast,
                        net.GW.AMs[net.V] >> net.COM.broadcast,
                    )

                    net.SET_selector.labels.append("SET M")
                    spa.ifmax(
                        net.SET_selector.labels[-1],
                        self.BG_bias + spa.dot(net.PRIM, s.SET_M),
                        net.GW.AMs[net.COM] >> net.M.broadcast,
                        net.GW.AMs[net.V] >> net.M.broadcast,
                        net.GW.AMs[net.ADD] >> net.M.broadcast,
                    )

                    net.SET_selector.labels.append("Thresholder")
                    spa.ifmax(net.SET_selector.labels[-1], self.BG_bias +
                              self.BG_thr)  # Threshold for action