How to change the weights between each synapses?

I am working on iris dataset and wanted to change the weights between each synapses. I found this on nengo forum and tried to implement on iris dataset. I am able to set the weights between each synapses to 0, but it is not reflected on the plot. Please see the attachment for the code.

  1. Just to analyze, I set the weights of all 10 neurons to 0, but I can still see the spikes in the plot. Why?

plot_iris_dataset

  1. In the answer of this, it is mentioned “…we modify the weights of the connection between the two ensembles”

Is modifying the weights of the connection between the two ensembles the same as modifying the weights of the connection between synapses?

  1. If not, then how can I change the weights between synapses?

If you could help me or direct me what and where to refer, it would be great!

Thank you very much!

iris_v1.py (6.1 KB)

Hi @rao208,

Just because the synapse weights between two ensembles are zero, does not mean that all the neurons in the second ensemble will be silent. Neurons in Nengo also have bias currents, which provide a “baseline” current in the absence of any input. If you want your neurons to be silent, you’ll also need to make sure all bias currents are below the neuron’s firing threshold.

The easiest way to do this is by changing what we call the intercepts of the neurons. The intercept is the point where, for a given input x, the neuron begins firing. So if we set all intercepts >= 0, then in the absence of input, all neurons will be silent.

# set all intercepts to 0
a = nengo.Ensemble(n_neurons, dimensions, intercepts=nengo.dists.Choice([0]))

# set all intercepts to 0.5
a = nengo.Ensemble(n_neurons, dimensions, intercepts=nengo.dists.Choice([0.5]))

# set all intercepts to random values between 0 and 0.9
a = nengo.Ensemble(n_neurons, dimensions, intercepts=nengo.dists.Uniform(0, 0.9))

If you’re setting the intercepts and synapse weights, you might want to also consider setting the max-rates, which control how quickly a neuron’s firing rate increases as the input increases.

To better understand how intercepts and max-rates affect neural tuning curves, you might want to look at the tuning curve example.

1 Like

Hey @Eric Thank you for your reply. I see the difference between the code in the link and my code (iris dataset). In my code, I did not set the intercept value, whereas the code in the link has intercept value. I have one more question

and

Best Regards
Vanditha

The short answer is yes, modifying the connection weights is the same as modifying the synapse weights. Just be sure to use the .neurons attribute on your ensembles when forming these connections (to indicate that you’re directly connecting neurons, rather than doing a decoded NEF-style connection).

In Nengo, we don’t have a stand-alone object for synapses. We have connections between neurons, which have an associated weight as well as a synaptic filter. The former is set with the transform argument on a neurons-to-neurons connection, and the later is set with the synapse attribute on any connection. So a “connection weight” is the weight on the connection between two neurons, and there is no separate idea of “synapse weight” aside from this. Be careful not to confuse the synaptic filter with a weight. For example, we may say synapse=0.5, which is a shorthand for synapse=nengo.Lowpass(0.5), i.e. a Lowpass synaptic filter with a time-constant of 0.5.

Here’s an example. Note that if you’re always connecting and probing using the .neurons attribute, then dims_a and dims_b don’t matter (these only matter for NEF-style connections).

a = nengo.Ensemble(n_neurons_a, dims_a)
b = nengo.Ensemble(n_neurons_b, dims_b)
nengo.Connection(
    a.neurons, 
    b.neurons, 
    transform=connection_weights, 
    synapse=synaptic_filter,
)
1 Like

@Eric Thank you very much for your reply. The concept of weights are getting more and more clear now. I have a follow up question.

  1. I have 10x10 weights, so I will have how many baseline current? 10x1?
  2. When intercepts is set to Uniform(low=-1.0, high=0.9). In your reply above, you made a statement it will “…set all intercepts to random values between 0 and 0.9” when intercept is Uniform(low=-1.0, high=0.9). How many intercepts do we have? 10 intercepts for 10 neurons? I thought it was only 1 intercept value.
  3. How can I print the values of the “baseline” current in Nengo? The bias parameter in nengo.Ensemble is not the baseline current right?

Each neuron has its own bias current and gain, such that the input current to the neuron i is J_i = g_i x_i + b_i. The gain and bias can be determined in one of two ways: either you can set them manually using the gain and bias arguments when you create an ensemble, or you can set them implicitly based on your desired max_rates and intercepts (Nengo will then compute the gain and bias using the neuron type). The latter method is what I described above. In your case, you have 10 neurons, so you’ll have 10 gain and bias values.

Each neuron has its own intercept; they are not shared. This allows neurons to have different tuning curves, and thus code for different parts of the input space. In the tuning curve example, you can see that each neuron begins firing at a different point along the X axis; these are the different intercepts.

To print the bias current, you can use the nengo.Simulator object you’ve used to build your model, as well as the handle to the nengo.Ensemble you want to print the bias currents for, like so: print(sim.data[ens].bias)

1 Like

Hi @Eric,

I printed the following parameters before and after I set weights to zero.

Before configuring weights = 0

  1. sim.data[ens2].bias

[ 11.33387593, -0.99492363, -30.79397568, -8.13427937, 3.07063806, 11.86735168, -1.94708691, 9.98872749, -3.41797826, -1.43711146]

  1. sim.data[ens2].max_rates

[356.6566124, 266.09879689, 326.87314282, 372.27112313, 242.11352655, 349.12747097, 288.7046451, 373.33176044, 202.66340248, 285.71903509]

  1. sim.data[ens2].gain

[14.05074736, 12.87879444, 50.1789458, 37.78255438, 6.82661282, 11.77680872, 16.11674386, 19.98729393, 10.74615897, 15.27721113]

  1. sim.data[ens2].intercepts

[-0.73546806, 0.15489987, 0.63361187, 0.24175918, -0.30331851, -0.9227756, 0.18285871, -0.44972208, 0.41112162, 0.15952594]

After configuring weights = 0

  1. sim.data[ens2].bias

[11.33387593, -0.99492363, -30.79397568, -8.13427937, 3.07063806, 11.86735168, -1.94708691, 9.98872749, -3.41797826, -1.43711146]

  1. sim.data[ens2].max_rates

[356.6566124, 266.09879689, 326.87314282, 372.27112313, 242.11352655, 349.12747097, 288.7046451, 373.33176044, 202.66340248, 285.71903509]

  1. sim.data[ens2].gain

[14.05074736, 12.87879444, 50.1789458, 37.78255438, 6.82661282, 11.77680872, 16.11674386, 19.98729393, 10.74615897, 15.27721113]

  1. sim.data[ens2].intercepts

[-0.73546806, 0.15489987, 0.63361187, 0.24175918, -0.30331851, -0.9227756, 0.18285871, -0.44972208, 0.41112162, 0.15952594]

As you can notice, there is no difference in Bias, Gain, Max Rates and Intercepts value which is understandable. The only difference between both of them is in the latter case, the weights = 0

Please note, I have set the seed value in nengo.Network and nengo.Ensemble. So in every execution of iris_v1.py, the bias, intercept, max rate and gain is the same.

Earlier you mentioned:

Just because the synapse weights between two ensembles are zero, does not mean that all the neurons in the second ensemble will be silent. Neurons in Nengo also have bias currents, which provide a “baseline” current in the absence of any input.

However, I see different neurons are activated in every execution and the spike rates are different before and after configuring weights = 0. (Please see the image uploaded(I have comments on the image). I have uploaded two images. Results of execution of iris_v1.py two times)

I understand why there are still spikes after weights = 0, but I do not understand

  1. why spike rates are different even though bias, gain, max rates, intercepts are same?
  2. Why the neuron which did not produce spikes before weights = 0 are now producing the spikes after weights = 0 even though bias, gain, max rates, intercepts are same?

In this link, it is mentioned that:

In Nengo, the behaviour of the neurons are dependent on the current input to the neuron.

I think by “current input”, it means the input that is fed to the code (in my case iris dataset). The input is the same in both the executions and sim.run. I am feeding the same dataset both the times. There are two sim.run (one before weights = 0 and one after weights = 0) in each execution.

Even if it means:

it should not change as gi, xi and bi are same before and after weights = 0 and in each executions.

I am just a little bid confused. What are the other factors that generate spikes? I believe it is not just the parameters in nengo.Ensemble. Am I correct?


Do you mean that different neurons fire if you re-run the script with no changes? That would suggest that something is not being seeded properly. If that’s the case, I would address that problem first, because it will make it difficult to diagnose any other problems.

What you described is that neurons will sometimes begin firing when you set weights to zero. This is expected, as weights can be negative as well as positive. If a neuron has largely negative input weights, then setting the weights to zero may cause the input current to increase, and thus the neuron to fire more.

Note that you can also probe the input to neurons in an ensemble with nengo.Probe(ens.neurons, "input"). This could help in your analysis.

The input current should be fully determined by the connection weights, gain, and bias. That is, J_i = g_i * sum(w_ij * y_j for j in range(n_inputs)) + b_i, where y_j is the output of incoming neuron j and w_ij is the connection weight between neuron j in the pre population and neuron i in the post population. The only exception is if you add neuronal noise (using the noise parameter on Ensemble); then it’s also added in to this input current.

The neuron type then turns the input current into spikes using its step function. For example, you can see the step function for the LIF neuron type here.

1 Like

Hi @Eric,

You have been very helpful. I understand spikes and weights better now. Thank you very much :slight_smile:

yes, I meant different neurons fire if I re-run the script with no change.

I will look into it and try to find the source of the problem.

Best Regards,