I am completely new with modeling spiking neuron networks in general and with nengo in particular. I have recently developed a network which is supposed to mimic some experimental data of mine. The model seems to work properly and I manage to access the data properly. However, my problem, right now, is that I don’t manage to create a batch in which I manipulate the values of the 2 nodes of the network to mimic different conditions. Do you have an idea how I should do this?
Here is what I have:
model = nengo.Network()
sample_stim1 = Piecewise({0: 0, 0.450: 1)})
sample_stim2 = Piecewise({0: 0, 0.450: -1)})
test_stim1 = Piecewise({0: 0, 0.450: 0, 1.350: -1, 1.800: ,1, 2.250: 0})
test_stim2 = Piecewise({0: 0, 0.450: 0, 1.350: 1, 1.800: ,-1, 2.250: 0})
with model:
stim_mem = nengo.Node(sample_stim)#here sample stim should take the values of either sample_stim1 # #or sample_stim2
stim_vis = nengo.Node(test_stim)#here test_stim should take the values of either test_stim1 # #or test_stim2
for j in range (0, numtrials) #num trials is the number of iteration
with nengo.Simulator(model) as sim:
tmp=np.random.choice([-1,1])
if tmp==1:
stim_mem=sample_stim1
stim_vis=test_stim1
else:
stim_mem=sample_stim2
stim_vis=test_stim2
sim.run(trial_duration)
There are a few syntax errors in your code that prevent it from running, which makes it a little bit harder to help, but to answer your question the easiest way to do this (fewest changes to the code in its current form) would be to substitute the output attribute of the nengo.Node with the new process (rather than reassigning the variable, which doesn’t do what you want because that simply creates a new variable with the same name, in Python).
Hello Aaron
Sorry for the syntax errors, it was not my actual code…
It seems I still have a lot to learn about how nengo works and how to simulate models. I’ve tried what you propose but I don’t think I understood correctly, because I don’t manage to make it work properly.
I’ve then tried to change things a little but it still does not work. Here is my actual code, but the values do not change on each iteration of the simulation:
model = nengo.Network()
def Pick_S(x):
if x==1:
sample_stim=S1
else:
sample_stim=S2
return sample_stim
def Pick_T(x):
if x==1:
test_stim=T1
else:
test_stim=T2
return test_stim
tmp=np.random.choice([-1,1])
sample_stim= Pick_S(tmp)
test_stim= Pick_S(tmp)
with model:
stim_mem = nengo.Node(sample_stim)
stim_vis = nengo.Node(test_stim)
Stim_mem = nengo.Probe(stim_mem)
Stim_vis = nengo.Probe(stim_vis)
for i in range(0,10):
with nengo.Simulator(model) as sim:
tmp=np.random.choice([-1,1])
sample_stim= Pick_S(tmp) # same results whether I use sample_stim.output=Pick_S(tmp) or not
test_stim= Pick_S(tmp) # same results whether I use test_stim.output=Pick_T(tmp) or not
sim.run(trial_duration)
Sample_values[i,:] = np.transpose(sim.data[Stim_mem])
Test_values[i,:] = np.transpose(sim.data[Stim_vis])
It looks like you tried sample_stim = ... and sample_stim.output = ... but neither is what I suggested. My suggestion above was to modify the output attribute on the node itself, as in stim_mem.output = ..., where stim_mem is the Node (not the Process). Here is your code, modified to run, and plot each trial to demonstrate randomness.
import numpy as np
import matplotlib.pyplot as plt
import nengo
from nengo.processes import Piecewise
S1 = Piecewise({0: 0, 0.450: 1})
S2 = Piecewise({0: 0, 0.450: -1})
T1 = Piecewise({0: 0, 0.450: 0, 1.350: -1, 1.800: 1, 2.250: 0})
T2 = Piecewise({0: 0, 0.450: 0, 1.350: 1, 1.800: -1, 2.250: 0})
trial_duration = 2.5
n_trials = 10
def Pick_S(x):
if x==1:
sample_stim=S1
else:
sample_stim=S2
return sample_stim
def Pick_T(x):
if x==1:
test_stim=T1
else:
test_stim=T2
return test_stim
tmp = np.random.choice([-1,1])
sample_stim = Pick_S(tmp)
test_stim = Pick_T(tmp)
model = nengo.Network()
with model:
stim_mem = nengo.Node(sample_stim)
stim_vis = nengo.Node(test_stim)
Stim_mem = nengo.Probe(stim_mem)
Stim_vis = nengo.Probe(stim_vis)
Sample_values = []
Test_values = []
for i in range(n_trials):
with nengo.Simulator(model) as sim:
tmp=np.random.choice([-1,1])
stim_mem.output = Pick_S(tmp)
stim_vis.output = Pick_T(tmp)
sim.run(trial_duration)
Sample_values.append(np.transpose(sim.data[Stim_mem]))
Test_values.append(np.transpose(sim.data[Stim_vis]))
fig, ax = plt.subplots(1, 2, figsize=(16, 5), sharey=True)
ax[0].set_title("Sample_values")
ax[1].set_title("Test_values")
for i in range(n_trials):
ax[0].plot(sim.trange(), Sample_values[i].T)
ax[1].plot(sim.trange(), Test_values[i].T)
ax[0].set_xlabel("Time (s)")
ax[1].set_xlabel("Time (s)")
fig.show()
And here is an alternative, but (IMO) cleaner and more Pythonic way of doing this, by use of a function to abstract away the notion of a trial – including picking the stimuli, building, simulating, and returning the results. You can extend this to analyze the data and return some analysis instead. Note that I also use fixed seeds for the RNG in order to make sure that each time you run this you get the same set of stimuli across all trials (for reproducibility). Hope this helps.
import numpy as np
import matplotlib.pyplot as plt
import nengo
from nengo.processes import Piecewise
S1 = Piecewise({0: 0, 0.450: 1})
S2 = Piecewise({0: 0, 0.450: -1})
T1 = Piecewise({0: 0, 0.450: 0, 1.350: -1, 1.800: 1, 2.250: 0})
T2 = Piecewise({0: 0, 0.450: 0, 1.350: 1, 1.800: -1, 2.250: 0})
trial_duration = 2.5
n_trials = 10
def run_trial(stim_seed):
stim_rng = np.random.RandomState(seed=stim_seed)
condition = stim_rng.choice(range(2))
S = [S1, S2][condition]
T = [T1, T2][condition]
with nengo.Network() as model:
stim_mem = nengo.Node(output=S)
stim_vis = nengo.Node(output=T)
probe_mem = nengo.Probe(stim_mem)
probe_vis = nengo.Probe(stim_vis)
with nengo.Simulator(model) as sim:
sim.run(trial_duration)
return sim.data[probe_mem], sim.data[probe_vis]
data = []
for i in range(n_trials):
data.append(run_trial(stim_seed=i))