def test_vocab_config(): with spa.Network() as model: with spa.Network() as model.shared_vocabs: pass with spa.Network(vocabs=VocabularyMap()) as model.non_shared_vocabs: pass assert model.shared_vocabs.vocabs is model.vocabs assert model.non_shared_vocabs.vocabs is not model.vocabs
def test_action_selection_keys_corner_cases(): with spa.Network(): with ActionSelection() as action_sel: pass assert list(action_sel.keys()) == [] with spa.Network(): with ActionSelection() as action_sel: spa.ifmax(0.0) assert list(action_sel.keys()) == [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
def test_instance_config(): with spa.Network() as net: ens = nengo.Ensemble(10, 1) net.config[nengo.Ensemble].set_param( "param", nengo.params.BoolParam("param", default=False) ) net.config[ens].param = True
def test_action_selection_enforces_connections_to_be_part_of_action(): with spa.Network(): state1 = spa.State(16) state2 = spa.State(16) with pytest.raises(SpaActionSelectionError): with ActionSelection(): state1 >> state2
def test_binary_operation_on_modules_with_fixed_pointer( Simulator, algebra, op, order, rng): vocab = spa.Vocabulary(16, pointer_gen=rng, algebra=algebra) vocab.populate("A; B") b = SemanticPointer(vocab["B"].v) # noqa: F841 with spa.Network() as model: a = spa.Transcode("A", output_vocab=vocab) # noqa: F841 if order == "AB": x = eval("a" + op + "b") elif order == "BA": x = eval("b" + op + "a") else: raise ValueError("Invalid order argument.") p = nengo.Probe(x.construct(), synapse=0.03) with Simulator(model) as sim: sim.run(0.3) assert_sp_close( sim.trange(), sim.data[p], vocab.parse(order[0] + op + order[1]), skip=0.2, atol=0.3, )
def test_missing_pointer(): vocab = spa.Vocabulary(16) with spa.Network(): a = spa.State(vocab) assert a with pytest.raises(SpaParseError): spa.sym.A >> a
def test_missing_sink(sink): d = 16 with spa.Network(): a = spa.State(d) assert a with pytest.raises(NameError): eval('a >> %s' % sink)
def test_constructed_objects_are_accessible(): with spa.Network() as model: model.config[spa.State].vocab = 16 model.state1 = spa.State() model.state2 = spa.State() model.state3 = spa.State() with spa.ActionSelection() as actions: spa.ifmax(spa.dot(model.state1, spa.sym.A), model.state3 >> model.state2) spa.ifmax(0.5, spa.sym.B >> model.state2) bg = actions.bg thalamus = actions.thalamus assert isinstance(thalamus.gates[0], nengo.Ensemble) assert isinstance(thalamus.gate_in_connections[0], nengo.Connection) assert isinstance(thalamus.gate_out_connections[0], nengo.Connection) assert isinstance(thalamus.channels[0], spa.State) assert isinstance(thalamus.channel_out_connections[0], nengo.Connection) assert isinstance(thalamus.fixed_connections[1], nengo.Connection) assert thalamus.bg_connection.pre is bg.output assert thalamus.bg_connection.post is thalamus.input
def test_memory_run(Simulator, seed, plt): with spa.Network(seed=seed) as model: memory = spa.State(vocab=32, feedback=1.0, feedback_synapse=0.01) def state_input(t): if 0 <= t < 0.05: return "A" else: return "0" state_input = spa.Transcode(state_input, output_vocab=32) state_input >> memory with model: p = nengo.Probe(memory.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.5) t = sim.trange() similarity = np.dot(sim.data[p], memory.vocab.vectors.T) plt.plot(t, similarity) plt.ylabel("Similarity to 'A'") plt.xlabel("Time (s)") # value should peak above 1.0, then decay down to near 1.0 assert np.mean(similarity[(t > 0.05) & (t < 0.1)]) > 1.0 assert np.mean(similarity[(t > 0.2) & (t < 0.3)]) > 0.7 assert np.mean(similarity[t > 0.49]) > 0.5
def test_no_feedback_run(Simulator, plt, seed): with spa.Network(seed=seed) as model: state = spa.State(vocab=32, feedback=0.0) def state_input(t): if 0 <= t < 0.3: return "A" elif 0.2 <= t < 0.6: return "B" else: return "0" state_input = spa.Transcode(state_input, output_vocab=32) state_input >> state with model: p = nengo.Probe(state.output, synapse=0.05) with Simulator(model) as sim: sim.run(0.8) data = np.dot(sim.data[p], state.vocab.vectors.T) plt.plot(sim.trange(), data) assert data[299, 0] > 0.9 assert data[299, 1] < 0.2 assert data[599, 0] < 0.2 assert data[599, 1] > 0.9 assert data[799, 0] < 0.2 assert data[799, 1] < 0.2
def test_encode_with_input(Simulator, seed): with spa.Network(seed=seed) as model: buffer = spa.State(vocab=16) def stimulus(t, x): return x[0] * buffer.vocab.parse('A') ctrl = nengo.Node(lambda t: t > 0.2) encode = spa.Transcode(stimulus, output_vocab=16, size_in=1) nengo.Connection(ctrl, encode.input) encode >> buffer p = nengo.Probe(buffer.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.4) vocab = buffer.vocab assert_sp_close(sim.trange(), sim.data[p], vocab.parse('0'), duration=0.2) assert_sp_close(sim.trange(), sim.data[p], vocab.parse('A'), skip=.38, duration=0.02)
def test_unbind(Simulator, side, seed): rng = np.random.RandomState(seed) vocab = spa.Vocabulary(36, pointer_gen=rng, algebra=VtbAlgebra()) vocab.populate("A; B") with spa.Network(seed=seed) as model: vtb = VTB(100, 36, unbind_left=(side == "left"), unbind_right=(side == "right")) if side == "left": left = nengo.Node(vocab["B"].v) right = nengo.Node(vocab.parse("B*A").v) elif side == "right": left = nengo.Node(vocab.parse("A*B").v) right = nengo.Node(vocab["B"].v) else: raise ValueError("Invalid 'side' value.") nengo.Connection(left, vtb.input_left) nengo.Connection(right, vtb.input_right) p = nengo.Probe(vtb.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)
def test_direct(Simulator, seed): with spa.Network(seed=seed) as model: model.buffer1 = spa.State(vocab=16) model.buffer1.vocab.populate('A; B; C') model.buffer2 = spa.State(vocab=32) model.buffer2.vocab.populate('A; B; C') spa.sym.A >> model.buffer1 spa.sym.B >> model.buffer2 spa.sym.C >> model.buffer1 spa.sym.C >> model.buffer2 with model: p1 = nengo.Probe(model.buffer1.output, synapse=0.03) p2 = nengo.Probe(model.buffer2.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.2) match1 = np.dot(sim.data[p1], model.buffer1.vocab.parse('A+C').v) match2 = np.dot(sim.data[p2], model.buffer2.vocab.parse('B+C').v) # both values should be near 1.0 since buffer1 is driven to both A and C # and buffer2 is driven to both B and C. assert match1[199] > 0.75 assert match2[199] > 0.75
def __init__(self, vocabs, experiment, n_samples, integrator_reset, proc_feedback, compare_tau, BG_thr, BG_bias, n_neurons_per_dim, seed=None, plot=False): self.vocabs = vocabs self.experiment = experiment self.n_samples = n_samples self.integrator_reset = integrator_reset self.proc_feedback = proc_feedback self.compare_tau = compare_tau self.BG_thr = BG_thr self.BG_bias = BG_bias self.n_neurons_per_dim = n_neurons_per_dim self.plot = plot self.set_seed(seed) self.network = spa.Network(seed=self.seed) self.construct_network()
def test_errors(): # motor does not exist with pytest.raises(AttributeError): with spa.Network() as model: model.vision = spa.State(vocab=16) with spa.ActionSelection: spa.ifmax(0.5, spa.sym.A >> model.motor)
def test_memory_run_decay(Simulator, plt, seed): with spa.Network(seed=seed) as model: memory = spa.State(vocab=32, feedback=(1.0 - 0.01 / 0.05), feedback_synapse=0.01) def state_input(t): if 0 <= t < 0.05: return "A" else: return "0" state_input = spa.Transcode(state_input, output_vocab=32) state_input >> memory with model: p = nengo.Probe(memory.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.3) data = np.dot(sim.data[p], memory.vocab.vectors.T) t = sim.trange() plt.plot(t, data) assert data[t == 0.05, 0] > 1.0 assert data[t == 0.299, 0] < 0.4
def test_routing(Simulator, seed, plt): model = spa.Network(seed=seed) model.config[spa.State].vocab = 3 model.config[spa.State].subdimensions = 3 with model: model.ctrl = spa.State(16, subdimensions=16, label='ctrl') def input_func(t): if t < 0.2: return 'A' elif t < 0.4: return 'B' else: return 'C' model.input = spa.Transcode(input_func, output_vocab=16) model.buff1 = spa.State(label='buff1') model.buff2 = spa.State(label='buff2') model.buff3 = spa.State(label='buff3') node1 = nengo.Node([0, 1, 0]) node2 = nengo.Node([0, 0, 1]) nengo.Connection(node1, model.buff1.input) nengo.Connection(node2, model.buff2.input) model.input >> model.ctrl with spa.ActionSelection(): spa.ifmax(spa.dot(model.ctrl, spa.sym.A), model.buff1 >> model.buff3) spa.ifmax(spa.dot(model.ctrl, spa.sym.B), model.buff2 >> model.buff3) spa.ifmax(spa.dot(model.ctrl, spa.sym.C), model.buff1 * model.buff2 >> model.buff3) buff3_probe = nengo.Probe(model.buff3.output, synapse=0.03) with Simulator(model) as sim: sim.run(0.6) data = sim.data[buff3_probe] plt.plot(sim.trange(), data) valueA = np.mean(data[150:200], axis=0) # should be [0, 1, 0] valueB = np.mean(data[350:400], axis=0) # should be [0, 0, 1] valueC = np.mean(data[550:600], axis=0) # should be [1, 0, 0] assert valueA[0] < 0.2 assert valueA[1] > 0.7 assert valueA[2] < 0.2 assert valueB[0] < 0.2 assert valueB[1] < 0.2 assert valueB[2] > 0.7 assert valueC[0] > 0.7 assert valueC[1] < 0.2 assert valueC[2] < 0.2
def test_run(Simulator, algebra, seed): rng = np.random.RandomState(seed) vocab = spa.Vocabulary(32, pointer_gen=rng, algebra=algebra) vocab.populate('A; B') with spa.Network(seed=seed, vocabs=VocabularyMap([vocab])) as model: model.superpos = spa.Superposition(2, vocab=32) def inputA(t): if 0 <= t < 0.1: return 'A' else: return 'B' model.input = spa.Transcode(inputA, output_vocab=vocab) model.input >> model.superpos.inputs[0] spa.sym.A >> model.superpos.inputs[1] with model: p = nengo.Probe(model.superpos.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.1 error = rmse(vocab.parse("(A+A).normalized()").v, sim.data[p][100]) assert error < 0.2
def test_invalid_sink(sink): d = 16 with spa.Network(): a = spa.State(d) assert a with pytest.raises((SyntaxError, SpaTypeError)): eval('a >> {}'.format(sink))
def test_am_basic(Simulator, plt, seed, rng): """Basic associative memory test.""" d = 64 vocab = Vocabulary(d, pointer_gen=rng) vocab.populate("A; B; C; D") with spa.Network("model", seed=seed) as m: m.am = ThresholdingAssocMem( threshold=0.3, input_vocab=vocab, mapping=vocab.keys(), function=filtered_step_fn, ) spa.sym.A >> m.am in_p = nengo.Probe(m.am.input) out_p = nengo.Probe(m.am.output, synapse=0.03) with Simulator(m) as sim: sim.run(0.2) t = sim.trange() plt.subplot(3, 1, 1) plt.plot(t, similarity(sim.data[in_p], vocab)) plt.ylabel("Input") plt.ylim(top=1.1) plt.subplot(3, 1, 2) plt.plot(t, similarity(sim.data[out_p], vocab)) plt.plot(t[t > 0.15], np.ones(t.shape)[t > 0.15] * 0.95, c="g", lw=2) plt.ylabel("Output") assert_sp_close(t, sim.data[in_p], vocab["A"], skip=0.15, atol=0.05) assert_sp_close(t, sim.data[out_p], vocab["A"], skip=0.15)
def test_missing_source(): d = 16 with spa.Network(): a = spa.State(d) assert a with pytest.raises(NameError): b >> a # noqa: F821
def test_invalid_mapping_string(): with spa.Network(): with pytest.raises(ValidationError): ThresholdingAssocMem(threshold=0.3, input_vocab=16, output_vocab=32, mapping="invalid")
def model(self): with spa.Network() as model: model.state_a = spa.State(16) model.state_b = spa.State(32) model.state_c = spa.State(32) model.scalar = spa.Scalar() return model
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)
def model(self, p): self.proto = PROTOCOLS[p.protocol] self.stim_provider = StimulusProvider(self.proto, p.distractor_rate, p.recall_duration) self.vocabs = Vocabularies(self.stim_provider, p.item_d, p.context_d, self.proto.n_items + 3, np.random.RandomState(p.seed + 1)) with spa.Network(seed=p.seed) as model: model.cue = CUE(self.stim_provider, self.vocabs, p.beta, p.gamma, p.ose_thr, p.ordinal_prob, p.noise, p.min_evidence) self.p_recalls = nengo.Probe(model.cue.output, synapse=0.01) self.p_pos = nengo.Probe(model.cue.output_pos, synapse=0.01) self.probes = { 'ctx': nengo.Probe(model.cue.tcm.current_ctx.current.mem.output, synapse=0.01), 'ctx_spikes': nengo.Probe( model.cue.tcm.current_ctx.current.mem.state_ensembles. ensembles[-1].neurons, 'spikes'), } return model
def test_additive_op_fixed_scalar_and_pointer_symbol(op, rng): vocab = spa.Vocabulary(16, pointer_gen=rng) vocab.populate("A") with spa.Network(): with pytest.raises(TypeError): eval("2" + op + "PointerSymbol('A')")
def test_nondefault_routing(Simulator, seed): m = spa.Network(seed=seed) m.config[spa.State].vocab = 3 m.config[spa.State].subdimensions = 3 with m: m.ctrl = spa.State(16, subdimensions=16, label="ctrl") def input_func(t): if t < 0.2: return "A" elif t < 0.4: return "B" else: return "C" m.input = spa.Transcode(input_func, output_vocab=16) m.buff1 = spa.State(label="buff1") m.buff2 = spa.State(label="buff2") m.cmp = spa.Compare(3) node1 = nengo.Node([0, 1, 0]) node2 = nengo.Node([0, 0, 1]) nengo.Connection(node1, m.buff1.input) nengo.Connection(node2, m.buff2.input) m.input >> m.ctrl with spa.ActionSelection(): spa.ifmax( spa.dot(m.ctrl, spa.sym.A), m.buff1 >> m.cmp.input_a, m.buff1 >> m.cmp.input_b, ) spa.ifmax( spa.dot(m.ctrl, spa.sym.B), m.buff1 >> m.cmp.input_a, m.buff2 >> m.cmp.input_b, ) spa.ifmax( spa.dot(m.ctrl, spa.sym.C), m.buff2 >> m.cmp.input_a, m.buff2 >> m.cmp.input_b, ) compare_probe = nengo.Probe(m.cmp.output, synapse=0.03) with Simulator(m) as sim: sim.run(0.6) similarity = sim.data[compare_probe] valueA = np.mean(similarity[150:200], axis=0) # should be [1] valueB = np.mean(similarity[350:400], axis=0) # should be [0] valueC = np.mean(similarity[550:600], axis=0) # should be [1] assert valueA > 0.6 assert valueB < 0.3 assert valueC > 0.6
def test_multiply_fixed_scalar_and_pointer_symbol(rng): vocab = spa.Vocabulary(16, pointer_gen=rng) vocab.populate("A") with spa.Network(): x = 2 * PointerSymbol("A", TVocabulary(vocab)) node = x.construct() assert_equal(node.output, vocab.parse("2 * A").v)
def test_unary_operation_on_pointer_symbol(op, rng): vocab = spa.Vocabulary(16, pointer_gen=rng) vocab.populate("A") with spa.Network(): x = eval(op + "PointerSymbol('A', TVocabulary(vocab))") node = x.construct() assert_equal(node.output, vocab.parse(op + "A").v)