Rate models

Rate and WilsonCowan (rate units, same dynamics) and HetRec (stochastic spiking with heterogeneous dendritic time constants).

Rate units: Rate

\[\frac{dx}{dt} = -x + g + I, \qquad r = \tanh(x)\]

Time constant 1 ms, no parameters. $g$ is the input of the step (written by RateSynapse, reset after each step), $I$ an external input. Record :x or :r.

using SpikingNeuralNetworks
SNN.@load_units
R = SNN.Rate(N = 100)
syn = SNN.RateSynapse(R, R; μ = 1.0, p = 0.2)
model = SNN.compose(; R, syn)
SNN.monitor!(R, [:r])
SNN.sim!(model, 50ms)
SNNModels.Rate — Type
Rate(; N = 100, name = "Rate", kwargs...)

Population of rate units with a tanh transfer function.

Equations

\[\frac{dx}{dt} = -x + g + I, \qquad r = \tanh(x)\]

with $t$ in ms, i.e. the time constant is fixed to 1 ms. $g$ is the input written by RateSynapse ($g_i \mathrel{+}= \sum_j W_{ij} r_j$ each step), $I$ an external input.

Integration

Forward Euler, x += dt * (-x + g + I), then r = tanh(x), then g is set to zero: $g$ is the synaptic input of one step, written by the connections after the population update (RateSynapse adds $W r$, the FORCE connections overwrite it). Use I for a constant input. The population has no fire field, so only :x, :r, :g can be recorded; populations are recorded right after their update, so a recorded :g is zero.

Fields

  • id::String = randstring(12), name::String = "Rate", param::RateParameter = RateParameter().
  • N::Int32 = 100.
  • VFT = Vector{Float32}: type of the state vectors; Vector{Float64} gives a Float64 population (see float_type).
  • x::VFT = 0.5randn(N): internal state.
  • r::VFT = tanh.(x): output rate, in $(-1, 1)$.
  • g::VFT: synaptic input, zeros; the target of RateSynapse (any target symbol is mapped to :g).
  • I::VFT: external input, zeros.
  • records::Dict.

References

Example

using SpikingNeuralNetworks
SNN.@load_units
R = SNN.Rate(N = 10)
R.I .= 0.5
SNN.monitor!(R, [:r])
SNN.sim!([R]; duration = 20ms)
source
SNNModels.RateParameter — Type
RateParameter <: AbstractPopulationParameter

Parameter type of the Rate population. It has no fields: the model has a fixed unit time constant and a tanh transfer function. Not exported (SNNModels.RateParameter).

source
SNNModels.integrate! — Method
integrate!(p::Rate, param::RateParameter, dt)

One forward-Euler step of the rate units: x += dt * (-x + g + I), r = tanh(x), then g = 0 (see Rate).

source

WilsonCowan

Same dynamics as Rate; not the coupled E/I equations of Wilson and Cowan (1972).

using SpikingNeuralNetworks
SNN.@load_units
W = SNN.WilsonCowan(N = 10)
W.I .= 0.2
SNN.monitor!(W, [:r])
SNN.sim!([W]; duration = 20ms)
SNNModels.WCParameter — Type
WCParameter <: AbstractPopulationParameter

Parameter type of WilsonCowan; it has no fields. Not exported (SNNModels.WCParameter).

source
SNNModels.WilsonCowan — Type
WilsonCowan(; N = 100, name = "WilsonCowan", kwargs...)

Population of rate units named after the Wilson-Cowan model. Its dynamics are identical to Rate: a single variable per unit with unit time constant and tanh transfer function. It does not implement the coupled excitatory/inhibitory Wilson-Cowan equations (no separate E and I variables, no refractory term, no sigmoid parameters).

Equations

\[\frac{dx}{dt} = -x + g + I, \qquad r = \tanh(x)\]

($t$ in ms), integrated with forward Euler; g is reset to zero after each step, as in Rate.

Fields

  • id::String = randstring(12), name::String = "WilsonCowan", param::WCParameter.
  • N::Int32 = 100; x = 0.5randn(N); r = tanh.(x); g, I: inputs, zeros; records::Dict.
  • VFT = Vector{Float32}: type of the state vectors; Vector{Float64} gives a Float64 population (see float_type).

RateSynapse (and the FORCE connections) target g, as for Rate (any target symbol is mapped to :g).

References

Wilson H. R., Cowan J. D. (1972). Excitatory and inhibitory interactions in localized populations of model neurons. Biophys. J. 12:1-24 (not implemented in full, see above).

Example

using SpikingNeuralNetworks
SNN.@load_units
W = SNN.WilsonCowan(N = 10)
SNN.monitor!(W, [:r])
SNN.sim!([W]; duration = 20ms)
source

Heterogeneous dendritic timescales: HetRec

Each neuron owns Nd dendrites with time constants sampled from τd; its soma also reads each dendrite of the other neurons with probability overlap. Inputs target the dendrites (:glu, :gaba, size N * Nd).

\[\begin{aligned} \tau_d\, \frac{dv_d}{dt} &= -v_d + g_E - g_I \\ \tau_m\, \frac{dv_s^i}{dt} &= \sum_{d \in \mathcal{D}_i} \left(v_d - v_s^i\right) \\ P(\text{spike of } i \text{ in } dt) &= r_i\, \sigma\!\left(k\, (v_s^i - a_i)\right) dt, \qquad \sigma(x) = \frac{1}{1 + e^{-x}} \end{aligned}\]

$r_i$ (from rate) is the maximal rate, $k$ = steepness, $a_i$ an adaptive baseline (time constant τrate, +1 per spike).

FieldDefaultUnitsMeaning
Nd2-dendrites per neuron
overlap0.5-probability of reading another neuron's dendrite
τdUniform(10, 100)msdistribution of dendritic time constants
rateUniform(0, 1)1/msdistribution of maximal rates
τabs5msmsabsolute refractory period
steepness11/mVslope of the sigmoid
τm20msmssomatic time constant
τrate100msmstime constant of the adaptive baseline
using SpikingNeuralNetworks
SNN.@load_units
H = SNN.Population(SNN.HetRecParameter(Nd = 3, overlap = 0.2); N = 20)
P = SNN.Poisson(N = 50, param = SNN.PoissonParameter(20Hz))
s = SNN.SpikingSynapse(P, H, :glu; conn = (μ = 1, p = 0.2))
model = SNN.compose(; P, H, s)
SNN.monitor!(H, [:fire, :v_s])
SNN.sim!(model, 200ms)
SNNModels.HetRec — Type
Population(param::HetRecParameter; N = 100)
HetRec

Population of N stochastic spiking neurons, each with param.Nd leaky dendritic compartments with heterogeneous time constants. Create it with Population(HetRecParameter(...); N), which samples τd and r, builds the dendrite-to-soma mapping and the sparse matrix of the mapping.

Input connections target the dendrites: the presynaptic spikes are written into receptors.glu / receptors.gaba (use the target symbols :glu, :gaba; size N * Nd) and filtered by a CurrentSynapse ($τ_e = 6$ ms, $τ_i = 2$ ms).

Equations

For dendrite $d$ and neuron $i$ ($g_E$, $g_I$: exponentially decaying current-based synaptic variables of the CurrentSynapse):

\[\begin{aligned} \tau_d\, \frac{dv_d}{dt} &= -v_d + g_E - g_I \\ \tau_m\, \frac{dv_s^i}{dt} &= \sum_{d \in \mathcal{D}_i} \left(W_{id}\, v_d - v_s^i\right) \\ \tau_{rate}\, \frac{da_i}{dt} &= -a_i + [\text{not refractory}]\,(v_s^i - a_i) + \tau_{rate} \textstyle\sum_f \delta(t - t_i^f) \\ P(\text{spike of } i \text{ in } [t, t + dt]) &= r_i\, \sigma\!\left(k\, (v_s^i - a_i)\right) dt \end{aligned}\]

with $\sigma(x) = 1 / (1 + e^{-x})$, $k$ = steepness, $\mathcal{D}_i$ the dendrites read by neuron $i$ (its own Nd dendrites plus those of other neurons selected with probability overlap, $W_{id} = 1$) and $a_i$ the adaptive baseline trace.

Integration

Per step: synapse update; dendrites v_d += dt * (-v_d - is) / τd with is = -(g_E - g_I); for each neuron, one forward-Euler step of the somatic equation, v_s += dt / τm * Σ_d (W v_d - v_s) (with $k_i$ connected dendrites the soma relaxes to their mean with time constant $τ_m / k_i$); tabs -= 1, fire = false, trace += dt * (-trace / τrate); if not refractory, trace += dt * (v_s - trace) / τrate and the neuron fires with the probability above, which sets tabs = round(Int, τabs / dt) and trace += 1.

Fields

  • id, name = "HetRec", N::Int32 = 100, param::HetRecParameter.
  • v_d (length N * Nd), v_s (length N): dendritic and somatic potentials.
  • M::Matrix{Float32}: dense mapping (unused after construction, zeros by default).
  • r: maximal rates (1/ms); fire; tabs; trace: adaptive baseline; randcache.
  • spikes::SpikeIndex: neurons that fired in the step (see spike_index).
  • τd: dendritic time constants (ms).
  • rowptr, colptr, I, J, index, W: CSC representation of the dendrite-to-soma mapping (columns = neurons, rows = dendrites).
  • is: dendritic synaptic current; synapse = CurrentSynapse(), synvars, receptors (size N * Nd); records::Dict.

Example

using SpikingNeuralNetworks
SNN.@load_units
H = SNN.Population(SNN.HetRecParameter(Nd = 3, overlap = 0.2); N = 20)
P = SNN.Poisson(N = 50, param = SNN.PoissonParameter(20Hz))
s = SNN.SpikingSynapse(P, H, :glu; conn = (μ = 1, p = 0.2))
model = SNN.compose(; P, H, s)
SNN.monitor!(H, [:fire, :v_s])
SNN.sim!(model, 200ms)
source
SNNModels.HetRecParameter — Type
HetRecParameter(; Nd = 2, overlap = 0.5, τd = Uniform(10, 100), rate = Uniform(0, 1),
                 τabs = 5ms, steepness = 1, τm = 20ms, τrate = 100ms)

Parameters of the HetRec population: stochastic spiking units whose input is filtered by Nd dendritic compartments per neuron with heterogeneous time constants. The docstring of the original code describes it as a heterogeneous-timescale, non-recurrent layer.

Fields

  • Nd::Int = 2: number of dendritic compartments per neuron (the population has N * Nd dendrites).
  • overlap::Float32 = 0.5: probability that the soma of neuron $i$ also reads dendrite $j$ of another neuron $k \neq i$; 0 = each soma reads only its own Nd dendrites, 1 = every soma reads all dendrites.
  • τd::Distribution = Uniform(10.0f0, 100.0f0): distribution of the dendritic time constants (ms), one sample per dendrite.
  • rate::Distribution = Uniform(0.0f0, 1.0f0): distribution of the maximal firing rate $r_i$ of each neuron, in spikes per ms (1 = 1 kHz).
  • τabs::Float32 = 5ms: absolute refractory period (ms).
  • steepness::Float32 = 1.0: slope of the sigmoid firing nonlinearity (1/mV).
  • τm::Float32 = 20ms: somatic integration time constant (ms).
  • τrate::Float32 = 100ms: time constant of the adaptive firing baseline trace (ms).

The number of neurons is not a field: it is the N keyword of Population. Reference not given in the code.

source