How to efficiently modify synnaptic weights for large networks

Hi

I am working with a large network model with more than 1e6 synapses. I now want to silence neurons by setting some of those connections to zero.

I am trying this via S.w[i, :] = 0, where S is the Synapses() object and i the index for the neuron to be silenced.

However, this approach takes really long (I interrupted my code after about 1 h). Is there some more efficient way to address synaptic weights or silence a neuron?

Thanks a lot for your help :slight_smile:

Hi @nspiller. Just to make sure I understand correctly, what exactly is taking long – the code that sets the weights to 0, or running a simulation where many weights are 0?

Hi @mstimberg,

setting the weight to 0, exactly this line of code: S.w[i, :] = 0.

Sorry, I did not write that clearly :slight_smile:

Ok, thanks. I guess it is not literally a single line like this, but rather many such lines, e.g. in a loop? I tried the following code with 1e6 synapses, and setting the weight to 0 for 100 neurons (i.e. 10% of all synapses):

from brian2 import *

source = NeuronGroup(1000, '')
target = NeuronGroup(1000, '')

synapses = Synapses(source, target, 'w : 1')
synapses.connect()
synapses.w = 'rand()'  # Not really necessary, but makes it more realistic

for idx in range(100):
    print(idx)
    synapses.w[idx, :] = 0

It is indeed not fast, but not that slow either – it takes about 0.4s per iteration, so in total about 40s. The 2-dimensional indexing into synapses is a very general mechanism, though, and it is not optimized for special cases like using : for one of the dimensions (we should probably do that!). Using the general “string condition” mechanism is much faster, actually, e.g. if I replace it by

for idx in range(100):
    print(idx)
    synapses.w["idx == i"] = 0

it runs in 0.5s in total! Finally, getting rid of the loop can speed up things even more, e.g. the above can be replaced by

synapses.w['i < 100'] = 0

which basically reduces the speed to that of a single iteration (~0.005s).

Hope that helps!

2 Likes

Hi @mstimberg,

thank you so much for the answer. Using this was sufficiently fast for my case:

synapses.w["idx == i"] = 0

A bit late, but here is an MWE and profiling for my issue:

from brian2 import NeuronGroup, Synapses
import numpy as np
from timeit import timeit

N_neu = int(1e5)
N_syn = int(1e6)

neu = NeuronGroup(N_neu, '')
syn = Synapses(neu, neu, 'w : 1')

idx_i = np.random.choice(range(N_neu), size=N_syn)
idx_j = np.random.choice(range(N_neu), size=N_syn)

syn.connect(i=idx_i, j=idx_j)
syn.w = 'rand()'

Using the string expression (100 runs):

def fun():
    syn.w["0 == i"] = 0

timeit(fun, number=100)

>> 0.5920858001336455

Using numpy-like syntax (1 run):

def fun():
    syn.w[0, :] = 0

timeit(fun, number=1)

>> 62.030049999943

All the best