Esempio n. 1
0
    def make_classification_network(self, number_of_stimuli, network_name):
        if network_name not in self.networks:
            network_size = number_of_stimuli * self.number_of_neurons
            count_mat = np.zeros((int(self.stimulus_duration / ms * 10), network_size), int)
            target = b2.NeuronGroup(N=number_of_stimuli, model=self.eqs, threshold='v>threshold', reset='v=0',
                                    namespace={'tau': self.tau, 'threshold': self.threshold})
            driving = b2.SpikeGeneratorGroup(N=network_size,
                                             indices=[0], times=[0 * ms])
            # counts = b2.TimedArray(values=_count_mat, dt=b2.defaultclock.dt)
            synapses = b2.Synapses(source=driving, target=target,
                                   model='w: 1', on_pre='v+=w*counts(t, i)')
            i = np.arange(network_size)
            j = np.repeat(range(number_of_stimuli), self.number_of_neurons)
            synapses.connect(j=j, i=i)
            synapses.w = np.tile(self.weights, reps=number_of_stimuli)

            spikes = b2.SpikeMonitor(target, record=True)
            voltage = b2.StateMonitor(target, 'v', record=True)

            net = b2.Network([target, driving, synapses, spikes, voltage])
            net.store()
            self.networks[network_name] = dict(net=net,
                                               count_mat=count_mat,
                                               synapses=synapses,
                                               v_mon=voltage,
                                               spike_mon=spikes,
                                               number_of_stimuli=number_of_stimuli,
                                               driving=driving)
        else:
            self.networks[network_name]['synapses'].w = np.tile(self.weights, reps=number_of_stimuli)
 def set_syn_input(self, target, time):
     '''adding sync inputs at some time points'''
     ext_in = bb.SpikeGeneratorGroup(1, [(0, time)], self.network.clock)
     C_syne = bb.Synapses(ext_in, target, model='w:siemens', pre='ge+=w')
     C_syne.connect_random(ext_in, target, sparseness=1.)
     C_syne.w = 30. * self.g_ee
     self.network.add(ext_in, C_syne)
Esempio n. 3
0
def run(TSTOP=250, group_size=100, g_time=150, neuron_n=1000, linear=True,
        ext_w=0.2, inh_w=0.2):
    """Run a simulation and return the resulting spiketrain"""
    # Basic equation of the model
    eq = """dv/dt = -gamma*v + I0 : volt
    Ie : volt
    Ii : volt
    """

    thetaU = 16 * mV
    tauM = 8 * ms
    gamma = 1 / tauM
    I0 = 17.6 * mV / tauM

    #Build the group of neuron to use
    G = br2.NeuronGroup(neuron_n, threshold="v>thetaU", reset="v=0*mV",
                        method='euler',
                        model=eq)

    #Record the spikes from this group
    spikes = br2.SpikeMonitor(G)

    #Build stimulation
    stim = br2.SpikeGeneratorGroup(1, [0], [g_time]*ms - br2.defaultclock.dt)
    stim_syn = br2.Synapses(stim, G, on_pre="v += 2*thetaU")
    stim_syn.connect(i=0, j=np.arange(group_size))
    br2.magic_network.schedule = ['start', 'groups', 'synapses', 'thresholds', 'resets', 'end']
    connections = np.random.rand(1000, 1000) < 0.3
    exc_or_inh  = np.random.rand(1000, 1000) < 0.5
    exc_i, exc_j = (connections & exc_or_inh).nonzero()
    inh_i, inh_j = (connections & ~exc_or_inh).nonzero()

    if linear:
        G.run_regularly('''
                        v += Ie + Ii
                        Ie = 0*mV
                        Ii = 0*mV
                        ''', when='after_synapses')
    else:
        G.run_regularly('''
                        v += clip(Ie, 0*mV, 2*mV) + clip(2*(Ie-2*mV), 0*mV, 4*mV) + Ii
                        Ie = 0*mV
                        Ii = 0*mV
                        ''', when='after_synapses')

    dt = br2.defaultclock.dt
    exc_syn = br2.Synapses(G, G, on_pre='Ie += %s*mV' % (ext_w), delay=5*ms-dt)
    inh_syn = br2.Synapses(G, G, on_pre='Ii -= %s*mV' % (inh_w), delay=5*ms-dt)
    exc_syn.connect(i=exc_i, j=exc_j)
    inh_syn.connect(i=inh_i, j=inh_j)

    #Set random initial conditions
    G.v = np.random.rand(neuron_n) * 16 * mV

    br2.run(TSTOP * ms)

    return spikes
Esempio n. 4
0
def events_generator(snn, dvsEventsList):
    xmax = int(numpy.max(snn.x) + 1)
    ymax = int(numpy.max(snn.y) + 1)

    times = dvsEventsList[0] * brian2.ms

    indices = dvsEventsList[1] + xmax * dvsEventsList[2]
    #print(indices)

    N = xmax * ymax
    #print(N)
    return brian2.SpikeGeneratorGroup(N, indices, times), times, indices
Esempio n. 5
0
def main4(plot=True):
    # what if we want to keep the input spike exactly the same throughout different taus?
    # Solution: We run PoissonGroup once, store all the spikes, and use the stored spikes across the multiple runs
    bs.start_scope()
    num_inputs = 100
    input_rate = 10 * bs.Hz
    w = 0.1
    tau_range = bs.linspace(1, 10, 30) * bs.ms
    output_rates = []

    P = bs.PoissonGroup(num_inputs, rates=input_rate)
    p_monitor = bs.SpikeMonitor(P)

    one_second = 1 * bs.second
    """
    Note that in the code above, we created Network objects. 
    The reason is that in the loop, if we just called run it would try to simulate all the objects, 
    including the Poisson neurons P, and we only want to run that once. 
    We use Network to specify explicitly which objects we want to include.
    """
    net = bs.Network(P, p_monitor)
    net.run(one_second)

    # keeps a copy of the spikes that are generated by the PoissonGroup during that explicit run earlier
    spikes_i = p_monitor.i
    spikes_t = p_monitor.t

    # Construct network that we run each time
    sgg = bs.SpikeGeneratorGroup(num_inputs, spikes_i, spikes_t)
    eqs = '''
    dv/dt = -v/tau : 1
    '''
    G = bs.NeuronGroup(1, eqs, threshold='v>1', reset='v=0', method='exact')
    S = bs.Synapses(sgg, G, on_pre='v += w')
    S.connect()  # fully connected network
    g_monitor = bs.SpikeMonitor(G)

    # store the current state of the network
    net = bs.Network(sgg, G, S, g_monitor)
    net.store()

    for tau in tau_range:
        net.restore()
        net.run(one_second)
        output_rates.append(g_monitor.num_spikes / bs.second)
    if plot:
        plt.clf()
        plt.plot(tau_range / bs.ms, output_rates)
        plt.xlabel(r'$\tau$ (ms)')
        plt.ylabel('Firing Rate (spikes/s)')
        # there is much less noise compared to before where we used different PoissonGroup everytime
        plt.show()
Esempio n. 6
0
def construct_feedforward_input(NTWK,
                                target_pop, afferent_pop,\
                                t, rate_array,\
                                verbose=False,
                                SEED=1):
    """
    This generates an input asynchronous from post synaptic neurons to post-synaptic neurons

    POPS and AFFERENCE_ARRAY should be 1D arrrays as their is only one 
    source population

    'pop_for_conductance' is the string identifying the source conductance
    that will be incremented by the afferent input !!
    """

    Model = NTWK['Model']

    # extract parameters of the afferent input
    Nsyn = Model['p_' + afferent_pop + '_' + target_pop] * Model['N_' +
                                                                 afferent_pop]
    Qsyn = Model['Q_' + afferent_pop + '_' + target_pop]

    #finding the target pop in the brian2 objects
    ipop = np.argwhere(NTWK['POPULATIONS'] == target_pop).flatten()[0]

    if Nsyn > 0:
        if verbose:
            print('drawing Poisson process for afferent input [...]')
        indices, times = set_spikes_from_time_varying_rate(\
                            t, rate_array,\
                            NTWK['POPS'][ipop].N, Nsyn, SEED=(SEED+2)**2%100)
        spikes = brian2.SpikeGeneratorGroup(NTWK['POPS'][ipop].N, indices,
                                            times)
        pre_increment = 'G' + afferent_pop + target_pop + ' += w'
        synapse = brian2.Synapses(spikes, NTWK['POPS'][ipop], on_pre=pre_increment,\
                                        model='w:siemens')
        synapse.connect('i==j')
        synapse.w = Qsyn * brian2.nS

        NTWK['PRE_SPIKES'].append(spikes)
        NTWK['PRE_SYNAPSES'].append(synapse)

    else:
        print('Nsyn = 0 for', afferent_pop + '_' + target_pop)
Esempio n. 7
0
 def make_plot_network(self):
     count_mat = np.zeros((int(self.stimulus_duration / ms * 10), self.number_of_neurons), int)
     target = b2.NeuronGroup(N=1, model=self.eqs, threshold='v>threshold', reset='v=0',
                             namespace={'tau': self.tau, 'threshold': self.threshold})
     driving = b2.SpikeGeneratorGroup(N=self.number_of_neurons,
                                      indices=[0], times=[0 * ms])
     synapses = b2.Synapses(source=driving, target=target,
                            model='w: 1', on_pre='v+=w*counts(t, i)')
     synapses.connect(i=range(number_of_neurons), j=[0] * number_of_neurons)
     synapses.w = self.weights
     spikes = b2.SpikeMonitor(target, record=True)
     voltage = b2.StateMonitor(target, 'v', record=True)
     net = b2.Network([target, driving, synapses, spikes, voltage])
     net.store()
     self.networks['plot'] = dict(net=net,
                                  synapses=synapses,
                                  count_mat=count_mat,
                                  v_mon=voltage,
                                  spike_mon=spikes,
                                  driving=driving)
Esempio n. 8
0
 def make_train_network(self, batch_size, network_name):
     if network_name not in self.networks:
         network_size = batch_size * self.number_of_neurons
         target = b2.NeuronGroup(N=network_size, model=self.eqs,
                                 namespace={'tau': self.tau})
         driving = b2.SpikeGeneratorGroup(N=network_size,
                                          indices=[0], times=[0 * ms])
         count_mat = np.zeros((int(self.stimulus_duration / ms * 10), network_size), int)
         synapses = b2.Synapses(driving, target, 'w: 1', on_pre='v+=1*counts(t, i)')
         synapses.connect(condition='i==j')
         synapses.w = np.tile(self.weights, reps=batch_size)
         voltage = b2.StateMonitor(target, 'v', record=True)
         net = b2.Network([target, driving, synapses, voltage])
         net.store()
         self.networks[network_name] = dict(net=net,
                                            count_mat=count_mat,
                                            synapses=synapses,
                                            v_mon=voltage,
                                            number_of_stimuli=batch_size,
                                            driving=driving)
     else:
         self.networks[network_name]['synapses'].w = np.tile(self.weights, reps=batch_size)
    def set_noisy_input(self, target, time, sigma=0., mcoef=30):
        '''adding sync inputs at some time points with 
            normal jitter distribution sigma

            mcoef is the strength of stimulation
            
        '''
        #print time, sigma
        t0 = time - 6. * sigma  # mean delay is set to 6*sigma
        ext_in = bb.SpikeGeneratorGroup(1, [0], [t0], clock=nn.network.clock)
        C_syne = bb.Synapses(ext_in,
                             self.Pe,
                             model='w:siemens',
                             on_pre='ge+=w')
        for n in target:
            C_syne.connect(i=0, j=self.Pe[n])
        C_syne.w = mcoef * self.g_ee
        #C_syne.delay=np.random.uniform(0,sigma,len(target))
        if sigma > 0.:
            C_syne.delay = np.random.normal(6. * sigma, sigma, len(target))
        else:
            C_syne.delay = np.zeros(len(target))
        self.network.add(ext_in, C_syne)
Esempio n. 10
0
td = ev.read_dataset(test_file)

td.data = np.unique(td.data)

# # check whether there is False
# counter = 0
# for i in td.data:
# 	if i[2] == False:
# 		counter = counter +1

flat_indices = (td.data.x * td.width) + td.data.y

br.start_scope()

pos_spikes = br.SpikeGeneratorGroup(td.width * td.height,
                                    flat_indices[td.data.p == True],
                                    td.data.ts[td.data.p == True] * br.ms)
neg_spikes = br.SpikeGeneratorGroup(td.width * td.height,
                                    flat_indices[td.data.p == False],
                                    td.data.ts[td.data.p == False] * br.ms)

# input layer
Input_Neurons = br.NeuronGroup(td.width * td.height,
                               eqs,
                               threshold='v>0 or v<-0',
                               reset='v = 0',
                               method='euler')
# hidden layer
Hidden_Neurons = br.NeuronGroup(50,
                                eqs,
                                threshold='v>' + str(threshold_val) +
def construct_feedforward_input(NTWK, target_pop, afferent_pop,\
                                t, rate_array,\
                                AFF_TO_POP_MATRIX=None,
                                additional_spikes={'indices':[], 'times':[]},
                                verbose=False,
                                SEED=1):
    """
    This generates an input asynchronous from post synaptic neurons to post-synaptic neurons

    POPS and AFFERENCE_ARRAY should be 1D arrrays as their is only one 
    source population

    'pop_for_conductance' is the string identifying the source conductance
    that will be incremented by the afferent input !!

    if AFF_TO_POP_MATRIX then fixed pre-pop number: see "poisson_generator.py"
    """

    Model = NTWK['Model']

    # Synapses  number ?
    Nsyn = Model['p_' + afferent_pop + '_' + target_pop] * Model['N_' +
                                                                 afferent_pop]

    if Nsyn > 0:  # if non-zero projection [...]

        # extract parameters of the afferent input
        Qsyn = Model['Q_' + afferent_pop + '_' + target_pop]

        #finding the target pop in the brian2 objects
        ipop = np.argwhere(NTWK['POPULATIONS'] == target_pop).flatten()[0]

        if verbose:
            print('drawing Poisson process for afferent input [...]')

        indices, times, pre_indices,\
            pre_times = spikes_from_time_varying_rate(\
                                                       t, rate_array,\
                                                       NTWK['POPS'][ipop].N,
                                                       Nsyn,
                                                       AFF_TO_POP_MATRIX=AFF_TO_POP_MATRIX,
                                                       SEED=(SEED+2)**2%100)

        # adding the additional spikes
        indices = np.concatenate([indices, additional_spikes['indices']])
        times = np.concatenate([times, additional_spikes['times']])

        # insuring no more than one prespike per bin
        indices, times = deal_with_multiple_spikes_per_bin(indices,
                                                           times,
                                                           t,
                                                           verbose=verbose)

        # incorporating into Brian2 objects
        spikes = brian2.SpikeGeneratorGroup(NTWK['POPS'][ipop].N, indices,
                                            times * brian2.ms)
        # sorted = True, see "deal_with_multiple_spikes_per_bin"
        pre_increment = 'G' + afferent_pop + target_pop + ' += w'
        synapse = brian2.Synapses(spikes, NTWK['POPS'][ipop], on_pre=pre_increment,\
                                        model='w:siemens')
        synapse.connect('i==j')
        synapse.w = Qsyn * brian2.nS

        NTWK['PRE_SPIKES'].append(spikes)
        NTWK['PRE_SYNAPSES'].append(synapse)

    else:
        print('Nsyn = 0 for', afferent_pop + '_' + target_pop)
        spikes, synapse, indices, times = None, None, [], []

    # storing quantities:
    if 'iRASTER_PRE' in NTWK.keys():
        NTWK['iRASTER_PRE'].append(indices)
        NTWK['tRASTER_PRE'].append(times)
    else:  # we create the key
        NTWK['iRASTER_PRE'] = [indices]
        NTWK['tRASTER_PRE'] = [times]

    if 'iRASTER_PRE_in_terms_of_Pre_Pop' in NTWK.keys():
        NTWK['iRASTER_PRE_in_terms_of_Pre_Pop'].append(pre_indices)
        NTWK['tRASTER_PRE_in_terms_of_Pre_Pop'].append(pre_times)
    else:  # we create the key
        NTWK['iRASTER_PRE_in_terms_of_Pre_Pop'] = [pre_indices]
        NTWK['tRASTER_PRE_in_terms_of_Pre_Pop'] = [pre_times]
Esempio n. 12
0
    def __groups(self):
        inputs_hidden = br.SpikeGeneratorGroup(self.N_inputs,
                                               indices=np.asarray([]),
                                               times=np.asarray([]) * br.ms,
                                               name='input_hidden')
        hidden = br.NeuronGroup(self.N_hidden, \
                               model='''dv/dt = ((-gL*(v - El)) + D) / (Cm*second)  : 1
                                        gL = 30                                     : 1 (shared)
                                        El = -70                                    : 1 (shared)
                                        vt = 20                                     : 1 (shared)
                                        Cm = 3.0                                    : 1 (shared)
                                        D                                           : 1''',
                                        method='rk2', refractory=0*br.ms, threshold='v>=vt',
                                        reset='v=El', name='hidden', dt=self.dta)
        inputs_out = br.SpikeGeneratorGroup(self.N_hidden,
                                            indices=np.asarray([]),
                                            times=np.asarray([]) * br.ms,
                                            name='input_out')
        output = br.NeuronGroup(self.N_output, \
                               model='''dv/dt = ((-gL*(v - El)) + D) / (Cm*second)  : 1
                                        gL = 30                                     : 1 (shared)
                                        El = -70                                    : 1 (shared)
                                        vt = 20                                     : 1 (shared)
                                        Cm = 3.0                                    : 1 (shared)
                                        D                                           : 1''',
                                        method='rk2', refractory=0*br.ms, threshold='v>=vt',
                                        reset='v=El', name='output', dt=self.dta)
        #hidden = br.Subgroup(neurons, 0, self.N_hidden, name='hidden')
        #output = br.Subgroup(neurons, self.N_hidden, self.N_hidden+self.N_output, name='output')

        Sh = br.Synapses(inputs_hidden,
                         hidden,
                         model='''
                            tl                                                  : second
                            tp                                                  : second
                            tau1 = 0.0025                                       : second (shared)
                            tau2 = 0.000625                                     : second (shared)
                            tauL = 0.010                                        : second (shared)
                            tauLp = 0.1*tauL                                    : second (shared)

                            w                                                   : 1

                            up = (sign(t - tp) + 1.0) / 2                       : 1
                            ul = (sign(t - tl - 3*ms) + 1.0) / 2                : 1
                            u = (sign(t) + 1.0) / 2                             : 1

                            c = 100*exp((tp - t)/tau1) - exp((tp - t)/tau2)     : 1
                            f = w*c                                             : 1
                            D_post = w*c*ul                                     : 1 (summed) ''',
                         pre='tp=t',
                         post='tl=t',
                         name='synapses_hidden',
                         dt=self.dta)
        So = br.Synapses(
            inputs_out,
            output,
            model='''tl                                                  : second
                            tp                                                  : second
                            tau1 = 0.0025                                       : second (shared)
                            tau2 = 0.000625                                     : second (shared)
                            tauL = 0.010                                        : second (shared)
                            tauLp = 0.1*tauL                                    : second (shared)

                            w                                                   : 1

                            up = (sign(t - tp) + 1.0) / 2                       : 1
                            ul = (sign(t - tl - 3*ms) + 1.0) / 2                : 1
                            u = (sign(t) + 1.0) / 2                             : 1

                            c = 100*exp((tp - t)/tau1) - exp((tp - t)/tau2)     : 1
                            f = w*c                                             : 1
                            D_post = w*c*ul                                     : 1 (summed) ''',
            pre='tp=t',
            post='tl=t',
            name='synapses_output',
            dt=self.dta)
        #Rh = br.Synapses(hidden, hidden, pre='c_post=0', name='winner_take_all_a', dt=self.dta)
        #Ro = br.Synapses(output, output, pre='c_post=0', name='winner_take_all_b', dt=self.dta)

        #Rh.connect('i!=j')
        #Ro.connect('i!=j')
        Sh.connect('True')
        So.connect('True')

        Sh.w[:, :] = '(1000*rand()+1750)'
        So.w[:, :] = '(1000*rand()+1750)'
        #So.w[0, 1] = '700'
        Sh.tl[:, :] = '-1*second'
        Sh.tp[:, :] = '-1*second'
        So.tl[:, :] = '-1*second'
        So.tp[:, :] = '-1*second'
        hidden.v[:] = -70
        output.v[:] = -70
        M = br.StateMonitor(output, 'v', record=True, name='monitor_v')
        N = br.StateMonitor(So, 'c', record=True, name='monitor_o_c')
        #O = br.StateMonitor(S, 'tp', record=True, name='monitor_o')
        #F = br.StateMonitor(S, 'f', record=True, name='monitor_f')
        Th = br.SpikeMonitor(hidden, variables='v', name='crossings_h')
        To = br.SpikeMonitor(output, variables='v', name='crossings_o')
        self.net_hidden = br.Network(inputs_hidden, hidden, Sh, Th)
        self.net_out = br.Network(inputs_out, output, So, M, N, To)
        self.actual = self.net_out['crossings_o'].all_values()['t']
        self.net_hidden.store()
        self.net_out.store()
def construct_feedforward_input(NTWK, target_pop, afferent_pop,\
                                t, rate_array,\
                                additional_spikes={'indices':[], 'times':[]},
                                additional_spikes_in_terms_of_pre_pop={'indices':[], 'times':[]},
                                verbose=False,
                                SEED=1):
    """
    This generates an input asynchronous from post synaptic neurons to post-synaptic neurons

    POPS and AFFERENCE_ARRAY should be 1D arrrays as their is only one 
    source population

    'pop_for_conductance' is the string identifying the source conductance
    that will be incremented by the afferent input !!

    """

    Model = NTWK['Model']

    # Synapses  number ?
    Nsyn = Model['p_' + afferent_pop + '_' + target_pop] * Model['N_' +
                                                                 afferent_pop]

    if Nsyn > 0:  # if non-zero projection [...]

        # extract parameters of the afferent input
        Qsyn = Model['Q_' + afferent_pop + '_' + target_pop]

        #finding the target pop in the brian2 objects
        ipop = np.argwhere(NTWK['POPULATIONS'] == target_pop).flatten()[0]

        if verbose:
            print('drawing Poisson process for afferent input [...]')

        indices, times = spikes_from_time_varying_rate(t, rate_array,\
                                                       NTWK['POPS'][ipop].N,
                                                       Nsyn,
                                                       SEED=(SEED+2)**2%100)

        # adding the additional spikes (1)
        indices = np.concatenate([indices, additional_spikes['indices']])
        times = np.concatenate([times, additional_spikes['times']])

        # adding the additional spikes (2)
        if len(additional_spikes_in_terms_of_pre_pop['indices']) > 0:
            try:
                Matrix = NTWK['M_conn_' + afferent_pop + '_' + target_pop]
                indices2, times2 = translate_aff_spikes_into_syn_target_events(
                    np.array(additional_spikes_in_terms_of_pre_pop['indices'],
                             dtype=int),
                    additional_spikes_in_terms_of_pre_pop['times'], Matrix)
            except KeyError:
                print("""
                -------------------------------------------------
                Need to construct the afference to use this, with:
                ntwk.build_fixed_afference(NTWK,
                                           ['AffExc'],
                                           ['Exc', 'Inh', 'DsInh'])
                """)
        else:
            indices2, times2 = [], []

        indices = np.concatenate(
            [indices, indices2, additional_spikes['indices']])
        times = np.concatenate([times, times2, additional_spikes['times']])

        # insuring no more than one prespike per bin
        # indices, times = deal_with_multiple_spikes_per_bin(indices, times, t, verbose=verbose)

        # incorporating into Brian2 objects
        spikes = brian2.SpikeGeneratorGroup(NTWK['POPS'][ipop].N, indices,
                                            times * brian2.ms)
        # sorted = True, see "deal_with_multiple_spikes_per_bin"
        pre_increment = 'G' + afferent_pop + target_pop + ' += w'
        synapse = brian2.Synapses(spikes, NTWK['POPS'][ipop], on_pre=pre_increment,\
                                        model='w:siemens')
        synapse.connect('i==j')
        synapse.w = Qsyn * brian2.nS

        NTWK['PRE_SPIKES'].append(spikes)
        NTWK['PRE_SYNAPSES'].append(synapse)

    else:
        print('Nsyn = 0 for', afferent_pop + '_' + target_pop)
        spikes, synapse, indices, times, pre_indices, pre_times = None, None, [], [], [], []

    # afferent array
    NTWK['Rate_%s_%s' % (afferent_pop, target_pop)] = rate_array

    # storing quantities:
    if 'iRASTER_PRE' in NTWK.keys():
        NTWK['iRASTER_PRE'].append(indices)
        NTWK['tRASTER_PRE'].append(times)
    else:  # we create the key
        NTWK['iRASTER_PRE'] = [indices]
        NTWK['tRASTER_PRE'] = [times]
Esempio n. 14
0
def prespecified_spike_neurons(n_neurons, spike_indices, spike_times):
    neurons = b2.SpikeGeneratorGroup(
        N=n_neurons, indices=spike_indices, times=spike_times)
    return neurons
Esempio n. 15
0
tau1 = 5.00 * br.ms
tau2 = 1.25 * br.ms

#Ni = br.NeuronGroup(3, '''dv/dt = (vt - vr)/period : volt (unless refractory)
#                                period: second
#                                fire_once: boolean''', \
#                                threshold='v>vt', reset='v=vr',
#                                refractory='fire_once')
#Ni.period = [1, 1, 7] * br.ms
#Ni.fire_once[:] = [True] * 3

indices = np.asarray([0])
times = np.asarray([6]) * br.ms

Ni = br.SpikeGeneratorGroup(3, indices=indices, times=times)
#Nh = br.NeuronGroup(1, model="""dv/dt=(gtot-v)/(10*ms) : 1
#                                  gtot : 1""")
Nh = br.NeuronGroup(1,
                    model="""v = I :1
                                I : 1""")
S = br.Synapses(Ni,
                Nh,
                model='''tl : second
                    alpha=exp((tl - t)/tau1) - exp((tl - t)/tau2) : 1
                    w : 1
                    I_post = w*alpha : 1 (summed)
                 ''',
                pre='tl+=t - tl')
S.connect('True')
S.w[:, :] = '(80+rand())'
t = time.time()
samples, labels = convert_all_samples(orig_samples)
print(f'Conversion took {sec_to_str(time.time()-t)}')
# %%
threshold = 0.3
weights = np.random.normal(0, 1e-3, num_neurons)
init_w = weights.copy()
t = time.time()
print('Setting up network')
duration = 500
tau = 2 * ms
count = np.zeros((duration * 10, num_samples * num_neurons), int)
count[(samples['times'] * 10).astype(int), samples['inds'].astype(int)] = samples['counts']
eqs = 'dv/dt = -v / tau : 1'
target = b2.NeuronGroup(num_samples, eqs, threshold='v>threshold', reset='v=0')
driving = b2.SpikeGeneratorGroup(num_samples * num_neurons, samples['inds'], samples['times'] * ms)
counts = b2.TimedArray(count, dt=b2.defaultclock.dt)
synapses = b2.Synapses(driving, target, 'w: 1', on_pre='v+=w*counts(t, i)')
i = np.arange(num_samples * num_neurons)
j = np.array([[i] * num_neurons for i in range(num_samples)]).flatten()
synapses.connect(j=j, i=i)
synapses.w = np.tile(weights, num_samples)

s = b2.SpikeMonitor(target, record=True)
print(f'Finished network setup, took {sec_to_str(time.time()-t)}')
b2.run(duration * ms)

decision = s.count != 0
correct = decision == labels

print(correct.mean())
Esempio n. 17
0
    def __init__(
        self,
        weights: np.ndarray,
        weights_in: np.ndarray,
        dt: float = 0.1 * ms,
        noise_std: float = 0 * mV,
        refractory=0 * ms,
        neuron_params=None,
        syn_params=None,
        integrator_name: str = "rk4",
        name: str = "unnamed",
    ):
        """
        Construct a spiking recurrent layer with IAF neurons, with a Brian2 back-end

        :param weights:             np.array NxN weight matrix
        :param weights_in:             np.array 1xN input weight matrix.

        :param refractory: float Refractory period after each spike. Default: 0ms

        :param neuron_params:    dict Parameters to over overwriting neuron defaulst

        :param syn_params:    dict Parameters to over overwriting synapse defaulst

        :param integrator_name:   str Integrator to use for simulation. Default: 'exact'

        :param name:         str Name for the layer. Default: 'unnamed'
        """
        warn("RecDynapseBrian: This layer is deprecated.")

        # - Call super constructor
        super().__init__(
            weights=weights,
            dt=np.asarray(dt),
            noise_std=np.asarray(noise_std),
            name=name,
        )

        # - Input weights must be provided
        assert weights_in is not None, "weights_in must be provided."

        # - Warn that nosie is not implemented
        if noise_std != 0:
            print("WARNING: Noise is currently not implemented in this layer.")

        # - Set up spike source to receive spiking input
        self._input_generator = b2.SpikeGeneratorGroup(
            self.size, [0], [0 * second], dt=np.asarray(dt) * second)

        # - Handle unit of dt: if no unit provided, assume it is in seconds
        dt = np.asscalar(np.array(dt)) * second

        ### --- Neurons

        # - Set up reservoir neurons
        self._neuron_group = teiliNG(
            N=self.size,
            equation_builder=teiliDPIEqts(num_inputs=2),
            name="reservoir_neurons",
            refractory=refractory,
            method=integrator_name,
            dt=dt,
        )

        # - Overwrite default neuron parameters
        if neuron_params is not None:
            self._neuron_group.set_params(
                dict(dTeiliNeuronParam, **neuron_params))
        else:
            self._neuron_group.set_params(dTeiliNeuronParam)

        ### --- Synapses

        # - Add recurrent synapses (all-to-all)
        self._rec_synapses = teiliSyn(
            self._neuron_group,
            self._neuron_group,
            equation_builder=teiliDPISynEqts,
            method=integrator_name,
            dt=dt,
            name="reservoir_recurrent_synapses",
        )
        self._rec_synapses.connect()

        # - Add source -> reservoir synapses (one-to-one)
        self._inp_synapses = teiliSyn(
            self._input_generator,
            self._neuron_group,
            equation_builder=teiliDPISynEqts,
            method=integrator_name,
            dt=np.asarray(dt) * second,
            name="receiver_synapses",
        )
        # Each spike generator neuron corresponds to one reservoir neuron
        self._inp_synapses.connect("i==j")

        # - Overwrite default synapse parameters
        if syn_params is not None:
            self._rec_synapses.set_params(neuron_params)
            self._inp_synapses.set_params(neuron_params)

        # - Add spike monitor to record layer outputs
        self._spike_monitor = b2.SpikeMonitor(self._neuron_group,
                                              record=True,
                                              name="layer_spikes")

        # - Call Network constructor
        self._net = b2.Network(
            self._neuron_group,
            self._rec_synapses,
            self._input_generator,
            self._inp_synapses,
            self._spike_monitor,
            name="recurrent_spiking_layer",
        )

        # - Record neuron / synapse parameters
        # automatically sets weights  via setters
        self.weights = weights
        self.weights_in = weights_in

        # - Store "reset" state
        self._net.store("reset")
Esempio n. 18
0
    def __init__(
        self,
        weights: Union[np.ndarray, int] = None,
        dt: float = 0.1 * ms,
        noise_std: float = 0 * mV,
        tau_syn: float = 5 * ms,
        synapse_eq=eqSynapseExp,
        integrator_name: str = "rk4",
        name: str = "unnamed",
    ):
        """
        Construct an exponential synapse layer (spiking input), with a Brian2 backend

        :param weights:             np.array MxN weight matrix
                                int Size of layer -> creates one-to-one conversion layer
        :param dt:             float Time step for state evolution. Default: 0.1 ms
        :param noise_std:       float Std. dev. of noise added to this layer. Default: 0

        :param tau_syn:         float Output synaptic time constants. Default: 5ms
        :param synapse_eq:      Brian2.Equations set of synapse equations for receiver. Default: exponential
        :param integrator_name:   str Integrator to use for simulation. Default: 'exact'

        :param name:         str Name for the layer. Default: 'unnamed'
        """
        warn(
            "FFExpSynBrian - This layer is deprecated. You can use FFExpSyn or FFExpSynTorch instead."
        )

        # - Provide default dt
        if dt is None:
            dt = 0.1 * ms

        # - Provide default weight matrix for one-to-one conversion
        if isinstance(weights, int):
            weights = np.identity(weights, "float")

        # - Call super constructor
        super().__init__(weights=weights, dt=dt, noise_std=noise_std, name=name)

        # - Set up spike source to receive spiking input
        self._input_generator = b2.SpikeGeneratorGroup(
            self.size_in, [0], [0 * second], dt=np.asarray(dt) * second
        )

        # - Set up layer receiver nodes
        self._neuron_group = b2.NeuronGroup(
            self.size,
            synapse_eq,
            refractory=False,
            method=integrator_name,
            dt=np.asarray(dt) * second,
            name="receiver_neurons",
        )

        # - Add source -> receiver synapses
        self._inp_synapses = b2.Synapses(
            self._input_generator,
            self._neuron_group,
            model="w : 1",
            on_pre="I_syn_post += w*amp",
            method=integrator_name,
            dt=np.asarray(dt) * second,
            name="receiver_synapses",
        )
        self._inp_synapses.connect()

        # - Add current monitors to record reservoir outputs
        self._state_monitor = b2.StateMonitor(
            self._neuron_group, "I_syn", True, name="receiver_synaptic_currents"
        )

        # - Call Network constructor
        self._net = b2.Network(
            self._input_generator,
            self._neuron_group,
            self._inp_synapses,
            self._state_monitor,
            name="ff_spiking_to_exp_layer",
        )

        # - Record layer parameters, set weights
        self.weights = weights
        self.tau_syn = tau_syn

        # - Store "reset" state
        self._net.store("reset")
                                '''
                       },
                       on_event={
                           'pre': 'spike',
                           'inh_done': 'stop_inhibition'
                       })
S_inhibit.connect(condition='i!=j', p=1)
print("done")

# -------------
# Input Stimuli
# -------------
print("Loading input stimuli... ", end='', flush=True)
stimuli = np.load(stimuli_filename)
times = [a * b.second for a in stimuli[0]]
G_in = b.SpikeGeneratorGroup(1, indices=stimuli[1], times=times)
print("done")

# -----------------------
# Creating input Synapses
# ------------------------
print("Preparing input synapse... ", end='', flush=True)
model = '''
w : 1
dApre/dt = -Apre/tau_Apre : 1 (event-driven)
dApost/dt = -Apost/tau_Apost : 1 (event-driven)
'''
stdp_pre = '''
v_post = (v_post + w*int(not_inhibited))*int(v_post <= v_max - w) + v_max*int(v_post > v_max-w);
Apre = Apre_reset;
w -= Apost*int(w > w_min + Apost) + w_min*int(w <= w_min + Apost)'''
Esempio n. 20
0
    def __init__(self, num_neurons, tau, threshold, duration=500):
        # TODO: Include t_max and v_max variables in the brian model, have them updated per-spike and try to create a custom event when t=t(end) to update the model weights
        #
        self.duration = duration * ms
        self.num_neurons = num_neurons
        self.threshold = threshold
        self.tau = tau * ms

        # Helper variables
        self._count_mat = np.zeros((duration * 10, self.num_neurons), int)
        # Synaptic efficacies
        self.weights = np.random.normal(0, 1e-3, num_neurons)

        # Model definition
        b2.start_scope()
        eqs = 'dv/dt = -v / tau: 1'
        self.counts = b2.TimedArray(self._count_mat, dt=b2.defaultclock.dt)

        # Evaluation network
        self.target = b2.NeuronGroup(1,
                                     eqs,
                                     threshold='v>threshold',
                                     reset='v=0',
                                     namespace={
                                         'tau': self.tau,
                                         'threshold': self.threshold
                                     })
        self.driving = b2.SpikeGeneratorGroup(self.num_neurons, [0], [0] * ms)

        self.spike_response = 'v+=w*counts(t, i)'
        self.synapses = b2.Synapses(self.driving,
                                    self.target,
                                    'w: 1',
                                    on_pre=self.spike_response)
        self.synapses.connect(i=list(range(self.num_neurons)), j=0)
        self.synapses.w = self.weights

        self.voltage = b2.StateMonitor(self.target, 'v', record=True)
        self.spikes = b2.SpikeMonitor(self.target, record=True)

        self.net = b2.Network(self.target, self.driving, self.synapses,
                              self.voltage, self.spikes)
        self.net.store()

        # Training network
        self.target_train = b2.NeuronGroup(self.num_neurons,
                                           eqs,
                                           namespace={'tau': self.tau})
        self.driving_train = b2.SpikeGeneratorGroup(self.num_neurons, [0],
                                                    [0] * ms)

        self.train_response = 'v+=1*counts(t, i)'
        self.synapses_train = b2.Synapses(self.driving_train,
                                          self.target_train,
                                          'w: 1',
                                          on_pre=self.train_response)
        self.synapses_train.connect(condition='i==j')
        self.synapses_train.w = self.weights

        self.voltage_train = b2.StateMonitor(self.target_train,
                                             'v',
                                             record=True)

        self.net_train = b2.Network(self.target_train, self.driving_train,
                                    self.synapses_train, self.voltage_train)
        self.net_train.store()

        self.debug_0 = 0  # For debugging problematic samples