I have built a nest model with a reverse stdp approach in which with time I'm trying to reduce the spikes in training data which is a normal bearing metal data and then during testing I'll try to test it on a anomalous data which should produce opposite results to that of training data so now firstly I made it in brian and it worked fine but here in nest after training the model when I have to test it then again the synaptic weights are changing which should not happen during testing. In brian I had put the learning rate as 0 thats why it was working fine but in Nest I am not able to find a way to test a model by freezing the weights. So I tried something which I'm not sure is the correct approach so can anyone please review this approach or if suggest a better approach for testing these kind of models.
Also I want to mention one thing that with my current approach the weights are freezing but as I'm assigning input spikes from anomalous signal and start testing, the kernel is getting died which usually happens when there is a some issue in nest network.
nest.ResetKernel() # Simulation parameters dt = 0.01 # Simulation time step in ms nest.SetKernelStatus({"resolution": dt})
N = 16 # Number of neurons gmax = 3 neuron_params = { "tau_m": 140.0, # Membrane time constant in ms "E_L": -70.6, # Resting potential (in mV) "V_th": -40.4, # Threshold potential (in mV) "V_reset": -70.6, # Reset potential (in mV) "V_m":0.0, }
nest.CopyModel("stdp_synapse_hom", "stdp_synapse_exc", {"weight":gmax,"alpha":1,"Wmax":gmax, "tau_plus": 20.0,"lambda": -0.0005, "mu_minus": 0, "mu_plus": 0}) nest.CopyModel("stdp_synapse_hom", "stdp_synapse_inh", {"weight":-gmax/(N-1),"alpha":1,"Wmax":-gmax, "tau_plus": 20.0,"lambda": 0.005, "mu_minus": 0, "mu_plus": 0})
G_spike_gen = nest.Create("spike_generator", N) G_input = nest.Create("parrot_neuron", N)
G_hidden = nest.Create("iaf_psc_delta", N,params=neuron_params) G_output = nest.Create("iaf_psc_delta", 1,params=neuron_params)
S_in = nest.Connect(G_spike_gen, G_input, "one_to_one")
# Connect input to hidden layer with excitatory STDP synapses S_exc = nest.Connect(G_input, G_hidden,"one_to_one",syn_spec = "stdp_synapse_exc")
# Retrieve the neuron IDs for G_input and G_hidden input_ids = G_input.tolist() hidden_ids = G_hidden.tolist()
# Get the existing excitatory connections and extract their source-target ID pairs exc_connections = nest.GetConnections(G_input, G_hidden) exc_connection_pairs = set(zip(exc_connections.get("source"), exc_connections.get("target")))
for i in input_ids: for h in hidden_ids: if (i, h) not in exc_connection_pairs: nc1 = nest.NodeCollection([i]) nc2 = nest.NodeCollection([h]) nest.Connect(nc1, nc2, syn_spec= "stdp_synapse_inh")
S_out = nest.Connect(G_hidden, G_output,"all_to_all",syn_spec = {"weight": 40.4/N})
def train_net(signals, spike_tol=0):
output_spike_recorder = nest.Create("spike_recorder") output_membrane_recorder = nest.Create("voltmeter", 1) nest.Connect(G_output, output_spike_recorder) # Record output layer spikes nest.Connect(output_membrane_recorder, G_output, "one_to_one")
while True: recorder_for_epoch = nest.Create("spike_recorder") nest.Connect(G_output, recorder_for_epoch) for signal in signals: indices, times = process_signal(signal) # Get the indices and times offset = nest.GetKernelStatus()["biological_time"] for i in range(N): times_for_neuron = [t+offset for j,t in enumerate(times) if indices[j] == i] G_spike_gen[i].set(spike_times = times_for_neuron) nest.Simulate(len(signal)*(1/SAMPLE_RATE)*1000) output_spikes_num = len(recorder_for_epoch.get()["events"]["times"]) print("# of output spikes: " + str(output_spikes_num)) del recorder_for_epoch if output_spikes_num <= spike_tol: print("Training finished") break
return output_membrane_recorder, output_spike_recorder
def synapse_freeze():
conn = nest.GetConnections() sources = conn.get("source") targets = conn.get("target") weights = conn.get("weight")
# Store as a list of tuples connections = list(zip(sources, targets, weights))
# Replace dynamic synapses with static synapses
for s,t,w in connections: nc1 = nest.NodeCollection([s]) nc2 = nest.NodeCollection([t]) conn_t = nest.GetConnections(nc1,nc2) model=nest.GetConnections(nc1,nc2).get("synapse_model")
if model=="stdp_synapse_exc": nest.Disconnect(nc1,nc2,syn_spec = {"synapse_model":"stdp_synapse_exc"}) nest.Connect(nc1,nc2,syn_spec = {"synapse_model":"static_synapse","weight":w})
if model=="stdp_synapse_inh": nest.Disconnect(nc1,nc2,syn_spec = {"synapse_model":"stdp_synapse_inh"}) nest.Connect(nc1,nc2,syn_spec = {"synapse_model":"static_synapse","weight":w})
print("Switched to static synapses with trained weights.")
def inference(signal):
output_spike_recorder_t = nest.Create("spike_recorder") output_membrane_recorder_t = nest.Create("voltmeter", 1) nest.Connect(G_output, output_spike_recorder_t) # Record output layer spikes nest.Connect(output_membrane_recorder_t, G_output, "one_to_one")
indices, times = process_signal(signal) # Prepare test signal offset = nest.GetKernelStatus()["biological_time"] for i in range(N): times_for_neuron = [t+offset for j,t in enumerate(times) if indices[j] == i] G_spike_gen[i].set(spike_times = times_for_neuron)
nest.Simulate(len(signal)*(1/SAMPLE_RATE)*1000) # Run simulation
output_spikes_num = len(output_spike_recorder_t.get()["events"]["times"]) print("# of output spikes: " + str(output_spikes_num))
return output_membrane_recorder_t, output_spike_recorder_t