Beispiel #1
0
    def build_genn_neuron(self, native_params, init_vals):
        # Create model using unmodified defs
        genn_model = create_custom_neuron_class(self.genn_neuron_name,
                                                **self.neuron_defs.definitions)

        # Get spike times
        spk_times = native_params["spikeTimes"]

        # Create empty numpy arrays to hold start and end spikes indices
        start_spike = np.empty(shape=native_params.shape, dtype=np.uint32)
        end_spike = np.empty(shape=native_params.shape, dtype=np.uint32)

        # Calculate indices for each sequence
        cum_size = 0
        for i, seq in enumerate(spk_times):
            start_spike[i] = cum_size
            cum_size += len(seq.value)
            end_spike[i] = cum_size

        # Build initialisation dictionary
        neuron_ini = {"startSpike": start_spike, "endSpike": end_spike}

        # Return with model
        return genn_model, {}, neuron_ini
Beispiel #2
0
import numpy as np
import matplotlib.pyplot as plt

from pygenn.genn_model import GeNNModel
from pygenn.genn_wrapper import NO_DELAY
from pygenn.genn_model import create_custom_weight_update_class
from pygenn.genn_model import create_custom_neuron_class


if_model = create_custom_neuron_class(
    "if_model",
    param_names=["Vtheta", "lambda", "Vrest", "Vreset"],
    var_name_types=[("V", "scalar")],
    sim_code="""
    if ($(V) >= $(Vtheta)) {
        $(V) = $(Vreset);
    }
    $(V) += (-$(lambda) + $(Isyn)) * DT;
    $(V) = fmax($(V), $(Vrest));
    """,
    reset_code="""
    """,
    threshold_condition_code="$(V) >= $(Vtheta)")

fusi_model = create_custom_weight_update_class(
    "fusi_model",
    param_names=["tauC", "a", "b", "thetaV", "thetaLUp", "thetaLDown", "thetaHUp", "thetaHDown",
                 "thetaX", "alpha", "beta", "Xmax", "Xmin", "JC", "Jplus", "Jminus"],
    var_name_types=[("X", "scalar")],
    post_var_name_types=[("C", "scalar")],
    sim_code="""
    $(addToInSyn, (($(X) > $(thetaX)) ? $(Jplus) : $(Jminus)));
Beispiel #3
0
fs_relu_input_model = create_custom_neuron_class(
    'fs_relu_input',
    param_names=['K', 'alpha'],
    derived_params=[
        ("scale", create_dpf_class(lambda pars, dt: pars[1] * 2**(-pars[0]))())
    ],
    var_name_types=[('input', 'scalar', VarAccess_READ_ONLY_DUPLICATE),
                    ('Vmem', 'scalar')],
    sim_code='''
    // Convert K to integer
    const int kInt = (int)$(K);
    
    // Get timestep within presentation
    const int pipeTimestep = (int)($(t) / DT);

    // If this is the first timestep, apply input
    if(pipeTimestep == 0) {
        $(Vmem) = $(input);
    }
    
    const scalar hT = $(scale) * (1 << (kInt - (1 + pipeTimestep)));
    ''',
    threshold_condition_code='''
    $(Vmem) >= hT
    ''',
    reset_code='''
    $(Vmem) -= hT;
    ''',
    is_auto_refractory_required=False)
Beispiel #4
0
#----------------------------------------------------------------------------
recurrent_alif_model = genn_model.create_custom_neuron_class(
    "recurrent_alif",
    param_names=["TauM", "TauAdap", "Vthresh", "TauRefrac", "Beta"],
    var_name_types=[("V", "scalar"), ("A", "scalar"), ("RefracTime", "scalar"),
                    ("E", "scalar")],
    additional_input_vars=[("ISynFeedback", "scalar", 0.0)],
    derived_params=[
        ("Alpha",
         genn_model.create_dpf_class(lambda pars, dt: np.exp(-dt / pars[0]))()
         ),
        ("Rho",
         genn_model.create_dpf_class(lambda pars, dt: np.exp(-dt / pars[1]))())
    ],
    sim_code="""
    $(E) = $(ISynFeedback);
    $(V) = ($(Alpha) * $(V)) + $(Isyn);
    $(A) *= $(Rho);
    if ($(RefracTime) > 0.0) {
      $(RefracTime) -= DT;
    }
    """,
    reset_code="""
    $(RefracTime) = $(TauRefrac);
    $(V) -= $(Vthresh);
    $(A) += 1.0;
    """,
    threshold_condition_code="""
    $(RefracTime) <= 0.0 && $(V) >= ($(Vthresh) + ($(Beta) * $(A)))
    """,
    is_auto_refractory_required=False)
Beispiel #5
0
lif_e_model = genn_model.create_custom_neuron_class(
    "lif_e_model",
    param_names=[
        "Tau", "Erest", "Vreset", "Vthres", "RefracPeriod", "tauTheta"
    ],
    var_name_types=[("V", "scalar"), ("RefracTime", "scalar"),
                    ("theta", "scalar"), ("SpikeNumber", "unsigned int")],
    sim_code="""
    if ($(RefracTime) <= 0.0)
    {
        scalar alpha = $(Erest) + $(Isyn);
        $(V) = ($(V) - alpha) * $(ExpTC);
    }
    else
    {
        $(RefracTime) -= DT;
        $(theta) = $(theta) * $(ExpTtheta);
    }
    """,
    reset_code="""
    $(V) = $(Vreset);
    $(RefracTime) = $(RefracPeriod);
    $(SpikeNumber) += 1;
    $(theta) += 1.0;
    """,
    threshold_condition_code=
    "$(RefracTime) <= 0.0 && $(V) >= $(Vthres) + $(theta)",
    derived_params=[
        ("ExpTC",
         genn_model.create_dpf_class(lambda pars, dt: np.exp(-dt / pars[0]))()
         ),
        ("ExpTtheta",
         genn_model.create_dpf_class(lambda pars, dt: np.exp(-dt / pars[5]))())
    ])
Beispiel #6
0
def accuracy(predictions, y_list):
    return np.sum(np.array(predictions) == np.array(y_list)) / float(
        len(y_list)) * 100


# ********************************************************************************
#                      Model Definitions
# ********************************************************************************

# Poisson model
poisson_model = genn_model.create_custom_neuron_class(
    "poisson_model",
    var_name_types=[("timeStepToSpike", "scalar"), ("frequency", "scalar")],
    sim_code="""
    if($(timeStepToSpike) <= 0.0f) {
        $(timeStepToSpike) += 1.0 / $(frequency);
    }
    $(timeStepToSpike) -= 1.0;
    """,
    threshold_condition_code="$(timeStepToSpike) <= 0.0")

# LIF neuron model
# excitatory neurons
lif_e_model = genn_model.create_custom_neuron_class(
    "lif_e_model",
    param_names=[
        "Tau", "Vrest", "Vreset", "Vthres", "RefracPeriod", "tauTheta",
        "thetaPlus"
    ],
    var_name_types=[("V", "scalar"), ("RefracTime", "scalar"),
                    ("theta", "scalar"), ("SpikeNumber", "unsigned int")],
if_params = {"Vthr": 5.0}
rm_params = {"Vspike": 60, "alpha": 3, "y": -2.468, "beta": 0.0165}
ex_params = {"Vsyn": 0, "tau_syn": 10, "g": G_MAX}
inh_params = {"Vsyn": -92, "tau_syn": 10, "g": G_MAX}
PROBABILITY_CONNECTION = 0.75
fixed_prob = {"prob": PROBABILITY_CONNECTION}

# ----------------------------------------------------------------------------
# Custom GeNN models
# ----------------------------------------------------------------------------
# Very simple integrate-and-fire neuron model
if_model = create_custom_neuron_class(
    "if_model",
    param_names=["Vthr"],
    var_name_types=[("V", "scalar"), ("SpikeCount", "unsigned int")],
    sim_code="$(V) += $(Isyn) * DT;",
    reset_code="""
    $(V) = 0.0;
    $(SpikeCount)++;
    """,
    threshold_condition_code="$(V) >= $(Vthr)")

# Current source model which injects current with a magnitude specified by a state variable
cs_model = create_custom_current_source_class(
    "cs_model",
    var_name_types=[("magnitude", "scalar")],
    injection_code="$(injectCurrent, $(magnitude));")

lateral_inhibition = create_custom_init_var_snippet_class(
    "lateral_inhibition",
    param_names=["g"],
    var_init_code="$(value)=($(id_pre)==$(id_post)) ? 0.0 : $(g);")
Beispiel #8
0
"""
Finally, we are ready to specify a custom input neuron model and the model.
"""

ssa_input_model = genn_model.create_custom_neuron_class(
    "ssa_input_model",
    param_names=["t_rise", "t_decay"],
    var_name_types=[("startSpike", "unsigned int"),
                    ("endSpike", "unsigned int"), ("z", "scalar"),
                    ("z_tilda", "scalar")],
    sim_code="""
    // filtered presynaptic trace
    // $(z) *= exp(- DT / $(t_rise));
    $(z) += (- $(z) / $(t_rise)) * DT;
    $(z_tilda) += ((- $(z_tilda) + $(z)) / $(t_decay)) * DT;
    if ($(z_tilda) < 0.0000001) {
        $(z_tilda) = 0.0;
    }
    """,
    reset_code="""
    $(startSpike)++;
    $(z) += 1.0;
    """,
    threshold_condition_code=
    "$(startSpike) != $(endSpike) && $(t)>= $(spikeTimes)[$(startSpike)]",
    extra_global_params=[("spikeTimes", "scalar*")],
    is_auto_refractory_required=False)

SSA_INPUT_PARAMS = {"t_rise": 5, "t_decay": 10}

ssa_input_init = {
Beispiel #9
0
fs_relu_model = create_custom_neuron_class(
    'fs_relu',
    param_names=['K', 'alpha', 'upstreamAlpha'],
    derived_params=[
        ("scale",
         create_dpf_class(lambda pars, dt: pars[1] * 2**(-pars[0]))()),
        ("upstreamScale",
         create_dpf_class(lambda pars, dt: pars[2] * 2**(-pars[0]))())
    ],
    var_name_types=[('Fx', 'scalar'), ('Vmem', 'scalar')],
    sim_code='''
    // Convert K to integer
    const int kInt = (int)$(K);

    // Get timestep within presentation
    const int pipeTimestep = (int)($(t) / DT);

    // Calculate magic constants. For RelU hT=h=T
    // **NOTE** d uses last timestep as that was when spike was SENT
    const scalar hT = $(scale) * (1 << (kInt - (1 + pipeTimestep)));
    const scalar d = $(upstreamScale) * (1 << ((kInt - pipeTimestep) % kInt));

    // Accumulate input
    // **NOTE** needs to be before applying input as spikes from LAST timestep must be processed
    $(Fx) += ($(Isyn) * d);

    // If this is the first timestep, apply input
    if(pipeTimestep == 0) {
        $(Vmem) = $(Fx);
        $(Fx) = 0.0;
    }
    ''',
    threshold_condition_code='''
    $(Vmem) >= hT
    ''',
    reset_code='''
    $(Vmem) -= hT;
    ''',
    is_auto_refractory_required=False)
Beispiel #10
0
###### Sample script to test implementation of Poisson neuron with changeable spiking frequency #######

from pygenn.genn_model import create_custom_neuron_class, GeNNModel

poisson_model = create_custom_neuron_class(
    "poisson_model",
    var_name_types=[("rate", "scalar"), ("spikeCount", "scalar")],
    sim_code="""
    """,
    reset_code="""
    $(spikeCount) += 1;
    """,
    threshold_condition_code="$(gennrand_uniform) >= exp(-$(rate) * 0.001 * DT)"
)

TIMESTEP = 1.0
PRESENT_TIMESTEPS = 1000

model = GeNNModel("float", "tutorial_1")
model.dT = TIMESTEP

poisson_init = {"rate": 30.0, "spikeCount": 0.0}

p = model.add_neuron_population("p", 1, poisson_model, {}, poisson_init)

model.build()
model.load()

while model.timestep < PRESENT_TIMESTEPS:
    model.step_time()
Beispiel #11
0
output_model = create_custom_neuron_class(
    "lif_superspike",
    param_names=[
        "C", "Tau_mem", "Vrest", "Vthresh", "Ioffset", "TauRefrac", "t_rise",
        "t_decay", "beta", "t_peak", "tau_avg_err"
    ],
    var_name_types=[("V", "scalar"), ("RefracTime", "scalar"),
                    ("sigma_prime", "scalar"), ("err_rise", "scalar"),
                    ("err_tilda", "scalar"), ("err_decay", "scalar"),
                    ("startSpike", "unsigned int"),
                    ("endSpike", "unsigned int"), ("avg_sq_err", "scalar")],
    sim_code="""
    // membrane potential dynamics
    if ($(RefracTime) == $(TauRefrac)) {
        $(V) = $(Vrest);
    }
    if ($(RefracTime) <= 0.0) {
        scalar alpha = (($(Isyn) + $(Ioffset)) * $(Rmembrane)) + $(Vrest);
        $(V) = alpha - ($(ExpTC) * (alpha - $(V)));
    }
    else {
        $(RefracTime) -= DT;
    }
    // filtered partial derivative
    const scalar one_plus_hi = 1.0 + fabs($(beta) * 0.001 * ($(V) - $(Vthresh)));
    $(sigma_prime) = 1.0 / (one_plus_hi * one_plus_hi);
    // error
    scalar S_pred = 0.0;
    if ($(startSpike) != $(endSpike) && $(t) >= $(spikeTimes)[$(startSpike)]) {
        $(startSpike)++;
        S_pred = 1.0;
    }
    const scalar S_real = $(RefracTime) <= 0.0 && $(V) >= $(Vthresh) ? 1.0 : 0.0;
    const scalar mismatch = S_pred - S_real;
    $(err_rise) = ($(err_rise) * $(t_rise_mult)) + mismatch;
    $(err_decay) = ($(err_decay) * $(t_decay_mult)) + mismatch;
    $(err_tilda) = ($(err_decay) - $(err_rise)) * $(norm_factor);
    // calculate average error trace
    const scalar temp = $(err_tilda) * $(err_tilda) * DT * 0.001;
    $(avg_sq_err) *= $(mul_avgerr);
    $(avg_sq_err) += temp;
    """,
    reset_code="""
    $(RefracTime) = $(TauRefrac);
    """,
    threshold_condition_code="$(RefracTime) <= 0.0 && $(V) >= $(Vthresh)",
    derived_params=[
        ("ExpTC", create_dpf_class(lambda pars, dt: exp(-dt / pars[1]))()),
        ("Rmembrane", create_dpf_class(lambda pars, dt: pars[1] / pars[0])()),
        ("norm_factor",
         create_dpf_class(lambda pars, dt: 1.0 / (-exp(-pars[9] / pars[6]) +
                                                  exp(-pars[9] / pars[7])))()),
        ("t_rise_mult",
         create_dpf_class(lambda pars, dt: exp(-dt / pars[6]))()),
        ("t_decay_mult",
         create_dpf_class(lambda pars, dt: exp(-dt / pars[7]))()),
        ("mul_avgerr",
         create_dpf_class(lambda pars, dt: exp(-dt / pars[10]))())
    ],
    extra_global_params=[("spikeTimes", "scalar*")])
Beispiel #12
0
    images = get_image_data("http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz", "testing_images.npy", 2051, max)
    labels = get_label_data("http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz", "testing_labels.npy", 2049)
    assert images.shape[0] == labels.shape[0]

    return images, labels

def accuracy(predictions, y_list):
    return np.sum(np.array(predictions) == np.array(y_list)) / float(len(y_list)) * 100

# ********************************************************************************
#                      Model Definitions
# ********************************************************************************
# Neurons for input layer
input_model = genn_model.create_custom_neuron_class(
    "input",
    extra_global_params=[("ImageData", "float*"), ("ImageOffset", "unsigned int*")],
    threshold_condition_code="$(gennrand_uniform) < $(ImageData)[$(ImageOffset)[0] + $(id)]",
    is_auto_refractory_required=False
)

# Neurons for hidden layers
hidden_layer_model = genn_model.create_custom_neuron_class(
    "hidden_layer",
    param_names=["Tau"],
    var_name_types=[("V", "scalar"), ("U", "scalar"), ("PhiF", "scalar"), ("PsiH", "scalar")],
    additional_input_vars=[("IsynBack", "scalar", 0.0)],
    derived_params=[
        ("OneMinusTau", genn_model.create_dpf_class(lambda pars, dt: 1.0 - pars[0])())
    ], 
    sim_code="""
        // Update voltage
        $(V) = ($(OneMinusTau) * $(V)) + ($(Tau) * $(Isyn));
Beispiel #13
0
    def convert(self, tf_model, scaled_tf_weights=None):
        supported_layers = (tf.keras.layers.Dense, tf.keras.layers.Flatten,
                            tf.keras.layers.Conv2D,
                            tf.keras.layers.AveragePooling2D,
                            tf.keras.layers.Dropout)

        # Check model compatibility
        if not isinstance(tf_model, tf.keras.models.Sequential):
            raise NotImplementedError(
                'Implementation for type {} models not found'.format(
                    type(tf_model)))

        for layer in tf_model.layers[:-1]:
            if not isinstance(layer, supported_layers):
                raise NotImplementedError(
                    '{} layers are not supported'.format(layer))
            elif isinstance(layer, tf.keras.layers.Dense):
                if layer.activation != tf.keras.activations.relu:
                    print(layer.activation)
                    raise NotImplementedError(
                        'Only ReLU activation function is supported')
                if layer.use_bias == True:
                    raise NotImplementedError(
                        'TensorFlow model should be trained without bias tensors'
                    )

        # create custom classes
        if_model = genn_model.create_custom_neuron_class(
            "if_model",
            param_names=["Vres", "Vthr", "Cm"],
            var_name_types=[("Vmem", "scalar"),
                            ("SpikeNumber", "unsigned int")],
            sim_code="""
            $(Vmem) += $(Isyn)*(DT / $(Cm));
            """,
            reset_code="""
            $(Vmem) = $(Vres); 
            $(SpikeNumber) += 1;
            """,
            threshold_condition_code="$(Vmem) >= $(Vthr)")

        cs_model = genn_model.create_custom_current_source_class(
            "cs_model",
            var_name_types=[("magnitude", "scalar")],
            injection_code="""
            $(injectCurrent, $(magnitude));
            """)

        # Params and init
        dense_if_params = {
            "Vres": self.Vres,
            "Vthr": self.Vthr,
            "Cm": self.dCm
        }

        sparse_if_params = {
            "Vres": self.Vres,
            "Vthr": self.Vthr,
            "Cm": self.sCm
        }

        if_init = {
            "Vmem":
            genn_model.init_var("Uniform", {
                "min": self.Vres,
                "max": self.Vthr
            }),
            "SpikeNumber":
            0
        }

        cs_init = {"magnitude": 10.0}

        # Fetch augmented weight matrices
        gw_inds, gw_vals, n_units = self.create_weight_matrices(
            tf_model, scaled_tf_weights)

        # Define model and populations
        self.g_model = genn_model.GeNNModel("float", "g_model")
        self.neuron_pops = []
        self.syn_pops = []

        for i, (inds, vals, n) in enumerate(zip(gw_inds, gw_vals, n_units),
                                            start=1):
            if i == 1:
                # Presynaptic neuron
                self.neuron_pops.append(
                    self.g_model.add_neuron_population("if" + str(i - 1),
                                                       n_units[i - 1],
                                                       if_model,
                                                       sparse_if_params,
                                                       if_init))

            if inds is None:
                # Postsynaptic neuron
                self.neuron_pops.append(
                    self.g_model.add_neuron_population("if" + str(i),
                                                       n_units[i], if_model,
                                                       dense_if_params,
                                                       if_init))

                # Synapse
                self.syn_pops.append(
                    self.g_model.add_synapse_population(
                        "syn" + str(i - 1) + str(i), "DENSE_INDIVIDUALG",
                        genn_wrapper.NO_DELAY, self.neuron_pops[-2],
                        self.neuron_pops[-1], "StaticPulse", {}, {'g': vals},
                        {}, {}, "DeltaCurr", {}, {}))

            else:
                self.neuron_pops.append(
                    self.g_model.add_neuron_population("if" + str(i),
                                                       n_units[i], if_model,
                                                       sparse_if_params,
                                                       if_init))

                self.syn_pops.append(
                    self.g_model.add_synapse_population(
                        "syn" + str(i - 1) + str(i), "SPARSE_INDIVIDUALG",
                        genn_wrapper.NO_DELAY, self.neuron_pops[-2],
                        self.neuron_pops[-1], "StaticPulse", {}, {'g': vals},
                        {}, {}, "DeltaCurr", {}, {}))

                self.syn_pops[-1].set_sparse_connections(inds[0], inds[1])

        self.current_source = self.g_model.add_current_source(
            "cs", cs_model, "if0", {}, cs_init)

        self.g_model.dT = self.timestep
        self.g_model.build()
        self.g_model.load()

        return self.g_model, self.neuron_pops, self.current_source
Beispiel #14
0
from pygenn.genn_model import create_custom_neuron_class
from pygenn.genn_wrapper.Models import VarAccess_READ_ONLY_DUPLICATE
from ml_genn.layers.input_neurons import InputNeurons

spike_input_model = create_custom_neuron_class(
    'spike_input',
    var_name_types=[('input', 'scalar', VarAccess_READ_ONLY_DUPLICATE)],
    sim_code='''
    const bool spike = $(input) != 0.0;
    ''',
    threshold_condition_code='''
    $(input) > 0.0 && spike
    ''',
    is_auto_refractory_required=False,
)


class SpikeInputNeurons(InputNeurons):
    def __init__(self, signed_spikes=False):
        super(SpikeInputNeurons, self).__init__()
        self.signed_spikes = signed_spikes

    def compile(self, mlg_model, layer):
        model = spike_input_model
        vars = {'input': 0.0}

        super(SpikeInputNeurons, self).compile(mlg_model, layer, model, {},
                                               vars, {})
# ----------------------------------------------------------------------------
IF_PARAMS = {"Vtheta": 1.0, "lambda": 0.01, "Vrest": 0.0, "Vreset": 0.0}
TIMESTEP = 1.0
PRESENT_TIMESTEPS = 100

# ----------------------------------------------------------------------------
# Custom GeNN models
# ----------------------------------------------------------------------------
if_model = create_custom_neuron_class(
    "if_model",
    param_names=["Vtheta", "lambda", "Vrest", "Vreset"],
    var_name_types=[("V", "scalar"), ("SpikeCount", "scalar")],
    sim_code="""
    if ($(V) >= $(Vtheta)) {
        $(V) = $(Vreset);
        $(SpikeCount) += 1;
    }
    $(V) += (-$(lambda) + $(Isyn)) * DT;
    $(V) = fmax($(V), $(Vrest));
    """,
    reset_code="""
    """,
    threshold_condition_code="$(V) >= $(Vtheta)")

poisson_model = create_custom_neuron_class(
    "poisson_model",
    var_name_types=[("rate", "scalar")],
    sim_code="""
    """,
    reset_code="""
    """,
Beispiel #16
0
import numpy as np
from pygenn.genn_model import create_custom_neuron_class
from ml_genn.layers.neurons import Neurons

if_model = create_custom_neuron_class(
    'if',
    var_name_types=[('Vmem', 'scalar'), ('nSpk', 'unsigned int')],
    extra_global_params=[('Vthr', 'scalar')],
    sim_code='''
    if ($(t) == 0.0) {
        // Reset state at t = 0
        $(Vmem) = 0.0;
        $(nSpk) = 0;
    }
    $(Vmem) += $(Isyn) * DT;
    ''',
    threshold_condition_code='''
    $(Vmem) >= $(Vthr)
    ''',
    reset_code='''
    $(Vmem) = 0.0;
    $(nSpk) += 1;
    ''',
    is_auto_refractory_required=False,
)


class IFNeurons(Neurons):
    def __init__(self, threshold=1.0):
        super(IFNeurons, self).__init__()
        self.threshold = threshold
Beispiel #17
0
# ----------------------------------------------------------------------------
# Custom models
# ----------------------------------------------------------------------------
izhikevich_dopamine_model = genn_model.create_custom_neuron_class(
    "izhikevich_dopamine",

    param_names=["a", "b", "c", "d", "tauD", "dStrength"],
    var_name_types=[("V", "scalar"), ("U", "scalar"), ("D", "scalar")],
    extra_global_params=[("rewardTimesteps", "uint32_t*")],
    sim_code=
        """
        $(V)+=0.5*(0.04*$(V)*$(V)+5.0*$(V)+140.0-$(U)+$(Isyn))*DT; //at two times for numerical stability
        $(V)+=0.5*(0.04*$(V)*$(V)+5.0*$(V)+140.0-$(U)+$(Isyn))*DT;
        $(U)+=$(a)*($(b)*$(V)-$(U))*DT;
        const unsigned int timestep = (unsigned int)($(t) / DT);
        const bool injectDopamine = (($(rewardTimesteps)[timestep / 32] & (1 << (timestep % 32))) != 0);
        if(injectDopamine) {
           const scalar dopamineDT = $(t) - $(prev_seT);
           const scalar dopamineDecay = exp(-dopamineDT / $(tauD));
           $(D) = ($(D) * dopamineDecay) + $(dStrength);
        }
        """,
    threshold_condition_code="$(V) >= 30.0",
    reset_code=
        """
        $(V)=$(c);
        $(U)+=$(d);
        """)

izhikevich_stdp_tag_update_code="""
    // Calculate how much tag has decayed since last update
from pygenn.genn_model import create_custom_neuron_class
from pygenn.genn_wrapper.Models import VarAccess_READ_ONLY_DUPLICATE
from ml_genn.layers.input_neurons import InputNeurons

poisson_input_model = create_custom_neuron_class(
    'poisson_input',
    var_name_types=[('input', 'scalar', VarAccess_READ_ONLY_DUPLICATE)],
    sim_code='''
    const bool spike = $(gennrand_uniform) >= exp(-fabs($(input)) * DT);
    ''',
    threshold_condition_code='''
    $(input) > 0.0 && spike
    ''',
    is_auto_refractory_required=False,
)


class PoissonInputNeurons(InputNeurons):
    def __init__(self, signed_spikes=False):
        super(PoissonInputNeurons, self).__init__()
        self.signed_spikes = signed_spikes

    def compile(self, mlg_model, layer):
        model = poisson_input_model
        vars = {'input': 0.0}

        super(PoissonInputNeurons, self).compile(mlg_model, layer, model, {},
                                                 vars, {})

#----------------------------------------------------------------------------
# Neuron models
#----------------------------------------------------------------------------
recurrent_lif_model = genn_model.create_custom_neuron_class(
    "recurrent_lif",
    param_names=["TauM", "Vthresh", "TauRefrac"],
    var_name_types=[("V", "scalar"), ("RefracTime", "scalar")],
    derived_params=[
        ("Alpha",
         genn_model.create_dpf_class(lambda pars, dt: np.exp(-dt / pars[0]))())
    ],
    sim_code="""
    $(V) = ($(Alpha) * $(V)) + $(Isyn);
    if ($(RefracTime) > 0.0) {
      $(RefracTime) -= DT;
    }
    """,
    reset_code="""
    $(RefracTime) = $(TauRefrac);
    $(V) -= $(Vthresh);
    """,
    threshold_condition_code="""
    $(RefracTime) <= 0.0 && $(V) >= $(Vthresh)
    """,
    is_auto_refractory_required=False)

recurrent_alif_model = genn_model.create_custom_neuron_class(
    "recurrent_alif",
    param_names=["TauM", "TauAdap", "Vthresh", "TauRefrac", "Beta"],
    var_name_types=[("V", "scalar"), ("A", "scalar"),
hidden_neuron_model = genn_model.create_custom_neuron_class(
    "hidden",
    param_names=["C", "tauMem", "Vrest", "Vthresh", "tauRefrac"],
    var_name_types=[("V", "scalar"), ("refracTime", "scalar"), ("errTilda", "scalar")],
    additional_input_vars=[("ISynFeedback", "scalar", 0.0)],
    derived_params=[("ExpTC", genn_model.create_dpf_class(lambda pars, dt: np.exp(-dt / pars[1]))()),
                    ("Rmembrane", genn_model.create_dpf_class(lambda pars, dt: pars[1] / pars[0])())],
   
    sim_code="""
    // membrane potential dynamics
    if ($(refracTime) == $(tauRefrac)) {
        $(V) = $(Vrest);
    }
    if ($(refracTime) <= 0.0) {
        scalar alpha = ($(Isyn) * $(Rmembrane)) + $(Vrest);
        $(V) = alpha - ($(ExpTC) * (alpha - $(V)));
    }
    else {
        $(refracTime) -= DT;
    }
    // error
    $(errTilda) = $(ISynFeedback);
    """,
    reset_code="""
    $(refracTime) = $(tauRefrac);
    """,
    threshold_condition_code="""
    $(refracTime) <= 0.0 && $(V) >= $(Vthresh)
    """,
    is_auto_refractory_required=False)
    default=1,
    help=
    "Number of samples in the dataset for which the network should be simulated. (default=1)",
)
args = parser.parse_args()

# Define custom Izhikevich neuron class

izk_neuron = create_custom_neuron_class(
    "izk_neuron",
    param_names=["a", "b", "c", "d", "C", "k"],
    var_name_types=[("V", "scalar"), ("U", "scalar")],
    sim_code="""
        $(V)+= (0.5/$(C))*($(k)*($(V) + 60.0)*($(V) + 40.0)-$(U)+$(Isyn));  //at two times for numerical stability
        $(V)+= (0.5/$(C))*($(k)*($(V) +  60.0)*($(V) + 40.0)-$(U)+$(Isyn));
        $(U)+=$(a)*($(b)*($(V) + 60.0)-$(U))*DT;
        """,
    reset_code="""
        $(V)=$(c);
        $(U)+=$(d);
        """,
    threshold_condition_code="$(V) > 30",
)

# Set the parameters and initial values of variables for the IZK neuron (whose class has been defined above)

izk_params = {
    "a": 0.03,
    "b": -2.0,
    "c": -50.0,
    "d": 100.0,
Beispiel #22
0
from pygenn.genn_model import create_custom_neuron_class
from pygenn.genn_wrapper.Models import VarAccess_READ_ONLY_DUPLICATE
from ml_genn.layers.input_neurons import InputNeurons

if_input_model = create_custom_neuron_class(
    'if_input',
    var_name_types=[('input', 'scalar', VarAccess_READ_ONLY_DUPLICATE),
                    ('Vmem', 'scalar')],
    sim_code='''
    if ($(t) == 0.0) {
        // Reset state at t = 0
        $(Vmem) = 0.0;
    }
    $(Vmem) += $(input) * DT;
    ''',
    threshold_condition_code='''
    $(Vmem) >= 1.0
    ''',
    reset_code='''
    $(Vmem) = 0.0;
    ''',
    is_auto_refractory_required=False,
)


class IFInputNeurons(InputNeurons):
    def compile(self, mlg_model, layer):
        model = if_input_model
        vars = {'input': 0.0, 'Vmem': 0.0}

        super(IFInputNeurons, self).compile(mlg_model, layer, model, {}, vars,