def model(self, p): vocab = spa.Vocabulary(p.D) for i in range(p.M): vocab.parse('M%d' % i) order = np.arange(p.n_tests) np.random.shuffle(order) model = spa.SPA() with model: model.cue = spa.State(p.D, vocab=vocab) for ens in model.cue.all_ensembles: ens.neuron_type = nengo.Direct() model.accum = spa.State(p.D, vocab=vocab, feedback=p.feedback) model.recall = spa.AssociativeMemory(vocab, wta_output=True, threshold_output=True) model.recalled = spa.State(p.D, vocab=vocab) for ens in model.recalled.all_ensembles: ens.neuron_type = nengo.Direct() nengo.Connection(model.cue.output, model.accum.input, transform=p.accum) nengo.Connection(model.recall.output, model.recalled.input) nengo.Connection(model.accum.output, model.recall.input) model.same = nengo.Ensemble(n_neurons=100, dimensions=1, encoders=nengo.dists.Choice([[1]]), intercepts=nengo.dists.Uniform(0.3, 1)) model.dot = nengo.networks.Product(n_neurons=200, dimensions=p.D) nengo.Connection(model.cue.output, model.dot.A) nengo.Connection(model.recalled.output, model.dot.B) nengo.Connection(model.dot.output, model.same, transform=[[1] * p.D]) def stim(t): index = int(t / p.T_test) index2 = order[index % len(order)] if index % 2 == 0: return 'X%d' % (index2 % p.M) else: return 'M%d' % (index2 % p.M) model.input = spa.Input(cue=stim) self.p_same = nengo.Probe(model.same, synapse=0.01) return model
def build_cleanup(self, net): net.vocab = spa.Vocabulary(dimensions=self.cleanup.dimensions) net.vocab.parse(" + ".join(s.label for s in self.syllables)) net.cleanup = spa.AssociativeMemory(net.vocab, wta_output=True, threshold_output=True, **self.cleanup.kwargs()) net.memory = spa.State(dimensions=self.cleanup.dimensions, vocab=net.vocab, **self.memory.kwargs()) nengo.Connection(net.cleanup.output, net.memory.input)
def generate(input_signal, alpha=1000.0): beta = alpha / 4.0 # Read in the class mean for numbers from vision network weights_data = np.load('models/mnist_vision_data/params.npz') weights = weights_data['Wc'] means_data = np.load('models/mnist_vision_data/class_means.npz') means = np.matrix(1.0 / means_data['means']) sps = np.multiply(weights.T, means.T)[:10] sps_labels = [ 'ZERO', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE' ] dimensions = weights.shape[0] # generate the Function Space forces, _, goals = forcing_functions.load_folder( 'models/handwriting_trajectories', rhythmic=False, alpha=alpha, beta=beta) # make an array out of all the possible functions we want to represent force_space = np.vstack(forces) # use this array as our space to perform svd over fs = nengo.FunctionSpace(space=force_space, n_basis=10) # store the weights for each number weights_x = [] weights_y = [] for ii in range(len(goals)): forces = force_space[ii * 2:ii * 2 + 2] # load up the forces to be output by the forcing function # calculate the corresponding weights over the basis functions weights_x.append(np.dot(fs.basis.T, forces[0])) weights_y.append(np.dot(fs.basis.T, forces[1])) # Create our vocabularies rng = np.random.RandomState(0) vocab_vision = Vocabulary(dimensions=dimensions, rng=rng) vocab_dmp_weights_x = Vocabulary(dimensions=fs.n_basis + 2, rng=rng) vocab_dmp_weights_y = Vocabulary(dimensions=fs.n_basis + 2, rng=rng) for label, sp, wx, wy, goal in zip(sps_labels, sps, weights_x, weights_y, goals): vocab_vision.add(label, np.array(sp)[0] / np.linalg.norm(np.array(sp)[0])) vocab_dmp_weights_x.add(label, np.hstack([wx, goal[0][0], goal[1][0]])) vocab_dmp_weights_y.add(label, np.hstack([wy, goal[0][1], goal[1][1]])) net = spa.SPA() # net.config[nengo.Ensemble].neuron_type = nengo.Direct() with net: # def input_func(t): # return vocab_vision.parse(input_signal).v # net.input = nengo.Node(input_func, label='input') net.input = spa.State(dimensions, subdimensions=10, vocab=vocab_vision) time_func = lambda t: min(max((t * 2) % 4 - 2.5, -1), 1) timer_node = nengo.Node(output=time_func, label='timer') # ------------------- Point Attractors -------------------- def goals_func(t, x): if (x[0] + 1) < 1e-5: return x[1], x[2] return x[3], x[4] goal_node = nengo.Node(goals_func, size_in=5, size_out=2, label='goals') nengo.Connection(timer_node, goal_node[0]) net.x = point_attractor.generate(n_neurons=1000, alpha=alpha, beta=beta) nengo.Connection(goal_node[0], net.x.input[0], synapse=None) net.y = point_attractor.generate(n_neurons=1000, alpha=alpha, beta=beta) nengo.Connection(goal_node[1], net.y.input[0], synapse=None) # -------------------- Ramp ------------------------------ ramp_node = nengo.Node(output=time_func, label='ramp node') ramp = nengo.Ensemble(n_neurons=1000, dimensions=1, label='ramp') nengo.Connection(ramp_node, ramp) # ------------------- Forcing Functions -------------------- net.assoc_mem_x = spa.AssociativeMemory( input_vocab=vocab_vision, output_vocab=vocab_dmp_weights_x, wta_output=False) nengo.Connection(net.input.output, net.assoc_mem_x.input) nengo.Connection(net.assoc_mem_x.output[[-2, -1]], goal_node[[1, 3]]) net.assoc_mem_y = spa.AssociativeMemory( input_vocab=vocab_vision, output_vocab=vocab_dmp_weights_y, wta_output=False) nengo.Connection(net.input.output, net.assoc_mem_y.input) nengo.Connection(net.assoc_mem_y.output[[-2, -1]], goal_node[[2, 4]]) # -------------------- Product for decoding ----------------------- net.product_x = nengo.Network('Product X') nengo.networks.Product(n_neurons=1000, dimensions=fs.n_basis, net=net.product_x, input_magnitude=1.0) net.product_y = nengo.Network('Product Y') nengo.networks.Product(n_neurons=1000, dimensions=fs.n_basis, net=net.product_y, input_magnitude=1.0) # get the largest basis function value for normalization max_basis = np.max(fs.basis * fs.scale) domain = np.linspace(-1, 1, fs.basis.shape[0]) for ff, product in zip( [net.assoc_mem_x.output, net.assoc_mem_y.output], [net.product_x, net.product_y]): for ii in range(fs.n_basis): # find the value of a basis function at a value of x def basis_fn(x, jj=ii): index = int(x[0] * len(domain) / 2.0 + len(domain) / 2.0) index = max(min(index, len(domain) - 1), 0) return fs.basis[index][jj] * fs.scale / max_basis # multiply the value of each basis function at x by its weight nengo.Connection(ramp, product.B[ii], function=basis_fn) nengo.Connection(ff[ii], product.A[ii]) def relay_func(t, x): t = time_func(t) if t <= -1: return [0, 0] return x relay = nengo.Node(output=relay_func, size_in=2, size_out=2, label='relay') nengo.Connection(net.product_x.output, relay[0], transform=np.ones((1, fs.n_basis)) * max_basis, synapse=None) nengo.Connection(net.product_y.output, relay[1], transform=np.ones((1, fs.n_basis)) * max_basis, synapse=None) nengo.Connection(relay[0], net.x.input[1], synapse=None) nengo.Connection(relay[1], net.y.input[1], synapse=None) # -------------------- Output ------------------------------ net.output = nengo.Node(size_in=2) nengo.Connection(net.x.output, net.output[0], synapse=0.01) nengo.Connection(net.y.output, net.output[1], synapse=0.01) # create a node to give a plot of the represented function ff_plot = fs.make_plot_node(domain=domain, lines=2, ylim=[-75, 75]) nengo.Connection(net.assoc_mem_x.output[:fs.n_basis], ff_plot[:fs.n_basis], synapse=0.1) nengo.Connection(net.assoc_mem_y.output[:fs.n_basis], ff_plot[fs.n_basis:], synapse=0.1) return net
def __init__(self, vocab_compare, status_scale=.8, status_feedback=.6, status_feedback_synapse=.1, pos_bias=0, neg_bias=0, threshold_input_detect=.5, threshold_cleanup=.3, wta_inhibit_scale_cleanup=3, **kwargs): dimensions = vocab_compare.dimensions super(CompareAccumulator, self).__init__(dimensions, vocab=vocab_compare, **kwargs) with self: #clean up memories for input, to enable clean comparison self.cleanup_inputA = spa.AssociativeMemory( input_vocab=vocab_compare, wta_output=True, threshold=threshold_cleanup, wta_inhibit_scale=wta_inhibit_scale_cleanup) self.cleanup_inputB = spa.AssociativeMemory( input_vocab=vocab_compare, wta_output=True, threshold=threshold_cleanup, wta_inhibit_scale=wta_inhibit_scale_cleanup) nengo.Connection(self.cleanup_inputA.output, self.inputA) nengo.Connection(self.cleanup_inputB.output, self.inputB) #compare status indicator self.comparison_status = nengo.Ensemble(50, 1) nengo.Connection(self.comparison_status, self.comparison_status, transform=status_feedback, synapse=status_feedback_synapse) #positive source nengo.Connection(self.output, self.comparison_status, transform=status_scale + pos_bias) #detect when input present on both inputs n_signal = min( 50, dimensions ) #number of random dimensions used to determine whether input is present #inputA self.switch_inA = nengo.Ensemble( n_neurons=n_signal * 50, dimensions=n_signal, radius=1) #50 neurons per dimension nengo.Connection( self.cleanup_inputA.input[0:n_signal], self.switch_inA, transform=10, synapse=None) #no synapse, as input signal directly #inputB self.switch_inB = nengo.Ensemble( n_neurons=n_signal * 50, dimensions=n_signal, radius=1) #50 neurons per dimension nengo.Connection( self.cleanup_inputB.input[0:n_signal], self.switch_inB, transform=10, synapse=None) #no synapse, as input signal directly #combine evidence self.switch_detect = nengo.Ensemble(n_neurons=500, dimensions=2, radius=1.4) nengo.Connection(self.switch_inA, self.switch_detect[0], function=lambda x: np.sqrt(np.sum(x * x)), eval_points=nengo.dists.Gaussian(0, .1)) nengo.Connection(self.switch_inB, self.switch_detect[1], function=lambda x: np.sqrt(np.sum(x * x)), eval_points=nengo.dists.Gaussian(0, .1)) #negative source self.negative_source = nengo.Ensemble(n_neurons=100, dimensions=1) nengo.Connection(self.switch_detect, self.negative_source, function=lambda x: 1 if x[0] * x[1] > threshold_input_detect else 0) nengo.Connection(self.negative_source, self.comparison_status, transform=-(status_scale / 2) - neg_bias) #inhibit when no input - doesn't work well cause it's also dependent on input def inhibit_function(x): if x[0] * x[1] > threshold_input_detect: return 0 else: return np.ones((self.comparison_status.n_neurons)) nengo.Connection(self.switch_detect, self.comparison_status.neurons, function=inhibit_function, transform=-1, synapse=0.005) #bias #nengo.Connection(self.negative_source, self.comparison_status, transform=bias) #outputs we can use on LHS self.outputs['status'] = (self.comparison_status, 1) #input for RHS self.inputs['cleanA'] = (self.cleanup_inputA.input, vocab_compare) self.inputs['cleanB'] = (self.cleanup_inputB.input, vocab_compare)
def get_model(q_scaling=1, direct=False, p_learning=True): model = nengo.Network('RL P-learning', seed=13) #if direct: # model.config[nengo.Ensemble].neuron_type = nengo.Direct() if direct: neuron_type = nengo.Direct() else: neuron_type = nengo.LIF() if p_learning: with model: # Model of the external environment # Input: action semantic pointer # Output: current state semantic pointer #model.env = nengo.Node(Environment(vocab=vocab, time_interval=time_interval), size_in=DIM, size_out=DIM) agent = Agent(vocab=vocab, time_interval=time_interval, q_scaling=q_scaling) model.env = nengo.Node(agent, size_in=1, size_out=DIM * 3) model.state = spa.State(DIM, vocab=vocab) model.action = spa.State(DIM, vocab=vocab) model.probability = spa.State(DIM, vocab=vocab) # State and selected action in one ensemble model.state_and_action = nengo.Ensemble( n_neurons=n_sa_neurons, dimensions=DIM * 2, intercepts=AreaIntercepts(dimensions=DIM * 2)) #model.cconv = nengo.networks.CircularConvolution(300, DIM) nengo.Connection(model.state.output, model.state_and_action[:DIM]) nengo.Connection(model.env[:DIM], model.state_and_action[DIM:]) conn = nengo.Connection( model.state_and_action, model.probability.input, function=lambda x: [0] * DIM, learning_rule_type=nengo.PES( pre_synapse=z**(-int(time_interval * 1000))), ) # Semantic pointer for the Q values of each state # In the form of q0*S0 + q1*S1 + q2*S2 model.q = spa.State(DIM, vocab=vocab) # Scalar reward value from the dot product of P and Q model.reward = nengo.Ensemble(100, 1, neuron_type=neuron_type) #TODO: figure out what the result of P.Q is used for model.prod = nengo.networks.Product(n_neurons=n_prod_neurons, dimensions=DIM) nengo.Connection(model.probability.output, model.prod.A) #nengo.Connection(model.q.output, model.prod.B) nengo.Connection(model.env[DIM * 2:], model.prod.B) nengo.Connection(model.prod.output, model.reward, transform=np.ones((1, DIM))) #TODO: doublecheck that this is the correct way to connect things nengo.Connection(model.env[DIM:DIM * 2], model.state.input) #TODO: need to set up error signal and handle timing model.error = spa.State(DIM, vocab=vocab) nengo.Connection(model.error.output, conn.learning_rule) #TODO: figure out which way the sign goes, one should be negative, and the other positive #TODO: figure out how to delay by one "time-step" correctly nengo.Connection(model.state.output, model.error.input, transform=-1) nengo.Connection(model.probability.output, model.error.input, transform=1, synapse=z**(-int(time_interval * 1000))) #synapse=nengolib.synapses.PureDelay(500)) #500ms delay # Testing the delay synapse to make sure it works as expected model.state_delay_test = spa.State(DIM, vocab=vocab) nengo.Connection(model.state.output, model.state_delay_test.input, synapse=z**(-int(time_interval * 1000))) nengo.Connection(model.reward, model.env) nengo.Connection(model.env[:DIM], model.action.input) # Purely for plotting nengo.Connection(model.env[DIM * 2:], model.q.input) # Purely for plotting return model, agent else: with model: agent = Agent(vocab=vocab, time_interval=time_interval, q_scaling=q_scaling) model.env = nengo.Node(agent, size_in=1, size_out=DIM * 3) model.assoc_mem = spa.AssociativeMemory(input_vocab=vocab, output_vocab=vocab, input_keys=input_keys, output_keys=output_keys, wta_output=True, threshold_output=True) #model.state = spa.State(DIM, vocab=vocab) #model.action = spa.State(DIM, vocab=vocab) model.probability = spa.State(DIM, vocab=vocab) # State and selected action convolved together #model.state_and_action = spa.State(DIM, vocab=vocab) model.cconv = nengo.networks.CircularConvolution(300, DIM) #nengo.Connection(model.state.output, model.cconv.A) #nengo.Connection(model.action.output, model.cconv.B) nengo.Connection(model.env[DIM:DIM * 2], model.cconv.A) nengo.Connection(model.env[:DIM], model.cconv.B) nengo.Connection(model.cconv.output, model.assoc_mem.input) nengo.Connection(model.assoc_mem.output, model.probability.input) # Semantic pointer for the Q values of each state # In the form of q0*S0 + q1*S1 + q2*S2 model.q = spa.State(DIM, vocab=vocab) # Scalar reward value from the dot product of P and Q model.reward = nengo.Ensemble(100, 1, neuron_type=neuron_type) #TODO: figure out what the result of P.Q is used for model.prod = nengo.networks.Product(n_neurons=15 * DIM, dimensions=DIM) nengo.Connection(model.probability.output, model.prod.A) #nengo.Connection(model.q.output, model.prod.B) nengo.Connection(model.env[DIM * 2:], model.prod.B) nengo.Connection(model.prod.output, model.reward, transform=np.ones((1, DIM))) nengo.Connection(model.reward, model.env) return model, agent
def run(self): n_neurons = 40 subdim = 16 direct = False output = self.stimuli.output # vector output from coherence score threshold = self.stimuli.threshold # for correct answer on inf task g_transform = np.transpose(np.ones((1, self.dimensions))) # mem gate model = spa.SPA(label='ConceptModel', seed=self.seed) with model: # Vision Component model.vision = spa.Buffer(dimensions=self.dimensions, subdimensions=subdim, neurons_per_dimension=n_neurons, vocab=self.main_voc, direct=direct) # Memory Component model.sp_mem = spa.Buffer(dimensions=self.dimensions, subdimensions=subdim, neurons_per_dimension=n_neurons, vocab=self.main_voc, direct=direct) model.context_mem = spa.Memory(dimensions=self.dimensions, subdimensions=subdim, neurons_per_dimension=n_neurons, vocab=self.main_voc, tau=0.01 / 0.3, direct=direct) # Inferential Evaluation Subsystem model.inference = spa.Buffer(dimensions=self.dimensions, subdimensions=subdim, neurons_per_dimension=n_neurons, vocab=self.feat_voc, direct=direct) model.score = spa.Memory(dimensions=1, neurons_per_dimension=3000, synapse=0.05, direct=direct) model.gatesignal = spa.Memory(dimensions=1, neurons_per_dimension=500, synapse=0.05, direct=direct) model.cleanup1 = spa.AssociativeMemory( input_vocab=self.feat_voc, output_vocab=self.weight_voc, n_neurons_per_ensemble=250, threshold=0.25) # Perceptual Evaluation Subsystem model.cleanup2 = spa.AssociativeMemory(input_vocab=self.label_voc, output_vocab=self.label_voc, n_neurons_per_ensemble=1000, threshold=threshold) # Shared Component model.decision = spa.Memory(dimensions=self.dimensions, subdimensions=subdim, neurons_per_dimension=n_neurons, vocab=self.label_voc, tau=0.01 / 0.3, synapse=0.05, direct=direct) # Motor Component model.motor = spa.Memory(dimensions=self.dimensions, subdimensions=subdim, neurons_per_dimension=n_neurons, vocab=self.label_voc, synapse=0.1, direct=direct) # Convenient probing of rule applications if self.raster: model.apps = spa.Buffer(dimensions=self.dimensions, subdimensions=subdim, neurons_per_dimension=n_neurons, vocab=self.feat_voc, direct=direct) self.pApps = nengo.Probe(model.apps.state.output, synapse=0.03) self.appSpikes = nengo.Probe(model.apps.state.ea_ensembles[3], 'spikes') nengo.Connection(model.cleanup1.output, model.apps.state.input) # Action definitions actions = spa.Actions( 'dot(vision, POSNER) --> context_mem=VIS', 'dot(vision, BROOKS) --> context_mem=VIS', 'dot(vision, MURPHY) --> context_mem=INFER', 'dot(context_mem, VIS) --> gatesignal=2, context_mem=R5', 'dot(context_mem, INFER) --> context_mem=R1', 'dot(context_mem, R1) --> inference=sp_mem*~R1, context_mem=R2', 'dot(context_mem, R2) --> inference=sp_mem*~R2, context_mem=R3', 'dot(context_mem, R3) --> inference=sp_mem*~R3, context_mem=R4', 'dot(context_mem, R4) --> inference=sp_mem*~R4, context_mem=R5', 'dot(context_mem, R5) --> motor=decision') # Basal ganglia and thalamus model.bg = spa.BasalGanglia(actions) model.thal = spa.Thalamus(model.bg) # Subnetworks defined outside of SPA model.product = Product(600, self.dimensions) model.vis_gate = Product(300, self.dimensions) model.mem_gate = Product(300, self.dimensions) model.conv = CircularConvolution(250, self.dimensions, invert_a=True) # Connections for gate with memory for perceptual evaluation tasks nengo.Connection(model.vision.state.output, model.vis_gate.B) nengo.Connection(model.gatesignal.state.output, model.vis_gate.A, transform=g_transform) nengo.Connection(model.vis_gate.output, model.conv.A) nengo.Connection(model.sp_mem.state.output, model.mem_gate.B) nengo.Connection(model.gatesignal.state.output, model.mem_gate.A, transform=g_transform) nengo.Connection(model.mem_gate.output, model.conv.B) nengo.Connection(model.conv.output, model.decision.state.input) # Connections for inferential evaluation tasks nengo.Connection(model.inference.state.output, model.cleanup1.input) nengo.Connection(model.cleanup1.output, model.product.A) nengo.Connection(model.vision.state.output, model.product.B) nengo.Connection(model.cleanup2.output, model.decision.state.input) nengo.Connection(model.product.output, model.score.state.input, transform=model.product.dot_product_transform()) nengo.Connection(model.score.state.output, model.cleanup2.input, transform=np.transpose(output)) # Input to visual buffer def vision(t): if t < 0.08: return self.stimuli.task if 0.0801 <= t < 1: return self.probe else: return '0' model.input = spa.Input(vision=vision, sp_mem=self.stimuli.memory) # Inhibit the gate with inference actions actions = [2, 4, 5, 6, 7, 8] target = model.gatesignal for action in actions: for e in target.all_ensembles: nengo.Connection(model.thal.actions.ensembles[action], e.neurons, transform=[[-2]] * e.n_neurons) # Set radius for ensemble computing scalar coherence score. for ens in model.score.state.ensembles: ens.radius = 2 # Define probes for semantic pointer plots self.pVision = nengo.Probe(model.vision.state.output, synapse=0.03) self.pMotor = nengo.Probe(model.motor.state.output, synapse=0.03) self.pMemory = nengo.Probe(model.sp_mem.state.output, synapse=0.03) self.pContext = nengo.Probe(model.context_mem.state.output, synapse=0.03) self.pScore = nengo.Probe(model.score.state.output, synapse=0.03) self.pDecision = nengo.Probe(model.decision.state.output, synapse=0.03) self.pActions = nengo.Probe(model.thal.actions.output, synapse=0.01) self.pUtility = nengo.Probe(model.bg.input, synapse=0.01) # Define probes for spike rasters self.visSpikes = nengo.Probe(model.vision.state.ea_ensembles[3], 'spikes') self.conSpikes = nengo.Probe( model.context_mem.state.ea_ensembles[5], 'spikes') self.memSpikes = nengo.Probe(model.sp_mem.state.ea_ensembles[7], 'spikes') self.motSpikes = nengo.Probe(model.motor.state.ea_ensembles[1], 'spikes') self.scoSpikes = nengo.Probe(model.score.state.ea_ensembles[0], 'spikes') # Run the model sim = nengo.Simulator(model) sim.run(0.45) # Save graph if plotting chosen if self.raster: graph = Plotter(self, sim) if self.stimuli.task == 'MURPHY': graph.plot_spikes_inf() else: graph.plot_spikes_vis() # Assess correctness of output self.measure_output(sim)
def create_model( trial_info=('Target', 1, 'Short', 'CARGO', 'HOOD'), hand='LEFT', seedin=1): initialize_vocabs() print trial_info global global_item1 global global_item2 global_item1 = trial_info[3] global_item2 = trial_info[4] global model model = spa.SPA(seed=seedin) with model: #display current stimulus pair 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) #visual model.visual_net = nengo.Network() with model.visual_net: if not extended_visual: model.stimulus = spa.State(D, vocab=vocab_concepts, feedback=1) model.stim = spa.Input(stimulus=present_item_simple) else: #represent currently attended item model.attended_item = nengo.Node(present_item) model.vision_process = nengo.Ensemble( n_hid, n_vis, eval_points=X_train, neuron_type=nengo.LIFRate(), intercepts=nengo.dists.Choice([-0.5 ]), #can switch these off max_rates=nengo.dists.Choice([100]), # why? encoders=encoders) # 1000 neurons, nrofpix = dimensions # visual_representation = nengo.Node(size_in=Dmid) #output, in this case 466 outputs model.visual_representation = nengo.Ensemble( n_hid, dimensions=Dmid) # output, in this case 466 outputs model.visconn = nengo.Connection( model.vision_process, model.visual_representation, synapse=0.005, eval_points=X_train, function=train_targets, solver=nengo.solvers.LstsqL2(reg=0.01)) nengo.Connection(model.attended_item, model.vision_process, synapse=None) # display attended item model.display_node = nengo.Node( display_func, size_in=model.attended_item.size_out) # to show input nengo.Connection(model.attended_item, model.display_node, synapse=None) #control model.control_net = nengo.Network() with model.control_net: model.attend = spa.State( D, vocab=vocab_concepts, feedback=.5) #if attend item, goes to concepts model.goal = spa.State(D, vocab_goal, feedback=1) #current goal model.target_hand = spa.State(Dmid, vocab=vocab_motor, feedback=1) # concepts model.concepts = spa.AssociativeMemory(vocab_concepts, wta_output=True, wta_inhibit_scale=1) if not extended_visual: nengo.Connection(model.stimulus.output, model.concepts.input) else: nengo.Connection(model.visual_representation, model.concepts.input, transform=vision_mapping) # pair representation model.vis_pair = spa.State(D, vocab=vocab_concepts, feedback=1) model.dm_items = spa.AssociativeMemory( vocab_items ) #familiarity should be continuous over all items, so no wta nengo.Connection(model.dm_items.output, model.dm_items.input, transform=.5, synapse=.01) model.familiarity = spa.State( 1, feedback_synapse=.01) #no fb syn specified nengo.Connection( model.dm_items.am.elem_output, model.familiarity.input, #am.element_output == all outputs, we sum transform=.8 * np.ones( (1, model.dm_items.am.elem_output.size_out))) #model.dm_pairs = spa.AssociativeMemory(vocab_concepts, input_keys=list_of_pairs,wta_output=True) #nengo.Connection(model.dm_items.output,model.dm_pairs.input) #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=1) #connect input multiplier with higher motor area nengo.Connection(model.motor_input.output, model.motor.input, synapse=.1, transform=10) #finger area model.fingers = spa.AssociativeMemory( vocab_fingers, input_keys=['L1', 'L2', 'R1', 'R2'], wta_output=True) #conncetion between higher order area (hand, finger), to lower area nengo.Connection(model.motor.output, model.fingers.input, transform=.4 * motor_mapping) #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.3) #feedback #connection between finger area and finger position nengo.Connection(model.fingers.am.elem_output, model.finger_pos.input, transform=np.diag([0.55, .53, .57, .55])) #fix these model.bg = spa.BasalGanglia( spa.Actions( 'dot(goal,DO_TASK)-.5 --> dm_items=vis_pair, goal=RECOG, attend=ITEM1', 'dot(goal,RECOG)+dot(attend,ITEM1)+familiarity-2 --> goal=RECOG2, dm_items=vis_pair, attend=ITEM2', 'dot(goal,RECOG)+dot(attend,ITEM1)+(1-familiarity)-2 --> goal=RECOG2, attend=ITEM2', #motor_input=1.5*target_hand+MIDDLE, 'dot(goal,RECOG2)+dot(attend,ITEM2)+familiarity-1.3 --> goal=RESPOND, dm_items=vis_pair,motor_input=1.2*target_hand+INDEX, attend=ITEM2', 'dot(goal,RECOG2)+dot(attend,ITEM2)+(1-familiarity)-1.3 --> goal=RESPOND, motor_input=1.5*target_hand+MIDDLE, attend=ITEM2', 'dot(goal,RESPOND)+dot(motor,MIDDLE+INDEX)-1.4 --> goal=END', 'dot(goal,END) --> goal=END', #'.6 -->', )) 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_items = .8*concepts', #.5 #'dm_pairs = 2*stimulus' 'vis_pair = attend*concepts+concepts', )) #probes #model.pr_goal = nengo.Probe(model.goal.output,synapse=.01) #sample_every=.01 seconds, etc... 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) #model.pr_target = nengo.Probe(model.target_hand.output, synapse=.01) #input model.input = spa.Input( goal=lambda t: 'DO_TASK' if t < 0.05 else '0', target_hand=hand, #attend=lambda t: 'ITEM1' if t < 0.1 else 'ITEM2', )
# For managing control signals model.ctrl = spa.Memory(dimensions=D, tau=0.05) model.switch = spa.Memory(dimensions=D, vocab=signal_vocab, synapse=0.1, tau=0.15) # Main state representations model.m_goal = spa.Memory(dimensions=D, vocab=base_vocab) model.i_goal = spa.Memory(dimensions=D, vocab=base_vocab, synapse=0.005, tau=0.05) model.action = spa.Memory(dimensions=D, vocab=act_id_vocab, synapse=0.005, tau=0.03) model.effect = spa.Memory(dimensions=D, vocab=base_vocab, synapse=0.005, tau=0.05) model.precon = spa.Memory(dimensions=D, vocab=base_vocab, synapse=0.005, tau=0.05) model.location = spa.State(dimensions=D, vocab=base_vocab) # Associative Memories model.loc_to_object = spa.AssociativeMemory(input_vocab=obj_vocab, output_vocab=obj_id_vocab, input_keys=objects, output_keys=objects, wta_output=False, threshold=.5) model.obj_to_action = spa.AssociativeMemory(input_vocab=act_vocab, output_vocab=act_id_vocab, input_keys=actions, output_keys=actions, wta_output=True, threshold=.9) model.action_to_effect = spa.AssociativeMemory(input_vocab=act_id_vocab, output_vocab=base_vocab, input_keys=actions, output_keys=effects, wta_output=True) model.cleanup_action = spa.AssociativeMemory(act_id_vocab, threshold=0.15, wta_output=True) model.action_to_precon = AssociativeMemory(input_vectors=inp_vecs, output_vectors=out_vecs) nengo.Connection(model.location.output, model.loc_to_object.input, transform=base_vocab['LOCATION'].get_convolution_matrix())
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 model(self, p): model = spa.SPA() with model: model.shape = spa.Buffer(p.D) model.color = spa.Buffer(p.D) model.bound = spa.Buffer(p.D) cconv = nengo.networks.CircularConvolution(n_neurons=200, dimensions=p.D) nengo.Connection(model.shape.state.output, cconv.A) nengo.Connection(model.color.state.output, cconv.B) nengo.Connection(cconv.output, model.bound.state.input, transform=p.mem_input_scale, synapse=p.mem_tau) deconv = nengo.networks.CircularConvolution(n_neurons=200, dimensions=p.D, invert_b=True) deconv.label = 'deconv' model.query = spa.Buffer(p.D) model.result = spa.Buffer(p.D) nengo.Connection(model.bound.state.output, deconv.A) nengo.Connection(model.query.state.output, deconv.B) nengo.Connection(deconv.output, model.result.state.input, transform=2) nengo.Connection(model.bound.state.output, model.bound.state.input, synapse=p.mem_tau) vocab = model.get_output_vocab('result') model.cleanup = spa.AssociativeMemory([ vocab.parse('RED').v, vocab.parse('BLUE').v, vocab.parse('CIRCLE').v, vocab.parse('SQUARE').v ]) model.clean_result = spa.Buffer(p.D) nengo.Connection(model.result.state.output, model.cleanup.input) nengo.Connection(model.cleanup.output, model.clean_result.state.input) stim_time = p.mem_tau / p.mem_input_scale self.stim_time = stim_time def stim_color(t): if 0 < t < stim_time: return 'BLUE' elif stim_time < t < stim_time * 2: return 'RED' else: return '0' def stim_shape(t): if 0 < t < stim_time: return 'CIRCLE' elif stim_time < t < stim_time * 2: return 'SQUARE' else: return '0' def stim_query(t): if t < stim_time * 2: return '0' else: index = int((t - stim_time) / p.test_present_time) return ['BLUE', 'RED', 'CIRCLE', 'SQUARE'][index % 4] model.input = spa.Input( shape=stim_shape, color=stim_color, query=stim_query, ) self.probe = nengo.Probe(model.clean_result.state.output, synapse=0.02) self.probe_wm = nengo.Probe(model.bound.state.output, synapse=0.02) self.vocab = model.get_output_vocab('clean_result') self.vocab_wm = model.get_output_vocab('bound') return model
attend_vocab = spa.Vocabulary(D) attend_vocab.parse('W1+W2') # These are the two words to be presented words = ['C', 'B'] # both should be recognized; result is YES #words = ['H', 'B'] # the first is not recognized; result is NO #words = ['D', 'J'] # the second is not recognized; result is NO model = spa.SPA() with model: # the current word model.stim = spa.State(D, vocab=mem_vocab) # the recognition memory model.memory = spa.AssociativeMemory(mem_vocab, default_output_key='NONE', threshold=0.3) nengo.Connection(model.stim.output, model.memory.input) # this stores the accumulated evidence for or against recognition model.evidence = spa.State(1, feedback=1, feedback_synapse=0.1) # this scaling factor controls how quickly we accumulate evidence evidence_scale = 0.3 nengo.Connection(model.memory.am.ensembles[-1], model.evidence.input, transform=-evidence_scale) nengo.Connection(model.memory.am.elem_output, model.evidence.input, transform=evidence_scale * np.ones(
#model.env = nengo.Node(Environment(vocab=vocab, time_interval=time_interval), size_in=DIM, size_out=DIM) model.env = nengo.Node(Agent(vocab=vocab, time_interval=time_interval), size_in=2, size_out=DIM * 3) model.state = spa.State(DIM, vocab=vocab) model.action = spa.State(DIM, vocab=vocab) #model.probability = spa.State(DIM, vocab=vocab) with cfg: model.probability_left = spa.State(DIM, vocab=vocab) model.probability_right = spa.State(DIM, vocab=vocab) model.state_ensemble = nengo.Ensemble(n_neurons=DIM * 50, dimensions=DIM) model.assoc_mem_left = spa.AssociativeMemory(input_vocab=vocab, output_vocab=vocab, input_keys=input_keys_left, output_keys=output_keys_left, wta_output=True, threshold_output=True) model.assoc_mem_right = spa.AssociativeMemory( input_vocab=vocab, output_vocab=vocab, input_keys=input_keys_right, output_keys=output_keys_right, wta_output=True, threshold_output=True) nengo.Connection(model.env[DIM:DIM * 2], model.assoc_mem_left.input) nengo.Connection(model.assoc_mem_left.output, model.probability_left.input) nengo.Connection(model.env[DIM:DIM * 2], model.assoc_mem_right.input) nengo.Connection(model.assoc_mem_right.output, model.probability_right.input)
def generate(input_signal, alpha=1000.0): beta = alpha / 4.0 # Read in the class mean for numbers from vision network weights_data = np.load('models/mnist_vision_data/params.npz') weights = weights_data['Wc'] means_data = np.load('models/mnist_vision_data/class_means.npz') means = np.matrix(1.0 / means_data['means']) sps = np.multiply(weights.T, means.T)[:10] sps_labels = [ 'ZERO', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE'] dimensions = weights.shape[0] # generate the Function Space forces, _, _ = forcing_functions.load_folder( 'models/handwriting_trajectories', rhythmic=True, alpha=alpha, beta=beta) # make an array out of all the possible functions we want to represent force_space = np.vstack(forces) # use this array as our space to perform svd over fs = nengo.FunctionSpace(space=force_space, n_basis=10) # store the weights for each trajectory weights_x = [] weights_y = [] for ii in range(len(forces)): forces = force_space[ii*2:ii*2+2] # load up the forces to be output by the forcing function # calculate the corresponding weights over the basis functions weights_x.append(np.dot(fs.basis.T, forces[0])) weights_y.append(np.dot(fs.basis.T, forces[1])) # Create our vocabularies rng = np.random.RandomState(0) vocab_vision = Vocabulary(dimensions=dimensions, rng=rng) vocab_dmp_weights_x = Vocabulary(dimensions=fs.n_basis, rng=rng) vocab_dmp_weights_y = Vocabulary(dimensions=fs.n_basis, rng=rng) for label, sp, wx, wy in zip( sps_labels, sps, weights_x, weights_y): vocab_vision.add( label, np.array(sp)[0] / np.linalg.norm(np.array(sp)[0])) vocab_dmp_weights_x.add(label, wx) vocab_dmp_weights_y.add(label, wy) net = spa.SPA() # net.config[nengo.Ensemble].neuron_type = nengo.Direct() with net: # --------------------- Inputs -------------------------- # def input_func(t): # return vocab_vision.parse(input_signal).v # net.input = nengo.Node(input_func, label='input') net.input = spa.State(dimensions, subdimensions=10, vocab=vocab_vision) number = nengo.Node(output=[0], label='number') # ------------------- Point Attractors -------------------- net.x = point_attractor.generate( n_neurons=1000, alpha=alpha, beta=beta) net.y = point_attractor.generate( n_neurons=1000, alpha=alpha, beta=beta) # -------------------- Oscillators ---------------------- kick = nengo.Node(nengo.utils.functions.piecewise({0: 1, .05: 0}), label='kick') osc = oscillator.generate(net, n_neurons=2000, speed=.05) osc.label = 'oscillator' nengo.Connection(kick, osc[0]) # ------------------- Forcing Functions -------------------- net.assoc_mem_x = spa.AssociativeMemory( input_vocab=vocab_vision, output_vocab=vocab_dmp_weights_x, wta_output=False) nengo.Connection(net.input.output, net.assoc_mem_x.input) net.assoc_mem_y = spa.AssociativeMemory( input_vocab=vocab_vision, output_vocab=vocab_dmp_weights_y, wta_output=False) nengo.Connection(net.input.output, net.assoc_mem_y.input) # -------------------- Product for decoding ----------------------- net.product_x = nengo.Network('Product X') nengo.networks.Product(n_neurons=1000, dimensions=fs.n_basis, net=net.product_x, input_magnitude=1.0) net.product_y = nengo.Network('Product Y') nengo.networks.Product(n_neurons=1000, dimensions=fs.n_basis, net=net.product_y, input_magnitude=1.0) # get the largest basis function value for normalization max_basis = np.max(fs.basis*fs.scale) domain = np.linspace(-np.pi, np.pi, fs.basis.shape[0]) domain_cossin = np.array([np.cos(domain), np.sin(domain)]).T for ff, product in zip([net.assoc_mem_x.output, net.assoc_mem_y.output], [net.product_x, net.product_y]): for ii in range(fs.n_basis): # find the value of a basis function at a value of (x, y) target_function = nengo.utils.connection.target_function( domain_cossin, fs.basis[:, ii]*fs.scale/max_basis) nengo.Connection(osc, product.B[ii], **target_function) # multiply the value of each basis function at x by its weight nengo.Connection(ff, product.A) nengo.Connection(net.product_x.output, net.x.input[1], transform=np.ones((1, fs.n_basis)) * max_basis, synapse=None) nengo.Connection(net.product_y.output, net.y.input[1], transform=np.ones((1, fs.n_basis)) * max_basis, synapse=None) # -------------------- Output ------------------------------ net.output = nengo.Node(size_in=2, label='output') nengo.Connection(net.x.output, net.output[0]) nengo.Connection(net.y.output, net.output[1]) # create a node to give a plot of the represented function ff_plot = fs.make_plot_node(domain=domain, lines=2, ylim=[-1000000, 1000000]) nengo.Connection(net.assoc_mem_x.output, ff_plot[:fs.n_basis], synapse=0.1) nengo.Connection(net.assoc_mem_y.output, ff_plot[fs.n_basis:], synapse=0.1) return net
def generate(input_signal, alpha=1000.0): beta = alpha / 4.0 # generate the Function Space forces, _, goals = forcing_functions.load_folder( 'models/locomotion_trajectories', rhythmic=True, alpha=alpha, beta=beta) # make an array out of all the possible functions we want to represent force_space = np.vstack(forces) # use this array as our space to perform svd over fs = nengo.FunctionSpace(space=force_space, n_basis=10) # store the weights for each movement weights_a = [] # ankle weights_k = [] # knee weights_h = [] # hip # NOTE: things are added to weights based on the order files are read for ii in range(int(len(goals) / 6)): forces = force_space[ii * 6:ii * 6 + 6] # load up the forces to be output by the forcing function # calculate the corresponding weights over the basis functions weights_a.append( np.hstack([ np.dot(fs.basis.T, forces[0]), # ankle 1 np.dot(fs.basis.T, forces[1]) ])) # ankle 2 weights_h.append( np.hstack([ np.dot(fs.basis.T, forces[2]), # hip 1 np.dot(fs.basis.T, forces[3]) ])) # hip 2 weights_k.append( np.hstack([ np.dot(fs.basis.T, forces[4]), # knee 1 np.dot(fs.basis.T, forces[5]) ])) # knee 2 # Create our vocabularies sps_labels = ['GALLOP', 'RUNNING', 'WALKING'] rng = np.random.RandomState(0) dimensions = 50 # some arbitrary number vocab_input = Vocabulary(dimensions=dimensions, rng=rng) vocab_dmp_weights_a = Vocabulary(dimensions=fs.n_basis * 2, rng=rng) vocab_dmp_weights_k = Vocabulary(dimensions=fs.n_basis * 2, rng=rng) vocab_dmp_weights_h = Vocabulary(dimensions=fs.n_basis * 2, rng=rng) for ii, (label, wa, wk, wh) in enumerate(zip(sps_labels, weights_a, weights_k, weights_h)): vocab_input.parse(label) # randomly generate input vector vocab_dmp_weights_a.add(label, wa) vocab_dmp_weights_k.add(label, wk) vocab_dmp_weights_h.add(label, wh) net = spa.SPA() net.config[nengo.Ensemble].neuron_type = nengo.LIFRate() with net: config = nengo.Config(nengo.Ensemble) config[nengo.Ensemble].neuron_type = nengo.Direct() with config: # --------------------- Inputs -------------------------- # def input_func(t): # return vocab_input.parse(input_signal).v # net.input = nengo.Node(input_func) net.input = spa.State(dimensions, subdimensions=10, vocab=vocab_input) # ------------------- Point Attractors -------------------- zero = nengo.Node([0]) net.a1 = point_attractor.generate(n_neurons=1000, alpha=alpha, beta=beta) nengo.Connection(zero, net.a1.input[0], synapse=None) net.a2 = point_attractor.generate(n_neurons=1000, alpha=alpha, beta=beta) nengo.Connection(zero, net.a1.input[0], synapse=None) net.k1 = point_attractor.generate(n_neurons=1000, alpha=alpha, beta=beta) nengo.Connection(zero, net.k1.input[0], synapse=None) net.k2 = point_attractor.generate(n_neurons=1000, alpha=alpha, beta=beta) nengo.Connection(zero, net.k2.input[0], synapse=None) net.h1 = point_attractor.generate(n_neurons=1000, alpha=alpha, beta=beta) nengo.Connection(zero, net.h1.input[0], synapse=None) net.h2 = point_attractor.generate(n_neurons=1000, alpha=alpha, beta=beta) nengo.Connection(zero, net.h2.input[0], synapse=None) # -------------------- Oscillators ---------------------- kick = nengo.Node(nengo.utils.functions.piecewise({ 0: 1, .05: 0 }), label='kick') osc = oscillator.generate(net, n_neurons=3000, speed=.01) osc.label = 'oscillator' nengo.Connection(kick, osc[0]) # ------------------- Forcing Functions -------------------- with config: net.assoc_mem_a = spa.AssociativeMemory( input_vocab=vocab_input, output_vocab=vocab_dmp_weights_a, wta_output=False) nengo.Connection(net.input.output, net.assoc_mem_a.input) net.assoc_mem_k = spa.AssociativeMemory( input_vocab=vocab_input, output_vocab=vocab_dmp_weights_k, wta_output=False) nengo.Connection(net.input.output, net.assoc_mem_k.input) net.assoc_mem_h = spa.AssociativeMemory( input_vocab=vocab_input, output_vocab=vocab_dmp_weights_h, wta_output=False) nengo.Connection(net.input.output, net.assoc_mem_h.input) # -------------------- Product for decoding ----------------------- product_a1 = nengo.Network('Product A1') nengo.networks.Product(n_neurons=1000, dimensions=fs.n_basis, net=product_a1) product_a2 = nengo.Network('Product A2') nengo.networks.Product(n_neurons=1000, dimensions=fs.n_basis, net=product_a2) product_h1 = nengo.Network('Product H1') nengo.networks.Product(n_neurons=1000, dimensions=fs.n_basis, net=product_h1) product_h2 = nengo.Network('Product H2') nengo.networks.Product(n_neurons=1000, dimensions=fs.n_basis, net=product_h2) product_k1 = nengo.Network('Product K1') nengo.networks.Product(n_neurons=1000, dimensions=fs.n_basis, net=product_k1) product_k2 = nengo.Network('Product K2') nengo.networks.Product(n_neurons=1000, dimensions=fs.n_basis, net=product_k2) # get the largest basis function value for normalization max_basis = np.max(fs.basis * fs.scale) domain = np.linspace(-np.pi, np.pi, fs.basis.shape[0]) domain_cossin = np.array([np.cos(domain), np.sin(domain)]).T for ff, product in zip([ net.assoc_mem_a.output[:fs.n_basis], net.assoc_mem_a.output[fs.n_basis:], net.assoc_mem_k.output[:fs.n_basis], net.assoc_mem_k.output[fs.n_basis:], net.assoc_mem_h.output[:fs.n_basis], net.assoc_mem_h.output[fs.n_basis:] ], [ product_a1, product_a2, product_k1, product_k2, product_h1, product_h2 ]): for ii in range(fs.n_basis): # find the value of a basis function at a value of (x, y) target_function = nengo.utils.connection.target_function( domain_cossin, fs.basis[:, ii] * fs.scale / max_basis) nengo.Connection(osc, product.B[ii], **target_function) # multiply the value of each basis function at x by its weight nengo.Connection(ff, product.A) nengo.Connection(product_a1.output, net.a1.input[1], transform=np.ones((1, fs.n_basis)) * max_basis) nengo.Connection(product_a2.output, net.a2.input[1], transform=np.ones((1, fs.n_basis)) * max_basis) nengo.Connection(product_k1.output, net.k1.input[1], transform=np.ones((1, fs.n_basis)) * max_basis) nengo.Connection(product_k2.output, net.k2.input[1], transform=np.ones((1, fs.n_basis)) * max_basis) nengo.Connection(product_h1.output, net.h1.input[1], transform=np.ones((1, fs.n_basis)) * max_basis) nengo.Connection(product_h2.output, net.h2.input[1], transform=np.ones((1, fs.n_basis)) * max_basis) # -------------------- Output ------------------------------ net.output = nengo.Node(size_in=6, label='output') nengo.Connection(net.a1.output, net.output[0], synapse=0.01) nengo.Connection(net.a2.output, net.output[1], synapse=0.01) nengo.Connection(net.k1.output, net.output[2], synapse=0.01) nengo.Connection(net.k2.output, net.output[3], synapse=0.01) nengo.Connection(net.h1.output, net.output[4], synapse=0.01) nengo.Connection(net.h2.output, net.output[5], synapse=0.01) # add in the goal offsets nengo.Connection(net.assoc_mem_a.output[[-2, -1]], net.output[[0, 1]], synapse=None) nengo.Connection(net.assoc_mem_k.output[[-2, -1]], net.output[[2, 3]], synapse=None) nengo.Connection(net.assoc_mem_h.output[[-2, -1]], net.output[[4, 5]], synapse=None) # create a node to give a plot of the represented function ff_plot_a = fs.make_plot_node(domain=domain, lines=2, ylim=[-1000000, 1000000]) nengo.Connection(net.assoc_mem_a.output, ff_plot_a, synapse=0.1) ff_plot_k = fs.make_plot_node(domain=domain, lines=2, ylim=[-1000000, 1000000]) nengo.Connection(net.assoc_mem_k.output, ff_plot_k, synapse=0.1) ff_plot_h = fs.make_plot_node(domain=domain, lines=2, ylim=[-1000000, 1000000]) nengo.Connection(net.assoc_mem_h.output, ff_plot_h, synapse=0.1) return net
def SyllableSequence(n_per_d, syllable_d, syllables, difference_gain=15, n_positions=7, threshold_memories=True, add_default_output=True, rng=np.random, net=None): if net is None: net = spa.SPA("Syllable sequence") assert isinstance(net, spa.SPA), "Network must be a SPA instance." vocab = spa.Vocabulary(dimensions=syllable_d, rng=rng, unitary=['INC', 'POS1']) vocab.parse('INC + POS1') for i in range(2, n_positions+1): vocab.add('POS%d' % i, vocab.parse('POS%d * INC' % (i-1))) vocab.parse(" + ".join(syllables)) syll_vocab = vocab.create_subset(syllables) net.vocab = vocab with net: # --- Input sequence net.sequence = spa.State(dimensions=syllable_d, neurons_per_dimension=n_per_d) # --- Input gated memories iterate through position vectors net.pos_curr = InputGatedMemory( n_per_d, dimensions=syllable_d, difference_gain=difference_gain) net.pos_next = InputGatedMemory( n_per_d, dimensions=syllable_d, difference_gain=difference_gain) # Switch from current to next with reciprocal connections nengo.Connection(net.pos_curr.output, net.pos_next.input) nengo.Connection(net.pos_next.output, net.pos_curr.input, transform=vocab['INC'].get_convolution_matrix()) # Switching depends on gate; get gate input elsewhere net.gate = nengo.Node(size_in=1) # pos gets gate nengo.Connection(net.gate, net.pos_curr.gate, synapse=None) # pos_next gets 1 - gate net.gate_bias = nengo.Node(output=1) nengo.Connection(net.gate_bias, net.pos_next.gate, synapse=None) nengo.Connection(net.gate, net.pos_next.gate, transform=-1, synapse=None) # --- Get syllables with unbinding net.bind = CircularConvolution( n_per_d, syllable_d, invert_a=False, invert_b=True) net.bind_next = CircularConvolution( n_per_d, syllable_d, invert_a=False, invert_b=True) nengo.Connection(net.sequence.output, net.bind.A) nengo.Connection(net.sequence.output, net.bind_next.A) nengo.Connection(net.pos_curr.output, net.bind.B) nengo.Connection(net.pos_next.output, net.bind_next.B, transform=vocab['INC'].get_convolution_matrix()) # --- Clean up noisy syllables with associative memories net.syllable = spa.AssociativeMemory( syll_vocab, wta_output=True, threshold_output=threshold_memories) net.syllable_next = spa.AssociativeMemory( syll_vocab, wta_output=True, threshold_output=threshold_memories) nengo.Connection(net.bind.output, net.syllable.input) nengo.Connection(net.bind_next.output, net.syllable_next.input) if add_default_output: default = np.zeros(syllable_d) net.syllable.am.add_default_output_vector(default) net.syllable_next.am.add_default_output_vector(default) return net
model = spa.SPA() with model: # the cue word model.cue = spa.State(D, vocab=vocab) # general working memory model.wm = spa.State(D, feedback=1, vocab=vocab) nengo.Connection(model.cue.output, model.wm.input, transform=make_memory(vocab, memory) * 0.5, synapse=0.1) # the one currently active word model.terms = spa.AssociativeMemory(input_vocab=vocab, wta_output=True, threshold=0.7) # use the working memory to trigger a word nengo.Connection(model.wm.output, model.terms.input, synapse=0.1) # have the triggered word inhibit itself in working memory nengo.Connection(model.terms.output, model.wm.input, synapse=0.1, transform=-2) # have the triggered word be a bit more stable (so it doesn't # disappear instantly) nengo.Connection(model.terms.output, model.terms.input, synapse=0.1, transform=0.5)
input_keys = ['S0*L', 'S0*R', 'S1*L', 'S1*R', 'S2*L', 'S2*R'] output_keys = ['0.7*S1 + 0.3*S2', '0.3*S1 + 0.7*S2', 'S0', 'S0', 'S0', 'S0'] vocab = spa.Vocabulary(dimensions=DIM) # TODO: these vectors might need to be chosen in a smarter way for sp in states+actions: vocab.parse(sp) model = nengo.Network('RL', seed=13) with model: model.assoc_mem = spa.AssociativeMemory(input_vocab=vocab, output_vocab=vocab, input_keys=input_keys, output_keys=output_keys, wta_output=True, threshold_output=True ) model.state = spa.State(DIM, vocab=vocab) model.action = spa.State(DIM, vocab=vocab) model.probability = spa.State(DIM, vocab=vocab) # State and selected action convolved together #model.state_and_action = spa.State(DIM, vocab=vocab) model.cconv = nengo.networks.CircularConvolution(300, DIM) nengo.Connection(model.state.output, model.cconv.A) nengo.Connection(model.action.output, model.cconv.B)
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(), 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) # pair 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. #learned words model.dm_learned_words = spa.AssociativeMemory( vocab_learned_words, threshold=.2 ) #default_output_key='NONE' familiarity should be continuous over all items, so no wta nengo.Connection(model.dm_learned_words.output, model.dm_learned_words.input, transform=.4, synapse=.02) # this stores the accumulated evidence for or against familiarity 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 #nengo.Connection(model.dm_learned_words.am.ensembles[-1], model.familiarity.input, transform=-(familiarity_scale+0.8)) #accumulate to -1 nengo.Connection( model.dm_learned_words.am.elem_output, model.familiarity.input, #am.element_output == all outputs, we sum transform=(familiarity_scale + .1) * np.ones( (1, model.dm_learned_words.am.elem_output.size_out)) ) #accumulate to 1 model.do_fam = spa.AssociativeMemory(vocab_reset, default_output_key='CLEAR', threshold=.2) 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) #negative accumulator nengo.Connection( model.do_fam.am.elem_output, model.familiarity.input, transform=-familiarity_scale * np.ones( (1, model.do_fam.am.elem_output.size_out))) #accumulate to -1 #fam model.dm_pairs = spa.AssociativeMemory(vocab_learned_pairs, input_keys=list_of_pairs,wta_output=True) #fam nengo.Connection(model.dm_pairs.output,model.dm_pairs.input,transform=.5) #this works: #fam model.representation = spa.AssociativeMemory(vocab_learned_pairs, input_keys=list_of_pairs, wta_output=True) #fam nengo.Connection(model.representation.output, model.representation.input, transform=2) #fam model.rep_filled = spa.State(1,feedback_synapse=.005) #no fb syn specified #fam nengo.Connection(model.representation.am.elem_output,model.rep_filled.input, #am.element_output == all outputs, we sum #fam transform=.8*np.ones((1,model.representation.am.elem_output.size_out)),synapse=0) #this doesn't: #model.representation = spa.State(D,feedback=1) #model.rep_filled = spa.State(1,feedback_synapse=.005) #no fb syn specified #nengo.Connection(model.representation.output,model.rep_filled.input, #am.element_output == all outputs, we sum # transform=.8*np.ones((1,model.representation.output.size_out)),synapse=0) # this shouldn't really be fixed I think #fam model.comparison = spa.Compare(D, vocab=vocab_concepts) #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) - .1 --> 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_judge_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_judge_familiarity= 'dot(goal,FAMILIARITY) - .1 --> goal=FAMILIARITY, 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, do_fam=GO, motor_input=1.6*(target_hand+MIDDLE)', h_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)', x_response_done= '1.1*dot(goal,RESPOND) + 1.5*dot(fingers,L1+L2+R1+R2) - .7--> goal=2*END', y_end='dot(goal,END)-.1 --> goal=END', z_threshold='.05 --> goal=0' #possible to match complete buffer, ie is representation filled? # motor_input=1.5*target_hand+MIDDLE, )) #'dot(attention, W1) - evidence - 0.8 --> motor=NO, attention=W1', #'dot(attention, W1) + evidence - 0.8 --> attention=W2, reset=EVIDENCE', #'dot(attention, W1) --> attention=W1', # if we don't set attention it goes back to 0 #'dot(attention, W2) - evidence - 0.8 --> motor=NO, attention=W2', #'dot(attention, W2) + evidence - 0.8 --> motor=YES, attention=W2', #'dot(attention, W2) --> attention=W2', # option might be feedback on attention, then no rule 3/6 but default rule 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 and False: 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, 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 = ''
#load_from = "test", ) model.mem.mem.create_weight_probes() #save weights nengo.Connection(model.in_layer.output, model.mem.input, synapse=None) nengo.Connection(model.correct.output, model.mem.correct, synapse=None) nengo.Connection(model.stoplearn, model.mem.mem.stop_pes) #feedback for mem inputs 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)
def make_motor_system(input_items, action_items, motor_feedback=0, motor_transform=10, finger_feedback=0.3, motor_to_fingers_strength=0.4): motor_vocab = spa.Vocabulary(D) for item in range(len(input_items)): motor_vocab.parse(input_items[item]) finger_vocab = spa.Vocabulary(D) for item in range(len(action_items)): finger_vocab.parse(action_items[item]) motor_mapping = np.zeros((D, D)) for item in range(len(input_items)): motor_mapping += np.outer( motor_vocab.parse(input_items[item]).v, finger_vocab.parse(action_items[item]).v).T motor_system = nengo.Network(label='motor_system') with motor_system: #input multiplier motor_input = spa.State(D, vocab=motor_vocab, label='motor_input') #higher motor area (SMA?) motor = spa.State(D, vocab=motor_vocab, feedback=motor_feedback, label='motor') # This thing has memory #connect input multiplier with higher motor area nengo.Connection(motor_input.output, motor.input, synapse=0.01, transform=motor_transform) #finger area fingers = spa.AssociativeMemory(finger_vocab, input_keys=action_items, wta_output=True, label='fingers') #conncetion between higher order area (hand, finger), to lower area (the actual motor mapping of the fingers) nengo.Connection(motor.output, fingers.input, transform=motor_to_fingers_strength * motor_mapping) #finger position - mapping to the actual finger movements! finger_pos = nengo.networks.EnsembleArray(n_neurons=50, n_ensembles=len(input_items), label='finger_pos') nengo.Connection(finger_pos.output, finger_pos.input, synapse=0.1, transform=finger_feedback) #feedback #connection between finger area and finger position nengo.Connection(fingers.am.elem_output, finger_pos.input, transform=finger_strength) #fixed values, ideally #make things accessable motor_system.fingers = fingers motor_system.motor_input = motor_input motor_system.finger_pos = finger_pos motor_system.motor_vocab = motor_vocab motor_system.motor = motor motor_system.finger_vocab = finger_vocab return motor_system
nengo.Connection(is_cooldown, activate_cooldown[1]) nengo.Connection(is_no_corridor, activate_cooldown[2]) ### COLOUR COUNTING SYSTEM ### # Create node thatreturns the colour of the cell currently occupied current_color = nengo.Node(lambda t: body.cell.cellcolor) # Create a memory to remember which colours the agent has seen (add small feedback so it doesn't forget) model.colour_memory = spa.State(D, vocab=colour_vocab, feedback=0.5) model.colour_memory.output.output = lambda t, x: x nengo.Connection(current_color, model.colour_memory.input, function=recognise_colour) # Add an associative memory to further reinforce remembering # (wta_output=False because we want to remember multiple things at once) model.cleanup = spa.AssociativeMemory(input_vocab=colour_vocab, wta_output=False) nengo.Connection(model.cleanup.output, model.colour_memory.input, synapse=0.05) nengo.Connection(model.colour_memory.output, model.cleanup.input, synapse=0.05) # Create a colour counter that keeps track of the number of colours we have seen, based on the memory # There are 5 colours, so radius=5 colour_counter = nengo.Ensemble(N, dimensions=1, radius=5) nengo.Connection(model.colour_memory.output, colour_counter, function=count_colours_from_memory) # Create node for user to input the desired amount of colours to find
def get_model(q_scaling=1, direct=False, p_learning=True): model = nengo.Network('RL P-learning', seed=13) #if direct: # model.config[nengo.Ensemble].neuron_type = nengo.Direct() if direct: learning = False #TEMP FIXME if not learning: model.config[nengo.Ensemble].neuron_type = nengo.Direct() neuron_type = nengo.Direct() else: learning = True #TEMP FIXME neuron_type = nengo.LIF() if p_learning: """ raise NotImplementedError with model: # Model of the external environment # Input: action semantic pointer # Output: current state semantic pointer #model.env = nengo.Node(Environment(vocab=vocab, time_interval=time_interval), size_in=DIM, size_out=DIM) agent = Agent(vocab=vocab, time_interval=time_interval, q_scaling=q_scaling) model.env = nengo.Node(agent, size_in=1, size_out=DIM*3) model.state = spa.State(DIM, vocab=vocab) model.action = spa.State(DIM, vocab=vocab) model.probability = spa.State(DIM, vocab=vocab) # State and selected action in one ensemble model.state_and_action = nengo.Ensemble(n_neurons=n_sa_neurons, dimensions=DIM*2, intercepts=AreaIntercepts(dimensions=DIM*2)) #model.cconv = nengo.networks.CircularConvolution(300, DIM) nengo.Connection(model.state.output, model.state_and_action[:DIM]) nengo.Connection(model.env[:DIM], model.state_and_action[DIM:]) conn = nengo.Connection(model.state_and_action, model.probability.input, function=lambda x: [0]*DIM, learning_rule_type=nengo.PES(pre_synapse=z**(-int(time_interval*1000))), ) # Semantic pointer for the Q values of each state # In the form of q0*S0 + q1*S1 + q2*S2 model.q = spa.State(DIM, vocab=vocab) # Scalar reward value from the dot product of P and Q model.reward = nengo.Ensemble(100, 1, neuron_type=neuron_type) #TODO: figure out what the result of P.Q is used for model.prod = nengo.networks.Product(n_neurons=n_prod_neurons, dimensions=DIM) nengo.Connection(model.probability.output, model.prod.A) #nengo.Connection(model.q.output, model.prod.B) nengo.Connection(model.env[DIM*2:], model.prod.B) nengo.Connection(model.prod.output, model.reward, transform=np.ones((1,DIM))) #TODO: doublecheck that this is the correct way to connect things nengo.Connection(model.env[DIM:DIM*2], model.state.input) #TODO: need to set up error signal and handle timing model.error = spa.State(DIM, vocab=vocab) nengo.Connection(model.error.output, conn.learning_rule) #TODO: figure out which way the sign goes, one should be negative, and the other positive #TODO: figure out how to delay by one "time-step" correctly nengo.Connection(model.state.output, model.error.input, transform=-1) nengo.Connection(model.probability.output, model.error.input, transform=1, synapse=z**(-int(time_interval*1000))) #synapse=nengolib.synapses.PureDelay(500)) #500ms delay # Testing the delay synapse to make sure it works as expected model.state_delay_test = spa.State(DIM, vocab=vocab) nengo.Connection(model.state.output, model.state_delay_test.input, synapse=z**(-int(time_interval*1000))) nengo.Connection(model.reward, model.env) nengo.Connection(model.env[:DIM], model.action.input) # Purely for plotting nengo.Connection(model.env[DIM*2:], model.q.input) # Purely for plotting return model, agent """ with model: cfg = nengo.Config(nengo.Ensemble) cfg[nengo.Ensemble].neuron_type = neuron_type # Model of the external environment agent = AgentSplit(vocab=vocab, time_interval=time_interval, q_scaling=q_scaling) model.env = nengo.Node(agent, size_in=1, size_out=DIM*4) with cfg: model.state = spa.State(DIM, vocab=vocab) model.action = spa.State(DIM, vocab=vocab) model.probability = spa.State(DIM, vocab=vocab) # The action that is currently being used along with the state to calculate value # If this matches with the actual action being taken, learning will happen (on the next step after a delay) model.calculating_action = spa.State(DIM, vocab=vocab) nengo.Connection(model.env[DIM*3:DIM*4], model.calculating_action.input) # State and selected action in one ensemble model.state_and_action = nengo.Ensemble(n_neurons=n_sa_neurons, dimensions=DIM*2, intercepts=AreaIntercepts(dimensions=DIM*2)) #model.cconv = nengo.networks.CircularConvolution(300, DIM) nengo.Connection(model.state.output, model.state_and_action[:DIM]) nengo.Connection(model.env[DIM*3:DIM*4], model.state_and_action[DIM:]) if learning: conn = nengo.Connection(model.state_and_action, model.probability.input, function=lambda x: [0]*DIM, learning_rule_type=nengo.PES(pre_synapse=z**(-int(time_interval*2*1000))), ) else: nengo.Connection(model.state_and_action, model.probability.input, function=correct_mapping) # Scalar value from the dot product of P and Q model.value = nengo.Ensemble(100, 1, neuron_type=nengo.Direct()) with cfg: # Semantic pointer for the Q values of each state # In the form of q0*S0 + q1*S1 + q2*S2 model.q = spa.State(DIM, vocab=vocab) model.prod = nengo.networks.Product(n_neurons=n_prod_neurons, dimensions=DIM) nengo.Connection(model.probability.output, model.prod.A) #nengo.Connection(model.q.output, model.prod.B) nengo.Connection(model.env[DIM*2:DIM*3], model.prod.B) nengo.Connection(model.prod.output, model.value, transform=np.ones((1,DIM))) #TODO: doublecheck that this is the correct way to connect things nengo.Connection(model.env[DIM:DIM*2], model.state.input) #TODO: need to set up error signal and handle timing model.error = spa.State(DIM, vocab=vocab) ##nengo.Connection(model.error.output, conn.learning_rule) model.error_node = nengo.Node(selected_error,size_in=DIM*3, size_out=DIM) nengo.Connection(model.error.output, model.error_node[:DIM]) nengo.Connection(model.action.output, model.error_node[DIM:DIM*2]) nengo.Connection(model.calculating_action.output, model.error_node[DIM*2:DIM*3]) if learning: nengo.Connection(model.error_node, conn.learning_rule) #TODO: figure out which way the sign goes, one should be negative, and the other positive #TODO: figure out how to delay by one "time-step" correctly nengo.Connection(model.state.output, model.error.input, transform=-1) nengo.Connection(model.probability.output, model.error.input, transform=1, synapse=z**(-int(time_interval*2*1000))) #synapse=nengolib.synapses.PureDelay(500)) #500ms delay # Testing the delay synapse to make sure it works as expected model.state_delay_test = spa.State(DIM, vocab=vocab) nengo.Connection(model.state.output, model.state_delay_test.input, synapse=z**(-int(time_interval*2*1000))) nengo.Connection(model.value, model.env) #nengo.Connection(model.env[:DIM], model.action.input) # Purely for plotting #nengo.Connection(model.env[DIM*2:DIM*3], model.q.input) # Purely for plotting return model, agent else: if direct: neuron_type = nengo.Direct() else: neuron_type = nengo.LIF() with model: agent = Agent(vocab=vocab, time_interval=time_interval, q_scaling=q_scaling) model.env = nengo.Node(agent, size_in=2, size_out=DIM*3) model.state = spa.State(DIM, vocab=vocab) model.action = spa.State(DIM, vocab=vocab) cfg = nengo.Config(nengo.Ensemble) cfg[nengo.Ensemble].neuron_type = neuron_type with cfg: model.probability_left = spa.State(DIM, vocab=vocab) model.probability_right = spa.State(DIM, vocab=vocab) model.state_ensemble = nengo.Ensemble(n_neurons=DIM*50,dimensions=DIM) model.assoc_mem_left = spa.AssociativeMemory(input_vocab=vocab, output_vocab=vocab, input_keys=input_keys_left, output_keys=output_keys_left, wta_output=True, threshold_output=True ) model.assoc_mem_right = spa.AssociativeMemory(input_vocab=vocab, output_vocab=vocab, input_keys=input_keys_right, output_keys=output_keys_right, wta_output=True, threshold_output=True ) nengo.Connection(model.env[DIM:DIM*2], model.assoc_mem_left.input) nengo.Connection(model.assoc_mem_left.output, model.probability_left.input) nengo.Connection(model.env[DIM:DIM*2], model.assoc_mem_right.input) nengo.Connection(model.assoc_mem_right.output, model.probability_right.input) # Semantic pointer for the Q values of each state # In the form of q0*S0 + q1*S1 + q2*S2 model.q = spa.State(DIM, vocab=vocab) # Scalar reward value from the dot product of P and Q #model.value = nengo.Ensemble(200, 2, neuron_type=neuron_type) model.value = nengo.Ensemble(200, 2, neuron_type=nengo.Direct()) with cfg: model.prod_left = nengo.networks.Product(n_neurons=50*DIM, dimensions=DIM) model.prod_right = nengo.networks.Product(n_neurons=50*DIM, dimensions=DIM) nengo.Connection(model.probability_left.output, model.prod_left.A) nengo.Connection(model.env[DIM*2:], model.prod_left.B) nengo.Connection(model.probability_right.output, model.prod_right.A) nengo.Connection(model.env[DIM*2:], model.prod_right.B) nengo.Connection(model.prod_left.output, model.value[0], transform=np.ones((1,DIM))) nengo.Connection(model.prod_right.output, model.value[1], transform=np.ones((1,DIM))) nengo.Connection(model.value, model.env) nengo.Connection(model.env[:DIM], model.action.input) # Purely for plotting nengo.Connection(model.env[DIM*2:], model.q.input) # Purely for plotting nengo.Connection(model.env[DIM:DIM*2], model.state.input) return model, agent