def test_spa_get(): D = 16 model = spa.SPA() with model: model.buf1 = spa.State(D) model.buf2 = spa.State(D) model.compare = spa.Compare(D) assert model.get_module('buf1') is model.buf1 assert model.get_module('buf1_default') is model.buf1 assert model.get_module('buf2') is model.buf2 assert model.get_module_input('buf1')[0] is model.buf1.input assert model.get_module_output('buf1')[0] is model.buf1.output assert model.get_module_input('compare_A')[0] is model.compare.inputA assert model.get_module_input('compare_B')[0] is model.compare.inputB with pytest.raises(SpaModuleError): model.get_module('dummy') with pytest.raises(SpaModuleError): model.get_module_input('dummy') with pytest.raises(SpaModuleError): model.get_module_output('dummy') with pytest.raises(SpaModuleError): model.get_module_input('buf1_A') with pytest.raises(SpaModuleError): model.get_module_input('compare')
def test_spa_get(): D = 16 model = spa.SPA() with model: model.buf1 = spa.State(D) model.buf2 = spa.State(D) model.compare = spa.Compare(D) assert model.get_module("buf1") is model.buf1 assert model.get_module("buf1_default") is model.buf1 assert model.get_module("buf2") is model.buf2 assert model.get_module_input("buf1")[0] is model.buf1.input assert model.get_module_output("buf1")[0] is model.buf1.output assert model.get_module_input("compare_A")[0] is model.compare.inputA assert model.get_module_input("compare_B")[0] is model.compare.inputB with pytest.raises(SpaModuleError): model.get_module("dummy") with pytest.raises(SpaModuleError): model.get_module_input("dummy") with pytest.raises(SpaModuleError): model.get_module_output("dummy") with pytest.raises(SpaModuleError): model.get_module_input("buf1_A") with pytest.raises(SpaModuleError): model.get_module_input("compare")
def test_output_detect(): model = spa.SPA() with model: # Find the output for ens ens = nengo.Ensemble(10, 2) val = Value(ens) assert val.n_lines == 2 assert val.output == ens # Find output for node node = nengo.Node([0, 0, 0]) val = Value(node) assert val.n_lines == 3 assert val.output == node # Find output for network ea = nengo.networks.EnsembleArray(10, 4) val = Value(ea) assert val.n_lines == 4 assert val.output == ea.output # Find output for SPA module model.comp = spa.Compare(4) val = Value(model.comp) assert val.n_lines == 1 assert val.output == model.comp.output
def __init__(self): self.compare = spa.Compare(dimensions=16) def inputA(t): if 0 <= t < 0.1: return 'A' else: return 'B' self.input = spa.Input(compare_A=inputA, compare_B='A')
def test_applicable_targets(): # Only return non-scalar targets model = spa.SPA() with model: model.comp = spa.Compare(4) assert SpaPlot.applicable_targets(model.comp) == [] model.state = spa.State(4) res = SpaPlot.applicable_targets(model.state) assert res == list(model.state.outputs.keys())
def test_basic(): with spa.SPA() as model: model.compare = spa.Compare(dimensions=16) inputA = model.get_module_input('compare_A') inputB = model.get_module_input('compare_B') output = model.get_module_output('compare') assert inputA[0] is model.compare.inputA assert inputB[0] is model.compare.inputB assert output[0] is model.compare.output assert inputA[1] is inputB[1] assert inputA[1] is output[1] assert inputA[1].dimensions == 16
def test_nondefault_routing(Simulator, seed, plt): D = 3 model = spa.SPA(seed=seed) with model: model.ctrl = spa.Buffer(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.Input(ctrl=input_func) model.buff1 = spa.Buffer(D, label='buff1') model.buff2 = spa.Buffer(D, label='buff2') model.cmp = spa.Compare(D) node1 = nengo.Node([0, 1, 0]) node2 = nengo.Node([0, 0, 1]) nengo.Connection(node1, model.buff1.state.input) nengo.Connection(node2, model.buff2.state.input) actions = spa.Actions('dot(ctrl, A) --> cmp_A=buff1, cmp_B=buff1', 'dot(ctrl, B) --> cmp_A=buff1, cmp_B=buff2', 'dot(ctrl, C) --> cmp_A=buff2, cmp_B=buff2', ) model.bg = spa.BasalGanglia(actions) model.thal = spa.Thalamus(model.bg) compare_probe = nengo.Probe(model.cmp.output, synapse=0.03) sim = Simulator(model) sim.run(0.6) vocab = model.get_output_vocab('cmp') data = sim.data[compare_probe] similarity = np.dot(data, vocab.parse('YES').v) 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_nondefault_routing(Simulator, seed): D = 3 model = spa.SPA(seed=seed) with model: model.ctrl = spa.Buffer(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.Input(ctrl=input_func) model.buff1 = spa.Buffer(D, label="buff1") model.buff2 = spa.Buffer(D, label="buff2") model.cmp = spa.Compare(D) node1 = nengo.Node([0, 1, 0]) node2 = nengo.Node([0, 0, 1]) nengo.Connection(node1, model.buff1.state.input) nengo.Connection(node2, model.buff2.state.input) actions = spa.Actions( "dot(ctrl, A) --> cmp_A=buff1, cmp_B=buff1", "dot(ctrl, B) --> cmp_A=buff1, cmp_B=buff2", "dot(ctrl, C) --> cmp_A=buff2, cmp_B=buff2", ) model.bg = spa.BasalGanglia(actions) model.thal = spa.Thalamus(model.bg) compare_probe = nengo.Probe(model.cmp.output, synapse=0.03) with Simulator(model) 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_basic(): with spa.SPA() as model: model.compare = spa.Compare(dimensions=16) inputA = model.get_module_input('compare_A') inputB = model.get_module_input('compare_B') output = model.get_module_output('compare') # all nodes should be acquired correctly assert inputA[0] is model.compare.inputA assert inputB[0] is model.compare.inputB assert output[0] is model.compare.output # all inputs should share the same vocab assert inputA[1] is inputB[1] assert inputA[1].dimensions == 16 # output should have no vocab assert output[1] is None
def test_run(Simulator, seed): with spa.SPA(seed=seed) as model: model.compare = spa.Compare(dimensions=16) def inputA(t): if 0 <= t < 0.1: return "A" else: return "B" model.input = spa.Input(compare_A=inputA, compare_B="A") compare, vocab = model.get_module_output("compare") with model: p = nengo.Probe(compare, "output", synapse=0.03) with Simulator(model) as sim: sim.run(0.2) assert sim.data[p][100] > 0.8 assert sim.data[p][199] < 0.2
def test_run(Simulator, seed): with spa.SPA(seed=seed) as model: model.compare = spa.Compare(dimensions=16) def inputA(t): if 0 <= t < 0.1: return 'A' else: return 'B' model.input = spa.Input(compare_A=inputA, compare_B='A') compare, vocab = model.get_module_output('compare') with model: p = nengo.Probe(compare, 'output', synapse=0.03) sim = Simulator(model) sim.run(0.2) assert sim.data[p][100] > 0.8 assert sim.data[p][199] < 0.2
compare_to_result_strength = 0.12966085928477078 ### MODEL ### model = spa.SPA(label='MAIN') with model: model.vision_system = v.make_vision_system( image_list, output_list, n_neurons=1000, AIT_V1_strength=0.06848695023305285, V1_r_transform=0.11090645719111913, AIT_r_transform=0.8079719992231219) model.concept = spa.State(D, vocab=vis_vocab) nengo.Connection(model.vision_system.AIT, model.concept.input) model.compare = spa.Compare(D) model.wm = spa.State(D, vocab=vis_vocab) model.result = spa.State(D, feedback=result_feedback) nengo.Connection(model.concept.output, model.compare.inputA, synapse=0.01) nengo.Connection(model.wm.output, model.compare.inputB) vocab = model.get_input_vocab('result') #I like this function so I'm keeping it here. I think it is very beautiful. #def conn_func(vocab, things_to_add): # for i in range(len(things_to_add)): # new = vocab.parse(things_to_add[i]).v # transform = 0.1*np.array([new]).T # return 0.4*transform
nengo.Connection(model.correct.output, model.correct.input, transform=1, synapse=.1)# nengo.Connection(model.in_layer.output, model.in_layer.input, transform=1, synapse=.1)# #switch to accumulate model.learn_state = spa.State(Dlow,vocab=vocab_reset) model.do_learn = spa.AssociativeMemory(vocab_reset, threshold=.1,default_output_key='CLEAR', wta_output=True) #removed default_output_key #nengo.Connection(model.do_learn.output, model.do_learn.input) nengo.Connection(model.learn_state.output,model.do_learn.input) nengo.Connection(model.do_learn.am.ensembles[-1], model.mem.mem.stop_pes, transform=-1, synapse=None) ### declarative retrieval from comparison input and output--------------- d_comp = D model.dm_compare = spa.Compare(d_comp,neurons_per_multiply=150,input_magnitude=.8) #d_comp.neuronsmay be reduced, e.g 150 direct_compare = True #keep that at true for now if direct_compare: for ens in model.dm_compare.all_ensembles: ens.neuron_type = nengo.Direct() nengo.Connection(model.mem.input[0:d_comp],model.dm_compare.inputA) nengo.Connection(model.mem.output[0:d_comp],model.dm_compare.inputB) #output ensemble of comparison model.dm_output_ens = nengo.Ensemble(n_neurons=1000,dimensions=1) nengo.Connection(model.dm_compare.output,model.dm_output_ens, synapse=None,transform=D/d_comp) #feedback (maybe not necessary, might make it more stable --> maybe remove) nengo.Connection(model.dm_output_ens, model.dm_output_ens, transform=.7, synapse=.1) #.8, .05
nengo.Connection(stim_target, model.target.input, synapse=None) stim_choice_a = nengo.Node(stim.choice_a) model.choice_a = spa.State(D, vocab=stim.vocab) nengo.Connection(stim_choice_a, model.choice_a.input, synapse=None) stim_choice_b = nengo.Node(stim.choice_b) model.choice_b = spa.State(D, vocab=stim.vocab) nengo.Connection(stim_choice_b, model.choice_b.input, synapse=None) # memory model.memory = spa.State(D, vocab=stim.vocab, feedback=1) nengo.Connection(model.target.output, model.memory.input) # comparison systems model.compare_a = spa.Compare(D) nengo.Connection(model.memory.output, model.compare_a.inputA) nengo.Connection(model.choice_a.output, model.compare_a.inputB) model.compare_b = spa.Compare(D) nengo.Connection(model.memory.output, model.compare_b.inputA) nengo.Connection(model.choice_b.output, model.compare_b.inputB) # accumulator to produce output accumulator = nengo.Ensemble(n_neurons=200, dimensions=1) nengo.Connection(accumulator, accumulator, synapse=0.1) nengo.Connection(model.compare_a.output, accumulator, transform=-acc_scale) nengo.Connection(model.compare_b.output, accumulator, transform=acc_scale) # reset the accumulator between trials stim_reset = nengo.Node(stim.reset)
def model(self, p): vis_items = ['FATIGUE', 'WHISKEY'] vis_vocab = spa.Vocabulary(p.D) self.vis_items = vis_items self.vis_vocab = vis_vocab result_vocab_items = ['SAME'] input_items = ['PUSH'] action_items = ['F1'] self.result_vocab_items = result_vocab_items self.input_items = input_items self.action_items = action_items ##### Vision and motor system ######### import vision_system as v import motor_system as m reload(v) reload(m) directory = '/home/stacy/github/visual-categorization/assoc_recog_s/images/' image_list = v.load_images(directory, items=vis_items) output_list = v.vector_gen_function(vis_items, vocab=vis_vocab) self.directory = directory self.image_list = image_list self.output_list = output_list model = spa.SPA(label='MAIN') with model: model.vision_system = v.make_vision_system( image_list, output_list, n_neurons=500, AIT_V1_strength=p.AIT_V1_strength, AIT_r_transform=p.AIT_r_transform, V1_r_transform=p.V1_r_transform) model.concept = spa.State(p.D, vocab=vis_vocab) nengo.Connection(model.vision_system.AIT, model.concept.input) model.compare = spa.Compare(p.D) model.wm = spa.State(p.D, vocab=vis_vocab) model.result = spa.State(p.D, feedback=p.result_feedback) nengo.Connection(model.concept.output, model.compare.inputA, synapse=0.01) nengo.Connection(model.wm.output, model.compare.inputB) vocab = model.get_input_vocab('result') nengo.Connection(model.compare.output, model.result.input, transform=p.compare_to_result_strength * np.array([vocab.parse('SAME').v]).T) def result_to_motor(in_vocab, out_vocab): mapping = np.zeros((p.D, p.D)) for i in range(len(input_items)): mapping += np.outer( in_vocab.parse(result_vocab_items[i]).v, out_vocab.parse(input_items[i]).v) transform = mapping.T return transform model.motor_system = m.make_motor_system( input_items, action_items, motor_feedback=p.motor_feedback, motor_transform=p.motor_transform, finger_feedback=p.finger_feedback, motor_to_fingers_strength=p.motor_to_fingers_strength) nengo.Connection(model.result.output, model.motor_system.motor_input.input, transform=result_to_motor( vocab, model.motor_system.motor_vocab)) def present_func(t): if t < 1: index = 0 else: index = 1 return image_list[index] stim = nengo.Node(present_func) nengo.Connection(stim, model.vision_system.presentation_node) stim_wm = nengo.Node( model.get_input_vocab('wm').parse('FATIGUE').v) nengo.Connection(stim_wm, model.wm.input) self.V1_probe = nengo.Probe(model.vision_system.V1) self.AIT_probe = nengo.Probe(model.vision_system.AIT, synapse=0.005) self.PFC_probe = nengo.Probe(model.compare.output, synapse=0.005) self.PMC_probe = nengo.Probe(model.result.output, synapse=0.005) self.MC_probe = nengo.Probe(model.motor_system.motor.output, synapse=0.005) self.finger_probe = nengo.Probe(model.motor_system.fingers.output, synapse=0.005) self.final_probe = nengo.Probe( model.motor_system.finger_pos.output, synapse=0.005) self.mymodel = model return model
def test_basal_ganglia(Simulator, seed, plt): model = spa.SPA(seed=seed) with model: model.vision = spa.Buffer(dimensions=16) model.motor = spa.Buffer(dimensions=16) model.compare = spa.Compare(dimensions=16) # test all acceptable condition formats actions = spa.Actions( '0.5 --> motor=A', 'dot(vision, CAT) --> motor=B', 'dot(vision*CAT, DOG) --> motor=C', '2*dot(vision, CAT*0.5) --> motor=D', 'dot(vision, CAT) + 0.5 - dot(vision,CAT) --> motor=E', 'dot(vision, PARROT) + compare --> motor=F', '0.5*dot(vision, MOUSE) + 0.5*compare --> motor=G', '( dot(vision, MOUSE) - compare ) * 0.5 --> motor=H') model.bg = spa.BasalGanglia(actions) def input(t): if t < 0.1: return '0' elif t < 0.2: return 'CAT' elif t < 0.3: return 'DOG*~CAT' elif t < 0.4: return 'PARROT' elif t < 0.5: return 'MOUSE' else: return '0' model.input = spa.Input(vision=input, compare_A='SHOOP', compare_B='SHOOP') p = nengo.Probe(model.bg.input, 'output', synapse=0.03) sim = Simulator(model) sim.run(0.5) t = sim.trange() plt.plot(t, sim.data[p]) plt.legend(["A", "B", "C", "D", "E", "F", "G", "H"]) plt.title('Basal Ganglia output') # assert the basal ganglia is prioritizing things correctly # Motor F assert sim.data[p][t == 0.4, 5] > 0.8 # Motor G assert sim.data[p][t == 0.5, 6] > 0.8 # Motor A assert 0.6 > sim.data[p][t == 0.1, 0] > 0.4 # Motor B assert sim.data[p][t == 0.2, 1] > 0.8 # Motor C assert sim.data[p][t == 0.3, 2] > 0.6 # Motor B should be the same as Motor D assert np.allclose(sim.data[p][:, 1], sim.data[p][:, 3]) # Motor A should be the same as Motor E assert np.allclose(sim.data[p][:, 0], sim.data[p][:, 4])
model.largest = spa.State(dimensions, neurons_per_dimension=1) # gets changed based off of which disk is being considered model.goal_peg_final = spa.State(dimensions, neurons_per_dimension=1) # input to cortical states model.set_focus = spa.State(dimensions, neurons_per_dimension=1) model.set_goal = spa.State(dimensions, neurons_per_dimension=1) model.set_goal_peg = spa.State(dimensions, neurons_per_dimension=1) ## action states # what to move model.move_disk = spa.State(dimensions, neurons_per_dimension=1) # where to move it model.move_peg = spa.State(dimensions, neurons_per_dimension=1) model.goal_target_peg_comp = spa.Compare(dimensions, neurons_per_multiply=1) model.focus_goal_comp = spa.Compare(dimensions, neurons_per_multiply=1) model.focus_goal_peg_comp = spa.Compare(dimensions, neurons_per_multiply=1) model.target_focus_peg_comp = spa.Compare(dimensions, neurons_per_multiply=1) # Connect the inputs to the the compare networks model.cortical_actions = spa.Actions( "goal_target_peg_comp_A = goal_peg", "goal_target_peg_comp_B = target_peg", "focus_goal_comp_A = focus", "focus_goal_comp_B = goal", "focus_goal_peg_comp_A = focus_peg", "focus_goal_peg_comp_B = goal_peg", "target_focus_peg_comp_A = target_peg", "target_focus_peg_comp_B = focus_peg")
def create_model(): #print trial_info print('---- INTIALIZING MODEL ----') global model model = spa.SPA() with model: #display current stimulus pair (not part of model) if nengo_gui_on and True: model.pair_input = nengo.Node(present_pair) model.pair_display = nengo.Node( display_func, size_in=model.pair_input.size_out) # to show input nengo.Connection(model.pair_input, model.pair_display, synapse=None) # control model.control_net = nengo.Network() with model.control_net: #assuming the model knows which hand to use (which was blocked) model.hand_input = nengo.Node(get_hand) model.target_hand = spa.State(Dmid, vocab=vocab_motor, feedback=1) nengo.Connection(model.hand_input, model.target_hand.input, synapse=None) model.attend = spa.State(D, vocab=vocab_attend, feedback=.5) # vocab_attend model.goal = spa.State(Dlow, vocab=vocab_goal, feedback=.7) # current goal ### vision ### # set up network parameters n_vis = X_train.shape[1] # nr of pixels, dimensions of network n_hid = 1000 # nr of gabor encoders/neurons # random state to start rng = np.random.RandomState(9) encoders = Gabor().generate( n_hid, (4, 4), rng=rng) # gabor encoders, 11x11 apparently, why? encoders = Mask( (14, 90)).populate(encoders, rng=rng, flatten=True) # use them on part of the image model.visual_net = nengo.Network() with model.visual_net: #represent currently attended item model.attended_item = nengo.Node(present_item2, size_in=D) nengo.Connection(model.attend.output, model.attended_item) model.vision_gabor = nengo.Ensemble( n_hid, n_vis, eval_points=X_train, # neuron_type=nengo.LIF(), neuron_type=nengo.AdaptiveLIF( tau_n=.01, inc_n=.05 ), #to get a better fit, use more realistic neurons that adapt to input intercepts=nengo.dists.Uniform(-0.1, 0.1), #intercepts=nengo.dists.Choice([-0.5]), #should we comment this out? not sure what's happening #max_rates=nengo.dists.Choice([100]), encoders=encoders) #recurrent connection (time constant 500 ms) # strength = 1 - (100/500) = .8 zeros = np.zeros_like(X_train) nengo.Connection( model.vision_gabor, model.vision_gabor, synapse=0.005, #.1 eval_points=np.vstack( [X_train, zeros, np.random.randn(*X_train.shape)]), transform=.5) model.visual_representation = nengo.Ensemble(n_hid, dimensions=Dmid) model.visconn = nengo.Connection( model.vision_gabor, model.visual_representation, synapse=0.005, #was .005 eval_points=X_train, function=train_targets, solver=nengo.solvers.LstsqL2(reg=0.01)) nengo.Connection(model.attended_item, model.vision_gabor, synapse=.02) #.03) #synapse? # display attended item, only in gui if nengo_gui_on: # show what's being looked at model.display_attended = nengo.Node( display_func, size_in=model.attended_item.size_out) # to show input nengo.Connection(model.attended_item, model.display_attended, synapse=None) #add node to plot total visual activity model.visual_activation = nengo.Node(None, size_in=1) nengo.Connection(model.vision_gabor.neurons, model.visual_activation, transform=np.ones((1, n_hid)), synapse=None) ### central cognition ### ##### Concepts ##### model.concepts = spa.AssociativeMemory( vocab_all_words, #vocab_concepts, wta_output=True, wta_inhibit_scale=1, #was 1 #default_output_key='NONE', #what to say if input doesn't match threshold=0.3 ) # how strong does input need to be for it to recognize nengo.Connection( model.visual_representation, model.concepts.input, transform=.8 * vision_mapping ) #not too fast to concepts, might have to be increased to have model react faster to first word. #concepts accumulator model.concepts_evidence = spa.State( 1, feedback=1, feedback_synapse=0.005 ) #the lower the synapse, the faster it accumulates (was .1) concepts_evidence_scale = 2.5 nengo.Connection(model.concepts.am.elem_output, model.concepts_evidence.input, transform=concepts_evidence_scale * np.ones( (1, model.concepts.am.elem_output.size_out)), synapse=0.005) #concepts switch model.do_concepts = spa.AssociativeMemory(vocab_reset, default_output_key='CLEAR', threshold=.2) nengo.Connection( model.do_concepts.am.ensembles[-1], model.concepts_evidence.all_ensembles[0].neurons, transform=np.ones( (model.concepts_evidence.all_ensembles[0].n_neurons, 1)) * -10, synapse=0.005) ###### Visual Representation ###### model.vis_pair = spa.State( D, vocab=vocab_all_words, feedback=1.0, feedback_synapse=.05 ) #was 2, 1.6 works ok, but everything gets activated. ##### Familiarity ##### # Assoc Mem with Learned Words # - familiarity signal should be continuous over all items, so no wta model.dm_learned_words = spa.AssociativeMemory(vocab_learned_words, threshold=.2) nengo.Connection(model.dm_learned_words.output, model.dm_learned_words.input, transform=.4, synapse=.02) # Familiarity Accumulator model.familiarity = spa.State( 1, feedback=.9, feedback_synapse=0.1) #fb syn influences speed of acc #familiarity_scale = 0.2 #keep stable for negative fam # familiarity accumulator switch model.do_fam = spa.AssociativeMemory(vocab_reset, default_output_key='CLEAR', threshold=.2) # reset nengo.Connection( model.do_fam.am.ensembles[-1], model.familiarity.all_ensembles[0].neurons, transform=np.ones( (model.familiarity.all_ensembles[0].n_neurons, 1)) * -10, synapse=0.005) #first a sum to represent summed similarity model.summed_similarity = nengo.Ensemble(n_neurons=100, dimensions=1) nengo.Connection( model.dm_learned_words.am.elem_output, model.summed_similarity, transform=np.ones( (1, model.dm_learned_words.am.elem_output.size_out))) #take sum #then a connection to accumulate this summed sim def familiarity_acc_transform(summed_sim): fam_scale = .5 fam_threshold = 0 #actually, kind of bias fam_max = 1 return fam_scale * (2 * ((summed_sim - fam_threshold) / (fam_max - fam_threshold)) - 1) nengo.Connection(model.summed_similarity, model.familiarity.input, function=familiarity_acc_transform) ##### Recollection & Representation ##### model.dm_pairs = spa.AssociativeMemory( vocab_learned_pairs, wta_output=True) #input_keys=list_of_pairs nengo.Connection(model.dm_pairs.output, model.dm_pairs.input, transform=.5, synapse=.05) #representation rep_scale = 0.5 model.representation = spa.State(D, vocab=vocab_all_words, feedback=1.0) model.rep_filled = spa.State( 1, feedback=.9, feedback_synapse=.1) #fb syn influences speed of acc model.do_rep = spa.AssociativeMemory(vocab_reset, default_output_key='CLEAR', threshold=.2) nengo.Connection( model.do_rep.am.ensembles[-1], model.rep_filled.all_ensembles[0].neurons, transform=np.ones( (model.rep_filled.all_ensembles[0].n_neurons, 1)) * -10, synapse=0.005) nengo.Connection(model.representation.output, model.rep_filled.input, transform=rep_scale * np.reshape(sum(vocab_learned_pairs.vectors), ((1, D)))) ###### Comparison ##### model.comparison = spa.Compare(D, vocab=vocab_all_words, neurons_per_multiply=500, input_magnitude=.3) #turns out comparison is not an accumulator - we also need one of those. model.comparison_accumulator = spa.State( 1, feedback=.9, feedback_synapse=0.05) #fb syn influences speed of acc model.do_compare = spa.AssociativeMemory(vocab_reset, default_output_key='CLEAR', threshold=.2) #reset nengo.Connection( model.do_compare.am.ensembles[-1], model.comparison_accumulator.all_ensembles[0].neurons, transform=np.ones( (model.comparison_accumulator.all_ensembles[0].n_neurons, 1)) * -10, synapse=0.005) #error because we apply a function to a 'passthrough' node, inbetween ensemble as a solution: model.comparison_result = nengo.Ensemble(n_neurons=100, dimensions=1) nengo.Connection(model.comparison.output, model.comparison_result) def comparison_acc_transform(comparison): comparison_scale = .6 comparison_threshold = 0 #actually, kind of bias comparison_max = .6 return comparison_scale * (2 * ( (comparison - comparison_threshold) / (comparison_max - comparison_threshold)) - 1) nengo.Connection(model.comparison_result, model.comparison_accumulator.input, function=comparison_acc_transform) #motor model.motor_net = nengo.Network() with model.motor_net: #input multiplier model.motor_input = spa.State(Dmid, vocab=vocab_motor) #higher motor area (SMA?) model.motor = spa.State(Dmid, vocab=vocab_motor, feedback=.7) #connect input multiplier with higher motor area nengo.Connection(model.motor_input.output, model.motor.input, synapse=.1, transform=2) #finger area model.fingers = spa.AssociativeMemory( vocab_fingers, input_keys=['L1', 'L2', 'R1', 'R2'], wta_output=True) nengo.Connection(model.fingers.output, model.fingers.input, synapse=0.1, transform=0.3) #feedback #conncetion between higher order area (hand, finger), to lower area nengo.Connection(model.motor.output, model.fingers.input, transform=.25 * motor_mapping) #was .2 #finger position (spinal?) model.finger_pos = nengo.networks.EnsembleArray(n_neurons=50, n_ensembles=4) nengo.Connection(model.finger_pos.output, model.finger_pos.input, synapse=0.1, transform=0.8) #feedback #connection between finger area and finger position nengo.Connection(model.fingers.am.elem_output, model.finger_pos.input, transform=1.0 * np.diag([0.55, .54, .56, .55])) #fix these model.bg = spa.BasalGanglia( spa.Actions( #wait & start a_aa_wait='dot(goal,WAIT) - .9 --> goal=0', a_attend_item1= 'dot(goal,DO_TASK) - .0 --> goal=RECOG, attend=ITEM1, do_concepts=GO', #attend words b_attending_item1= 'dot(goal,RECOG) + dot(attend,ITEM1) - concepts_evidence - .3 --> goal=RECOG, attend=ITEM1, do_concepts=GO', # vis_pair=2.5*(ITEM1*concepts)', c_attend_item2= 'dot(goal,RECOG) + dot(attend,ITEM1) + concepts_evidence - 1.6 --> goal=RECOG2, attend=ITEM2, vis_pair=3*(ITEM1*concepts)', d_attending_item2= 'dot(goal,RECOG2+RECOG) + dot(attend,ITEM2) - concepts_evidence - .4 --> goal=RECOG2, attend=ITEM2, do_concepts=GO, dm_learned_words=1.0*(~ITEM1*vis_pair)', #vis_pair=1.2*(ITEM2*concepts) e_start_familiarity= 'dot(goal,RECOG2) + dot(attend,ITEM2) + concepts_evidence - 1.8 --> goal=FAMILIARITY, do_fam=GO, vis_pair=1.9*(ITEM2*concepts), dm_learned_words=2.0*(~ITEM1*vis_pair+~ITEM2*vis_pair)', #judge familiarity f_accumulate_familiarity= '1.1*dot(goal,FAMILIARITY) - 0.2 --> goal=FAMILIARITY-RECOG2, do_fam=GO, dm_learned_words=.8*(~ITEM1*vis_pair+~ITEM2*vis_pair)', g_respond_unfamiliar= 'dot(goal,FAMILIARITY) - familiarity - .5*dot(fingers,L1+L2+R1+R2) - .6 --> goal=RESPOND_MISMATCH-FAMILIARITY, do_fam=GO, motor_input=1.6*(target_hand+MIDDLE)', #g2_respond_familiar = 'dot(goal,FAMILIARITY) + familiarity - .5*dot(fingers,L1+L2+R1+R2) - .6 --> goal=RESPOND, do_fam=GO, motor_input=1.6*(target_hand+INDEX)', #recollection & representation h_recollection= 'dot(goal,FAMILIARITY) + familiarity - .5*dot(fingers,L1+L2+R1+R2) - .6 --> goal=RECOLLECTION-FAMILIARITY, dm_pairs = vis_pair', i_representation= 'dot(goal,RECOLLECTION) - rep_filled - .1 --> goal=RECOLLECTION, dm_pairs = vis_pair, representation=3*dm_pairs, do_rep=GO', #comparison & respond j_10_compare_word1= 'dot(goal,RECOLLECTION+1.4*COMPARE_ITEM1) + rep_filled - .9 --> goal=COMPARE_ITEM1-RECOLLECTION, do_rep=GO, do_compare=GO, comparison_A = ~ITEM1*vis_pair, comparison_B = ~ITEM1*representation', k_11_match_word1= 'dot(goal,COMPARE_ITEM1) + comparison_accumulator - .7 --> goal=COMPARE_ITEM2-COMPARE_ITEM1, do_rep=GO, comparison_A = ~ITEM1*vis_pair, comparison_B = ~ITEM1*representation', l_12_mismatch_word1= 'dot(goal,COMPARE_ITEM1) + .4 * dot(goal,RESPOND_MISMATCH) - comparison_accumulator - .7 --> goal=RESPOND_MISMATCH-COMPARE_ITEM1, do_rep=GO, motor_input=1.6*(target_hand+MIDDLE), do_compare=GO, comparison_A = ~ITEM1*vis_pair, comparison_B = ~ITEM1*representation', compare_word2= 'dot(goal,COMPARE_ITEM2) - .5 --> goal=COMPARE_ITEM2, do_compare=GO, comparison_A = ~ITEM2*vis_pair, comparison_B = ~ITEM2*representation', m_match_word2= 'dot(goal,COMPARE_ITEM2) + comparison_accumulator - .7 --> goal=RESPOND_MATCH-COMPARE_ITEM2, motor_input=1.6*(target_hand+INDEX), do_compare=GO, comparison_A = ~ITEM2*vis_pair, comparison_B = ~ITEM2*representation', n_mismatch_word2= 'dot(goal,COMPARE_ITEM2) - comparison_accumulator - dot(fingers,L1+L2+R1+R2)- .7 --> goal=RESPOND_MISMATCH-COMPARE_ITEM2, motor_input=1.6*(target_hand+MIDDLE),do_compare=GO, comparison_A = ~ITEM2*vis_pair, comparison_B = ~ITEM2*representation', #respond o_respond_match= 'dot(goal,RESPOND_MATCH) - .1 --> goal=RESPOND_MATCH, motor_input=1.6*(target_hand+INDEX)', p_respond_mismatch= 'dot(goal,RESPOND_MISMATCH) - .1 --> goal=RESPOND_MISMATCH, motor_input=1.6*(target_hand+MIDDLE)', #finish x_response_done= 'dot(goal,RESPOND_MATCH) + dot(goal,RESPOND_MISMATCH) + 2*dot(fingers,L1+L2+R1+R2) - .7 --> goal=2*END', y_end= 'dot(goal,END)-.1 --> goal=END-RESPOND_MATCH-RESPOND_MISMATCH', z_threshold='.05 --> goal=0' #possible to match complete buffer, ie is representation filled? # motor_input=1.5*target_hand+MIDDLE, )) print(model.bg.actions.count) #print(model.bg.dimensions) model.thalamus = spa.Thalamus(model.bg) model.cortical = spa.Cortical( # cortical connection: shorthand for doing everything with states and connections spa.Actions( # 'motor_input = .04*target_hand', # 'dm_learned_words = .1*vis_pair', #'dm_pairs = 2*stimulus' #'vis_pair = 2*attend*concepts+concepts', #fam 'comparison_A = 2*vis_pair', #fam 'comparison_B = 2*representation*~attend', )) #probes model.pr_motor_pos = nengo.Probe( model.finger_pos.output, synapse=.01) #raw vector (dimensions x time) model.pr_motor = nengo.Probe(model.fingers.output, synapse=.01) #model.pr_motor1 = nengo.Probe(model.motor.output, synapse=.01) if not nengo_gui_on: model.pr_vision_gabor = nengo.Probe( model.vision_gabor.neurons, synapse=.005 ) #do we need synapse, or should we do something with the spikes model.pr_familiarity = nengo.Probe( model.dm_learned_words.am.elem_output, synapse=.01) #element output, don't include default model.pr_concepts = nengo.Probe( model.concepts.am.elem_output, synapse=.01) # element output, don't include default #multiply spikes with the connection weights #input model.input = spa.Input(goal=goal_func) #print(sum(ens.n_neurons for ens in model.all_ensembles)) #return model #to show select BG rules # get names rules if nengo_gui_on: vocab_actions = spa.Vocabulary(model.bg.output.size_out) for i, action in enumerate(model.bg.actions.actions): vocab_actions.add(action.name.upper(), np.eye(model.bg.output.size_out)[i]) model.actions = spa.State(model.bg.output.size_out, subdimensions=model.bg.output.size_out, vocab=vocab_actions) nengo.Connection(model.thalamus.output, model.actions.input) for net in model.networks: if net.label is not None and net.label.startswith('channel'): net.label = ''
def __init__(self): self.compare = spa.Compare(dimensions=16)
def test_basal_ganglia(Simulator, seed, plt, allclose): model = spa.SPA(seed=seed) with model: model.vision = spa.Buffer(dimensions=16) model.motor = spa.Buffer(dimensions=16) model.compare = spa.Compare(dimensions=16) # test all acceptable condition formats actions = spa.Actions( "0.5 --> motor=A", "dot(vision, CAT) --> motor=B", "dot(vision*CAT, DOG) --> motor=C", "2*dot(vision, CAT*0.5) --> motor=D", "dot(vision, CAT) + 0.5 - dot(vision,CAT) --> motor=E", "dot(vision, PARROT) + compare --> motor=F", "0.5*dot(vision, MOUSE) + 0.5*compare --> motor=G", "( dot(vision, MOUSE) - compare ) * 0.5 --> motor=H", ) model.bg = spa.BasalGanglia(actions) def input(t): if t < 0.1: return "0" elif t < 0.2: return "CAT" elif t < 0.3: return "DOG*~CAT" elif t < 0.4: return "PARROT" elif t < 0.5: return "MOUSE" else: return "0" model.input = spa.Input(vision=input, compare_A="SHOOP", compare_B="SHOOP") p = nengo.Probe(model.bg.input, "output", synapse=0.03) with Simulator(model) as sim: sim.run(0.5) t = sim.trange() plt.plot(t, sim.data[p]) plt.legend(["A", "B", "C", "D", "E", "F", "G", "H"]) plt.title("Basal Ganglia output") # assert the basal ganglia is prioritizing things correctly # Motor F assert sim.data[p][t == 0.4, 5] > 0.8 # Motor G assert sim.data[p][t == 0.5, 6] > 0.8 # Motor A assert 0.6 > sim.data[p][t == 0.1, 0] > 0.4 # Motor B assert sim.data[p][t == 0.2, 1] > 0.8 # Motor C assert sim.data[p][t == 0.3, 2] > 0.6 # Motor B should be the same as Motor D assert allclose(sim.data[p][:, 1], sim.data[p][:, 3]) # Motor A should be the same as Motor E assert allclose(sim.data[p][:, 0], sim.data[p][:, 4])
vocab_space = spa.Vocabulary(D_space) model = spa.SPA() with model: model.rule = spa.State(D_space, vocab=vocab_space) model.objs = spa.State(D_space, feedback=1, vocab=vocab_space) model.status = spa.State(32) speed = 0.3 separation = 0.3 strength = 0.4 model.subjx = spa.Compare(D_space) model.subjy = spa.Compare(D_space) model.objx = spa.Compare(D_space) model.objy = spa.Compare(D_space) for ens in model.all_ensembles: ens.neuron_type = nengo.Direct() model.cortical = spa.Cortical( spa.Actions( 'subjx_A=rule*~S*X', 'subjy_A=rule*~S*Y', 'objx_A=rule*~O*X', 'objy_A=rule*~O*Y', 'subjx_B=objs', 'subjy_B=objs',
vocab=vocab) model.cue = spa.State(dimensions=dimensions, neurons_per_dimension=100, feedback=0.7, vocab=vocab) model.target = spa.State(dimensions=dimensions, neurons_per_dimension=100, feedback=0.7, vocab=vocab) model.representation = spa.Memory(dimensions=dimensions, neurons_per_dimension=100, vocab=vocab) model.awake = spa.Memory(dimensions=dimensions, neurons_per_dimension=100, vocab=vocab) model.similar = spa.Compare(dimensions=dimensions, vocab=vocab) model.output = spa.Buffer(dimensions=dimensions, neurons_per_dimension=100) model.state = spa.Buffer(dimensions=dimensions, neurons_per_dimension=100) # Specify the action mapping and attention function actions = spa.Actions( #'dot(cue, LEFT) --> vision1=vision1*2', #'dot(cue, RIGHT) --> vision2=vision2*2', #'dot(cue, HIGH) --> output = LOW' #'dot(cue, LOW) --> output = LOW' 'similar --> output = Match', '1.5 - similar --> output = NotMatch', '1.4 --> output = IDK', '3 * dot(state, Wait) --> output = IDK') cortical_actions = spa.Actions('representation=vision1 * L + vision2 * R', 'awake=representation * ~cue', 'similar_A = awake', 'similar_B = target')