Hi - I tried to address with using neuronal assemblies borrowing heavily from the AssociativeMemory Learning example.
- I want the model to learn associations between car model and car company, and then car company and country of production.
- Neuronal assemblies learn these mappings.
- The assemblies learn the associations between 4 models and 2 companies, and then between 3 companies and 2 countries.
- Learning for these associations occur in separate stages (1st 2 seconds and then 6.5 to 8 sec)
- A gate blocks the flow of information between the 1st and 2nd association until learning is complete. The gate is controlled by BG-thal.
This model accomplishes what I wanted the spa.AssociativeObject to do. My goal is trying to understand how semantic memory is chunked. Code written for the gui is below.
import numpy as np
import nengo
import nengo.spa as spa
D = 32
num_items = 5
rng = np.random.RandomState(seed=7)
intercept = 0.08
# Model constants
n_neurons = 2000
dt = 0.001
period = 0.4
T = period*num_items*2
# Model network
model = spa.SPA()
with model:
model.vocab = spa.Vocabulary(D)
RAV4 = model.vocab.parse('RAV4')
CAMRY = model.vocab.parse('CAMRY')
COROLLA = model.vocab.parse('COROLLA')
ACCORD = model.vocab.parse('ACCORD')
TOYOTA = model.vocab.parse('TOYOTA')
HONDA = model.vocab.parse('HONDA')
JAPAN = model.vocab.parse('JAPAN')
KOREA = model.vocab.parse('KOREA')
CLOSED = model.vocab.parse('CLOSED')
OPEN = model.vocab.parse('OPEN')
def car_model_input(t):
if 0 < t < 0.6:
return 'RAV4'
elif 0.6 < t < 1.2:
return 'CAMRY'
elif 1.2 < t < 2.0:
return 'ACCORD'
elif 2 < t < 3.0:
return 'RAV4'
elif 4 < t < 5:
return 'ACCORD'
elif 13 < t < 14:
return 'CAMRY'
else:
return '0'
def company_input(t):
if 0 < t < 1.2:
return 'TOYOTA'
elif 1.2 < t < 2.0:
return 'HONDA'
else:
return '0'
model.store_car_model = spa.State(D)
model.input_car_model = spa.Input(store_car_model = car_model_input)
model.store_company = spa.State(D)
model.input_company = spa.Input(store_company = company_input)
learning = nengo.Node(output=lambda t: -int(t>=T/2))
recall_model_to_company = nengo.Node(size_in=D)
# Create the memory
memory_model_to_company = nengo.Ensemble(n_neurons, D, intercepts=[intercept]*n_neurons)
# Learn the encoders/keys
voja = nengo.Voja(post_tau=None, learning_rate=5e-2)
conn_in = nengo.Connection(model.store_car_model.output, memory_model_to_company, synapse=None,
learning_rule_type=voja)
nengo.Connection(learning, conn_in.learning_rule, synapse=None)
# Learn the decoders/values, initialized to a null function
conn_out = nengo.Connection(memory_model_to_company, recall_model_to_company, learning_rule_type=nengo.PES(1e-3),
function=lambda x: np.zeros(D))
# Create the error population
error = nengo.Ensemble(n_neurons, D)
nengo.Connection(learning, error.neurons, transform=[[10.0]]*n_neurons,
synapse=None)
# Calculate the error and use it to drive the PES rule
nengo.Connection(model.store_company.output, error, transform=-1, synapse=None)
nengo.Connection(recall_model_to_company, error, synapse=None)
nengo.Connection(error, conn_out.learning_rule)
# make assembly to read recall - ?why isn;t reading?
model.read_recall = spa.State(D)
nengo.Connection(recall_model_to_company, model.read_recall.input, transform = 10)
intercept2 = 0.08
def country_input(t):
if 0 < t < 6.5:
return '0'
elif 6.5 < t < 7.5:
return 'JAPAN'
elif 7.5 < t < 8.0:
return 'KOREA'
else:
return '0'
def company_input2(t):
if 0 < t < 6.5:
return '0'
elif 6.5 < t < 7.0:
return 'TOYOTA'
elif 7.0 < t < 7.5:
return 'HONDA'
elif 7.5 < t < 8.0:
return 'KIA'
elif 9.0 < t < 10:
return 'TOYOTA'
elif 11 < t < 12:
return 'KIA'
else:
return '0'
model.store_country = spa.State(D, label = 'store_country_state_label')
model.input_country = spa.Input(store_country = country_input)
model.store_company2 = spa.State(D)
model.input_company2 = spa.Input(store_company2 = company_input2, label = 'input_company2')
def learn(t):
if 0 < t < 6.5:
return -1
elif 6.5 < t < 8.0:
return 0
else:
return -1
learning2 = nengo.Node(learn, label = 'learning2')
recall2 = nengo.Node(size_in=D, size_out = D, label = 'recall2')
# Create the memory
memory2_company_to_country = nengo.Ensemble(n_neurons, D, intercepts=[intercept2]*n_neurons)
# Learn the encoders/keys
voja = nengo.Voja(post_tau=None, learning_rate=5e-2)
conn_in2 = nengo.Connection(model.store_company2.output, memory2_company_to_country, synapse=None,
learning_rule_type=voja)
nengo.Connection(learning2, conn_in2.learning_rule, synapse=None)
# Learn the decoders/values, initialized to a null function
conn_out2 = nengo.Connection(memory2_company_to_country, recall2, learning_rule_type=nengo.PES(1e-3),
function=lambda x: np.zeros(D))
# Create the error population
error2 = nengo.Ensemble(n_neurons, D)
nengo.Connection(learning2, error2.neurons, transform=[[10.0]]*n_neurons,
synapse=None)
# Calculate the error and use it to drive the PES rule
nengo.Connection(model.store_country.output, error2, transform=-1, synapse=None)
nengo.Connection(recall2, error2, synapse=None)
nengo.Connection(error2, conn_out2.learning_rule)
# make assembly to read recall
model.read_recall2 = spa.State(D)
nengo.Connection(recall2, model.read_recall2.input, transform = 10)
############################
model.gate = spa.State(D, feedback = 0)
def control_gate(t):
if 0 < t < 8:
return 'CLOSED'
elif 8 < t < 15:
return 'OPEN'
else:
return '0'
model.gate_instructions = spa.State(D, feedback = 0)
nengo.Connection(recall_model_to_company, model.gate.input, synapse = 0.01)
nengo.Connection(model.gate.output, recall_model_to_company, transform = -1)
nengo.Connection(model.gate.output, memory2_company_to_country, synapse = 0.01)
model.control_gate_action = spa.Actions (
'dot(gate_instructions, CLOSED)-->',
'dot(gate_instructions, OPEN)--> ')
model.input_gate_instructions = spa.Input(gate_instructions = control_gate)
model.bg = spa.BasalGanglia(model.control_gate_action)
model.thal = spa.Thalamus(model.bg)
#ZERO
for e in model.gate.all_ensembles:
nengo.Connection(model.thal.output[0], e.neurons,
transform= -2.5* np.ones((e.n_neurons, 1)))
#
#ONE
#for e in model.gate.all_ensembles:
# nengo.Connection(model.thal.output[0], e.neurons,
# transform= -2.5* np.ones((e.n_neurons, 1)))
Thanks
Howard