Ejemplo n.º 1
0
def get_phi_spiker(neuron=None):
    """
    returns a somatic spiker that implements an inhomogenuous poisson process,
    i.e. a spike will be elicited with probability dt*firing_rate
    """
    if neuron is None:
        neuron = get_default("neuron")
    return lambda curr, dt, **kwargs: phi(curr['y'][0], neuron) * dt >= np.random.rand()
Ejemplo n.º 2
0
def get_phi_spiker(neuron=None):
    """
    returns a somatic spiker that implements an inhomogenuous poisson process,
    i.e. a spike will be elicited with probability dt*firing_rate
    """
    if neuron is None:
        neuron = get_default("neuron")
    return lambda curr, dt, **kwargs: phi(curr['y'][0], neuron
                                          ) * dt >= np.random.rand()
Ejemplo n.º 3
0
def run(sim,
        spiker,
        spiker_dendr,
        accumulators,
        neuron,
        learn,
        **kwargs):
    """ this is the main simulation routine.

    Arguments:

    sim -- a dictionary containing the following simulation parameters
        start:      starting time
        end:        ending time
        dt:         time step
        I_ext:      function for evaluating externally applied current
        pre_spikes: a list of presynaptic spikes
    spiker       -- the somatic spiker
    spiker_dendr -- the dendritic spiker
    accumulators -- a list of accumulators for saving model variables during the simulation
    neuron       -- a dictionary containing the neuron parameters, default_neuron is 
                    used if none specified
    learn        -- a dictionary contianing the learning parameters, default_learn is used 
                    if none specified
    returns:
    a list of accumulators containing simulation results
    """

    use_seed = kwargs.get('seed', 0)
    np.random.seed(use_seed)

    # restrict to positive weights by default
    normalizer = lambda weights: np.where(weights > 0, weights, 0.0)

    # set some default parameters
    p_backprop      = 1.0
    syn_cond_soma = sim.get('syn_cond_soma', {sym: lambda t: 0.0 for sym in ['E', 'I']})
    # ここはデフォルトのphi()を使っている
    dendr_predictor = kwargs.get('dendr_predictor', phi)

    # これはずっと0
    I_ext = sim.get('I_ext', step_current(np.array([[sim['start'], 0.0]])))

    # ensure numpy arrays, for fancy indexing
    pre_spikes = sim['pre_spikes']
    for i, pre_sp in enumerate(pre_spikes):
        pre_spikes[i] = np.array(pre_sp)

    n_syn = len(pre_spikes)
    for key in ['eps', 'eta', 'tau_delta']:
        if not isinstance(learn[key], collections.Iterable):
            learn[key] = np.array([learn[key] for _ in range(n_syn)])
    for acc in accumulators:
        acc.prepare_arrays(n_syn)
        
    t_start = sim['start']
    t_end   = sim['end']
    dt      = sim['dt']
    
    U0 = neuron['E_L']

    curr = {
        't': t_start,
        'y': np.concatenate((np.array([U0, neuron['E_L'], neuron['E_L']]),
                             np.zeros(2 * n_syn)))
        # yは203個になる
        # 最初の3つは[U, V, V_w_star]
        # それ以降は[dV_dws, dV_w_star_dws]の繰り返し
    }
    last_spike = {
        't': float('-inf'),
        'y': curr['y']
    }
    last_spike_dendr = {
        't': float('-inf'),
        'y': curr['y']
    }

    weights = np.array(learn['eps'])

    g_E_Ds         = np.zeros(n_syn)
    syn_pots_sums  = np.zeros(n_syn)
    PIVs           = np.zeros(n_syn)
    deltas         = np.zeros(n_syn)
    weight_updates = np.zeros(n_syn)
    
    while curr['t'] < t_end - dt / 2:
        # currにはtとyが入っている.
        # curr['y'] = (203,)
        
        #print("t={}, t_end={}".format(curr['t'], t_end)) #..
        
        # for each synapse: is there a presynaptic spike at curr['t']?
        # 各ニューロンのpre synapseニューロンが発火したかどうか
        curr_pres = np.array([np.sum(np.isclose(pre_sp, curr['t'],
                                                rtol=1e-10,
                                                atol=1e-10)) for pre_sp in pre_spikes])
        # (100,)の 0or1 (2以上の場合もありうる)

        g_E_Ds = g_E_Ds + curr_pres * weights
        g_E_Ds = g_E_Ds - dt * g_E_Ds / neuron['tau_s'] # 時定数で減衰
        # (100,)

        # 現在時刻tより前のpre synapse発火タイミングでのexponentialを加算する
        syn_pots_sums = np.array(
            [np.sum(np.exp(-(curr['t'] - pre_sp[pre_sp <= curr['t']]) / neuron['tau_s'])) \
             for pre_sp in pre_spikes])
        # (100,)

        # is there a postsynaptic spike at curr['t']?
        if curr['t'] - last_spike['t'] < neuron['tau_ref']:
            # refractory period中だった場合
            does_spike = False
        else:
            does_spike = spiker(curr=curr, dt=dt)
            # sineタスクの場合はdoes_spikeがtrueになることが無い

        if does_spike:
            last_spike = {'t': curr['t'],
                          'y': curr['y']}

        # does the dendrite detect a spike?
        dendr_spike = spiker_dendr(curr=curr,
                                   last_spike=last_spike,
                                   last_spike_dendr=last_spike_dendr)
        # floatの値, phi(U) * dt

        if dendr_spike:
            last_spike_dendr = {'t': curr['t'],
                                'y': curr['y']}

        # dendritic prediction
        # V_w_starから予測 (sigmoidを使ったphi(V_w_star))
        dendr_pred = dendr_predictor(curr['y'][2], neuron)
        # 指定されたh or phi_prime(V_w_star) / phi(V_w_star)
        h = kwargs.get('h', phi_prime(curr['y'][2], neuron) / phi(curr['y'][2], neuron))

        # update weights
        # 重みの更新
        # dV_w_star_dws
        # (delta_factorは1.0)
        pos_PIVs = neuron['delta_factor'] * float(dendr_spike) / dt * h * curr['y'][4::2]
        neg_PIVs = dendr_pred                                       * h * curr['y'][4::2]
        PIVs = pos_PIVs - neg_PIVs # (phi(U) - phi(V_w_star)) * h * dV_w_star_dws
        deltas += dt * (PIVs - deltas) / learn['tau_delta']
        weight_updates = learn['eta'] * deltas
        weights = normalizer(weights + weight_updates)

        # advance state: integrate from curr['t'] to curr['t']+dt
        curr_I = I_ext(curr['t'])
        args = (curr['y'],
                curr['t'],
                curr['t'] - last_spike['t'],
                g_E_Ds,
                syn_pots_sums,
                curr_I,
                neuron,
                syn_cond_soma,
                p_backprop)
        curr['y'] += dt * urb_senn_rhs(*args)
        curr['t'] += dt

        # save state
        vals = {
            'g_E_Ds'        : g_E_Ds,
            'syn_pots_sums' : syn_pots_sums,
            'y'             : curr['y'],
            'spike'         : float(does_spike),
            'dendr_pred'    : dendr_pred,
            'h'             : h,
            'PIVs'          : PIVs,
            'pos_PIVs'      : pos_PIVs,
            'neg_PIVs'      : neg_PIVs,
            'dendr_spike'   : float(dendr_spike),
            'pre_spikes'    : curr_pres,
            'weights'       : weights,
            'weight_updates': weight_updates,
            'deltas'        : deltas,
            'I_ext'         : curr_I
        }
        for acc in accumulators:
            acc.add(curr['t'], **vals)

    for acc in accumulators:
        acc.cleanup()
        acc.add_variable('seed', use_seed)

    return accumulators
Ejemplo n.º 4
0
 def phi_U_learner(curr, **kwargs):
     # phi(U) * dtを返す
     return factor * phi(curr['y'][0], neuron) * dt
Ejemplo n.º 5
0
def run(sim,
        spiker,
        spiker_dendr,
        accumulators,
        neuron=None,
        learn=None,
        normalizer=None,
        **kwargs):
    """ this is the main simulation routine.

    Arguments:

    sim -- a dictionary containing the following simulation parameters
        start:      starting time
        end:        ending time
        dt:         time step
        I_ext:      function for evaluating externally applied current
        pre_spikes: a list of presynaptic spikes
    spiker       -- the somatic spiker
    spiker_dendr -- the dendritic spiker
    accumulators -- a list of accumulators for saving model variables during the simulation
    neuron       -- a dictionary containing the neuron parameters, default_neuron is 
                    used if none specified
    learn        -- a dictionary contianing the learning parameters, default_learn is used 
                    if none specified
    normalizer   -- a function to normalize synaptic weights, e.g. the default normalizer
                    ensures non-negative weights
    returns:
    a list of accumulators containing simulation results
    """

    use_seed = kwargs.get('seed', 0)
    np.random.seed(use_seed)

    if neuron is None:
        neuron = get_default('neuron')

    if learn is None:
        learn = get_default('learn')

    # restrict to positive weights by default
    if normalizer is None:
        normalizer = lambda weights: np.where(weights > 0, weights, 0.0)

    # set some default parameters
    p_backprop      = kwargs.get('p_backprop', 1.0)
    syn_cond_soma = sim.get('syn_cond_soma', {sym: lambda t: 0.0 for sym in ['E', 'I']})
    dendr_predictor = kwargs.get('dendr_predictor', phi)

    I_ext = sim.get('I_ext', step_current(np.array([[sim['start'], 0.0]])))

    # ensure numpy arrays, for fancy indexing
    pre_spikes = sim['pre_spikes']
    for i, pre_sp in enumerate(pre_spikes):
        pre_spikes[i] = np.array(pre_sp)

    n_syn = len(pre_spikes)
    
    for key in ['eps', 'eta', 'tau_delta']:
        if not isinstance(learn[key], collections.Iterable):
            learn[key] = np.array([learn[key] for _ in range(n_syn)])
    for acc in accumulators:
        acc.prepare_arrays(n_syn)
        
    t_start = sim['start']
    t_end   = sim['end']
    dt      = sim['dt']
    
    U0 = neuron['E_L']

    curr = {
        't': t_start,
        'y': np.concatenate((np.array([U0, neuron['E_L'], neuron['E_L']]),
                             np.zeros(2 * n_syn)))}
    last_spike = {
        't': float('-inf'),
        'y': curr['y']
    }
    last_spike_dendr = {
        't': float('-inf'),
        'y': curr['y']
    }

    weights = np.array(learn['eps'])

    g_E_Ds         = np.zeros(n_syn)
    syn_pots_sums  = np.zeros(n_syn)
    PIVs           = np.zeros(n_syn)
    deltas         = np.zeros(n_syn)
    weight_updates = np.zeros(n_syn)
    
    while curr['t'] < t_end - dt / 2:
        #print("t={}, t_end={}".format(curr['t'], t_end)) #..
        
        # for each synapse: is there a presynaptic spike at curr['t']?
        curr_pres = np.array([np.sum(np.isclose(pre_sp, curr['t'],
                                                rtol=1e-10,
                                                atol=1e-10)) for pre_sp in pre_spikes])

        g_E_Ds = g_E_Ds + curr_pres * weights
        g_E_Ds = g_E_Ds - dt * g_E_Ds / neuron['tau_s']

        syn_pots_sums = np.array(
            [np.sum(np.exp(-(curr['t'] - pre_sp[pre_sp <= curr['t']]) / neuron['tau_s'])) \
             for pre_sp in pre_spikes])

        # is there a postsynaptic spike at curr['t']?
        if curr['t'] - last_spike['t'] < neuron['tau_ref']:
            does_spike = False
        else:
            does_spike = spiker(curr=curr, dt=dt)

        if does_spike:
            last_spike = {'t': curr['t'],
                          'y': curr['y']}

        # does the dendrite detect a spike?
        dendr_spike = spiker_dendr(curr=curr,
                                   last_spike=last_spike,
                                   last_spike_dendr=last_spike_dendr)

        if dendr_spike:
            last_spike_dendr = {'t': curr['t'], 'y': curr['y']}

        # dendritic prediction
        dendr_pred = dendr_predictor(curr['y'][2], neuron)
        h = kwargs.get('h', phi_prime(curr['y'][2], neuron) / phi(curr['y'][2], neuron))

        # update weights
        pos_PIVs = neuron['delta_factor'] * float(dendr_spike) / dt * h * curr['y'][4::2]
        neg_PIVs = dendr_pred                                       * h * curr['y'][4::2]
        PIVs = pos_PIVs - neg_PIVs
        deltas += dt * (PIVs - deltas) / learn['tau_delta']
        weight_updates = learn['eta'] * deltas
        weights = normalizer(weights + weight_updates)

        # advance state: integrate from curr['t'] to curr['t']+dt
        curr_I = I_ext(curr['t'])
        args = (curr['y'],
                curr['t'],
                curr['t'] - last_spike['t'],
                g_E_Ds,
                syn_pots_sums,
                curr_I,
                neuron,
                syn_cond_soma,
                p_backprop)
        curr['y'] += dt * urb_senn_rhs(*args)
        curr['t'] += dt

        # save state
        vals = {
            'g_E_Ds'        : g_E_Ds,
            'syn_pots_sums' : syn_pots_sums,
            'y'             : curr['y'],
            'spike'         : float(does_spike),
            'dendr_pred'    : dendr_pred,
            'h'             : h,
            'PIVs'          : PIVs,
            'pos_PIVs'      : pos_PIVs,
            'neg_PIVs'      : neg_PIVs,
            'dendr_spike'   : float(dendr_spike),
            'pre_spikes'    : curr_pres,
            'weights'       : weights,
            'weight_updates': weight_updates,
            'deltas'        : deltas,
            'I_ext'         : curr_I
        }
        for acc in accumulators:
            acc.add(curr['t'], **vals)

    for acc in accumulators:
        acc.cleanup()
        acc.add_variable('seed', use_seed)

    return accumulators
Ejemplo n.º 6
0
 def phi_U_learner(curr, **kwargs):
     return factor * phi(curr['y'][0], neuron) * dt
Ejemplo n.º 7
0
 def dendr_predictor(V, neuron):
     return np.sum([phi(V,{'phi':{'alpha': al, 'beta':p["beta_wiggle"], 'r_max': r_m}}) for al in alphas])
Ejemplo n.º 8
0
def task((repetition_i, p)):

    n_syn = p["n_syn"]

    learn = get_default("learn")
    learn["eps"] = 1e-1 / (1.0 * n_syn)
    learn["eta"] = learn["eps"] * p["eps_factor"]

    neuron = get_default("neuron")
    neuron["phi"]["alpha"] = p["alpha"]
    neuron["phi"]["beta"] = p["beta"]
    neuron["phi"]["r_max"] = 0.1
    neuron["g_S"] = p["g_S"]

    learn_epochs = 2
    test_epochs = 1
    epochs = learn_epochs + test_epochs
    l_c = 4
    eval_c = 2
    cycles = epochs * l_c + (epochs + 1) * eval_c
    cycle_dur = p["cycle_dur"]
    epoch_dur = (l_c + eval_c) * cycle_dur
    t_end = cycles * cycle_dur

    g_factor = p["g_factor"]

    def exc_soma_cond(t):
        if t % (cycle_dur * (l_c + eval_c)) < cycle_dur * eval_c or t > learn_epochs * epoch_dur:
            return 0.0
        return p["exc_level"] * p["g_factor"]

    def inh_soma_cond(t):
        if t % (cycle_dur * (l_c + eval_c)) < cycle_dur * eval_c or t > learn_epochs * epoch_dur:
            return 0.0
        return 1e-1 * p["g_factor"]

    dt = 0.05
    f_r = 1.0 / cycle_dur
    t_pts = np.arange(0, t_end / cycles, dt)

    seed = int(int(time.time() * 1e8) % 1e9)

    reg_spikes = [np.arange(i+1,t_end+1,10) for i in range(n_syn)]

    poisson_spikes = [t_pts[np.random.rand(t_pts.shape[0]) < f_r * dt] for _ in range(n_syn)]
    poisson_spikes = [[] if spikes.shape[0] == 0 else np.concatenate(
        [np.arange(spike, t_end, cycle_dur) for spike in spikes]) for spikes in poisson_spikes]
    for train in poisson_spikes:
        train.sort()

    my_s = {
        'start': 0.0,
        'end': t_end,
        'dt': dt,
        'pre_spikes': reg_spikes,
        'syn_cond_soma': {'E': exc_soma_cond, 'I': inh_soma_cond},
        'I_ext': lambda t: 0.0
    }

    phi_spiker = get_phi_spiker(neuron)

    # deprecated
    def my_spiker(curr, dt, **kwargs):
        # we want no spikes in eval cycles
        if curr['t'] % (cycle_dur * (l_c + eval_c)) < cycle_dur * eval_c:
            return False
        else:
            return phi_spiker(curr, dt, **kwargs)

    if p["wiggle"] is None:
        dendr_predictor = phi
    else:
        us = np.linspace(-100,20,1000)
        ampl = neuron["phi"]["r_max"]
        phis = phi(us, neuron)
        alphas = []
        for i in range(p["wiggle"]):
            alphas.append(us[phis > (i+0.5)*ampl/p["wiggle"]][0])
        r_m = neuron['phi']['r_max']/p["wiggle"]
        def dendr_predictor(V, neuron):
            return np.sum([phi(V,{'phi':{'alpha': al, 'beta':p["beta_wiggle"], 'r_max': r_m}}) for al in alphas])


    accs = [PeriodicAccumulator(get_all_save_keys(), interval=20,
                                y_keep=3), BooleanAccumulator(['spike'])]
    accums = run(my_s, get_fixed_spiker(np.array([])), get_phi_U_learner(neuron, dt, p["exc_decrease"]),
                 accs, neuron=neuron, seed=seed, learn=learn, dendr_predictor=dendr_predictor)

    dump((seed, accums), 'wiggle_test/' + p['ident'])
Ejemplo n.º 9
0
def run(sim, spiker, spiker_dendr, accumulators, neuron=None, learn=None, normalizer=None, **kwargs):
    """ this is the main simulation routine, can either be called directly, or with
    the convenience routine do in helper.py
    arguments:
    sim -- a dictionary containing the following simulation parameters
        start: starting time
        end: ending time
        dt: time step
        I_ext: function for evaluating externally applied current
        pre_spikes: a list of presynaptic spikes
    spiker -- the somatic spiker
    spiker_dendr -- the dendritic spiker
    accumulators -- a list of accumulators for saving model variables during the simulation
    neuron -- a dictionary containing the neuron parameters, default_neuron is used if none specified
    learn -- a dictionary contianing the learning parameters, default_learn is used if none specified
    normalizer -- a function to normalize synaptic weights, e.g. the default normalizer
        ensures non-negative weights
    returns:
    a list of accumulators containing simulation results
    """

    use_seed = kwargs.get('seed', 0)
    np.random.seed(use_seed)

    if neuron is None:
        neuron = get_default('neuron')

    if learn is None:
        learn = get_default('learn')

    # restrict to positive weights by default
    if normalizer is None:
        normalizer = lambda weights: np.where(weights > 0, weights, 0.0)

    # set some default parameters
    voltage_clamp = kwargs.get('voltage_clamp', False)
    p_backprop = kwargs.get('p_backprop', 1.0)
    syn_cond_soma = sim.get('syn_cond_soma', {sym: lambda t: 0.0 for sym in ['E', 'I']})
    dendr_predictor = kwargs.get('dendr_predictor', phi)

    I_ext = sim.get('I_ext', step_current(np.array([[sim['start'], 0.0]])))

    # ensure numpy arrays, for fancy indexing
    pre_spikes = sim['pre_spikes']
    for i, pre_sp in enumerate(pre_spikes):
        pre_spikes[i] = np.array(pre_sp)

    n_syn = len(pre_spikes)
    for key in ['eps', 'eta', 'tau_delta']:
        if not isinstance(learn[key], collections.Iterable):
            learn[key] = np.array([learn[key] for _ in range(n_syn)])
    for acc in accumulators:
        acc.prepare_arrays(n_syn)

    t_start, t_end, dt = sim['start'], sim['end'], sim['dt']

    if voltage_clamp:
        U0 = kwargs['U_clamp']
    else:
        U0 = neuron['E_L']

    curr = {'t': t_start,
            'y': np.concatenate((np.array([U0, neuron['E_L'], neuron['E_L']]), np.zeros(2 * n_syn)))}
    last_spike = {'t': float('-inf'), 'y': curr['y']}
    last_spike_dendr = {'t': float('-inf'), 'y': curr['y']}

    weights = np.array(learn['eps'])

    g_E_Ds = np.zeros(n_syn)
    syn_pots_sums = np.zeros(n_syn)
    PIVs = np.zeros(n_syn)
    deltas = np.zeros(n_syn)
    weight_updates = np.zeros(n_syn)
    while curr['t'] < t_end - dt / 2:

        # for each synapse: is there a presynaptic spike at curr['t']?
        curr_pres = np.array(
            [np.sum(np.isclose(pre_sp, curr['t'], rtol=1e-10, atol=1e-10)) for pre_sp in pre_spikes])

        g_E_Ds = g_E_Ds + curr_pres * weights
        g_E_Ds = g_E_Ds - dt * g_E_Ds / neuron['tau_s']

        syn_pots_sums = np.array(
            [np.sum(np.exp(-(curr['t'] - pre_sp[pre_sp <= curr['t']]) / neuron['tau_s'])) for pre_sp in pre_spikes])

        # is there a postsynaptic spike at curr['t']?
        if curr['t'] - last_spike['t'] < neuron['tau_ref']:
            does_spike = False
        else:
            does_spike = spiker(curr=curr, dt=dt)

        if does_spike:
            last_spike = {'t': curr['t'], 'y': curr['y']}

        # does the dendrite detect a spike?
        dendr_spike = spiker_dendr(curr=curr, last_spike=last_spike,
                                   last_spike_dendr=last_spike_dendr)

        if dendr_spike:
            last_spike_dendr = {'t': curr['t'], 'y': curr['y']}

        # dendritic prediction
        dendr_pred = dendr_predictor(curr['y'][2], neuron)
        h = kwargs.get('h', phi_prime(curr['y'][2], neuron) / phi(curr['y'][2], neuron))

        # update weights
        pos_PIVs = neuron['delta_factor'] * float(dendr_spike) / dt * h * curr['y'][4::2]
        neg_PIVs = dendr_pred * h * curr['y'][4::2]
        PIVs = pos_PIVs - neg_PIVs
        deltas += dt * (PIVs - deltas) / learn['tau_delta']
        weight_updates = learn['eta'] * deltas
        weights = normalizer(weights + weight_updates)

        # advance state: integrate from curr['t'] to curr['t']+dt
        curr_I = I_ext(curr['t'])
        args = (curr['y'], curr['t'], curr['t'] - last_spike['t'], g_E_Ds,
                syn_pots_sums, curr_I, neuron, syn_cond_soma, voltage_clamp, p_backprop)
        curr['y'] += dt * urb_senn_rhs(*args)
        curr['t'] += dt

        # save state
        vals = {'g_E_Ds': g_E_Ds,
                'syn_pots_sums': syn_pots_sums,
                'y': curr['y'],
                'spike': float(does_spike),
                'dendr_pred': dendr_pred,
                'h': h,
                'PIVs': PIVs,
                'pos_PIVs': pos_PIVs,
                'neg_PIVs': neg_PIVs,
                'dendr_spike': float(dendr_spike),
                'pre_spikes': curr_pres,
                'weights': weights,
                'weight_updates': weight_updates,
                'deltas': deltas,
                'I_ext': curr_I}
        for acc in accumulators:
            acc.add(curr['t'], **vals)

    for acc in accumulators:
        acc.cleanup()
        acc.add_variable('seed', use_seed)

    return accumulators