API Reference¶
Core computations live in two modules: mnesis_chains (pattern
generators, the HD_SNN network, analytical initialisation, training and inference)
and mnesis_boilerplate (imports, device setup, the Params dataclass and
utilities). Documentation is generated from the docstrings via
sphinx.ext.autodoc/napoleon.
mnesis_chains — core network and pattern generators¶
Core module of the MNESIS library.
Defines the spiking-pattern generators (SpikingPattern,
StochasticSpikingPattern) and the HD_SNN network class –
a recurrent spiking neural network with heterogeneous synaptic delays –
together with its analytical weight initialisation, training
(HD_SNN.learn_model()) and inference (HD_SNN.forward_pass())
methods, and a load() helper for trained checkpoints.
- class mnesis_chains.SpikingPattern¶
Bases:
objectGenerate a frozen spiking pattern based on a Bernoulli process.
The target is a single, reproducible spike raster of shape
(N_pattern, N_neuron, N_time)drawn once from a Bernoulli distribution of ratep_A, seeded withopt.seedso that the same pattern is obtained across runs.- init(opt, verbose=False)¶
Draw the frozen target pattern.
- Parameters:
opt – A
Paramsinstance providingN_pattern,N_neuron,N_time,p_A,seedanddevice.verbose – If
True, print the shape and mean firing rate of the generated target.
- __call__(seed=None, verbose=False)¶
Return the frozen target pattern.
- Parameters:
seed – Ignored; accepted so that every generator can be called with the same signature as
StochasticSpikingPattern.verbose – Ignored, for the same reason.
- Returns:
The stored spike raster, of shape
(N_pattern, N_neuron, N_time).- Return type:
- class mnesis_chains.StochasticSpikingPattern¶
Bases:
SpikingPatternA stochastic spiking pattern generator.
Extends
SpikingPatternwith stochastic variability: each call returns a new realization of the base pattern in which bits are flipped independently with probabilityopt.p_flip(“balanced bit flipping”), so the marginal firing rate is preserved while the pattern structure is stochastically modified.- __call__(seed=None, verbose=False)¶
Generate a stochastic realization of the spiking pattern.
Each call returns a new realization of the base pattern where bits are independently flipped with probability
self.opt.p_flip. The balanced-flip operation preserves the marginal frequency while introducing temporal and spatial variability in the structure.- Parameters:
seed – Seed for the bit-flip generator;
Nonedraws a fresh random seed.verbose – If
True, report the number of flipped bits.
- Returns:
Stochastic realization of the spiking pattern, with the same dimensions as the base pattern.
- Return type:
- class mnesis_chains.HD_SNN(opt, pattern_object)¶
Bases:
ModuleRecurrent spiking neural network with Heterogeneous Delays (HD-SNN).
Each of the
num_delaydelays of every synapse carries an independent learnable weight, gathered in a single tensorWof shape(N_neuron, N_neuron * num_delay): the membrane of a neuron is driven by the lastnum_delayspikes of all its presynaptic peers. The network is alin(the delay-expanded linear layer, no bias) followed bydropoutand a leaky integrate-and-fire neuron (snntorchsnn.Leaky) whose non-differentiable threshold crossing is trained through a surrogate gradient.- pattern_object¶
The spiking-pattern generator providing the targets.
- net¶
nn.Sequentialof the('lin', 'dropout', 'lif')modules.
Build the network and initialise the pattern generator.
- Parameters:
opt – A
Paramsinstance.pattern_object – A
SpikingPattern-like object; itsinit(opt)method is called to produce the targets.
- forward_pass(input_spikes, reset_spikes=None, feedback=True)¶
Unroll the network over time and record its activations.
Starting at
t = num_delay, each neuron receives the lastnum_delayspikes of every neuron, taken from the recurrent output, the external input and (optionally) a reset mask, combined as(A + B - C).clamp(0, 1)and ravelled into the delay-expanded linear layer before the leaky integrate-and-fire step.On MPS the loop synchronises every
sync_everysteps: without it, a long run (about 1e5 steps) piles up all its kernels in a single Metal command buffer, which the driver rejects as a whole (kIOGPUCommandBufferCallbackErrorOutOfMemory) while PyTorch silently returns all-zero tensors.- Parameters:
input_spikes – External spikes of shape
(N_pattern, N_neuron, N_time).reset_spikes – Spikes to clamp off from the recurrent drive, same shape as
input_spikes;Nonemeans no reset.feedback – If
False, the output spikes are not fed back (open loop): each neuron only sees the external input, so that the replay cannot outlast the trigger by more thannum_delaysteps. A control showing that the replay is sustained by the recurrent positive feedback.
- Returns:
(current, mem_rec, spikes)– the post-synaptic current, the membrane potential and the output spikes, each of shape(N_pattern, N_neuron, N_time).- Return type:
- get_W_init()¶
Compute the closed-form (analytical) weight initialisation.
The target patterns are cast as a linear regression problem: every sliding window of
num_delaypast spikes (the “context”) should predict the next time step of activity. Two orthogonal flags select the estimator:do_deconv: deconvolve the LIF membrane, i.e. regress onto the input currents*(t) - beta * s*(t-1)rather than onto the raw target spikes; a perfect context then drives the membrane to 1, a margin1 - lif_thresholdabove the threshold.do_pinv: solve exactly with the (CPU-computed) pseudo-inverseW = pinv(C) T; otherwise use the normalised Hebbian cross-correlationT^T C / <||c||^2>.
The regression is fitted on the frozen pattern, the noise-free reference that every evaluation scores against, so that the initialisation is deterministic for a given
opt.seed.- Returns:
The initial weights for
net.lin, of shape(N_neuron, N_neuron * num_delay).- Return type:
- update_weight()¶
Set
net.lin.weightto the analytical initialisation.Copies
get_W_init()into the linear layer in-place, undertorch.no_grad().
- get_input_spikes(target, p_A=None, N_pretime=None, N_trigger_time=None, N_time=None, seed=None)¶
Build the trigger input spikes for the network.
The input concatenates a
N_pretimechunk of spontaneous Bernoulli activity at ratep_A, then the trigger window ofnum_delaysteps, which shows the lastN_trigger_timesteps of its spiking-motif window (target stepsnum_delay - N_trigger_timetonum_delay - 1); its firstnum_delay - N_trigger_timesteps prolong the spontaneous activity. Any remaining time bins stay silent. The total length isN_time + 2*N_pretime.A partial trigger is aligned on the end of the window because the readout is only trained on complete spiking-motif windows, which end where the replay starts: the partial window shown to the first evoked step is then a subset of a trained context, not a context shifted into the spontaneous activity.
- Parameters:
target – The memorised pattern of shape
(N_pattern, N_neuron, N_time).p_A – Spontaneous firing rate; defaults to
opt.p_A.N_pretime – Length of the spontaneous prefix; defaults to
opt.N_pretime.N_trigger_time – Number of steps of the cue, taken at the end of the trigger window (time bins,
0 <= N_trigger_time <= num_delay); defaults toopt.num_delay(full trigger).N_time – Length of the memory stretch; defaults to
opt.N_time.seed – Seed for the spontaneous activity;
Nonedraws from the globaltorchgenerator (seeded byParams). As inflip_bits(), the generator is seeded with a value derived fromseed(on a stream of its own), so that a seed equal to the seed of the frozen motif does not replay its uniform draws as spontaneous activity.
- Returns:
Detached input spikes of shape
(N_pattern, N_neuron, N_time + 2*N_pretime).- Return type:
- get_recall_time(input_spikes, feedback=True, bin_width=None)¶
Recall of each motif in successive bins of the evoked window.
Runs
forward_pass()and scores the evoked window against the frozen motif withget_recall_time().- Parameters:
input_spikes – External spikes, as built by
get_input_spikes().feedback –
Falsefor the open-loop control (seeforward_pass()).bin_width – Width of a time bin (time bins); defaults to
num_delay.
- Returns:
recall of shape
(N_pattern, N_bin).- Return type:
np.ndarray
- learn_model(verbose=True)¶
Train the delay weights by surrogate-gradient BPTT.
At each epoch a fresh noisy realisation is drawn from
pattern_object(data augmentation), the network is unrolled throughforward_pass()on the cued input fromget_input_spikes(), and the loss (SpikeF1scoreLossby default, orMSELoss) between the output and that realisation is evaluated only after the spontaneous pre-time and the trigger window. The learning rate follows a cosine decay with linear warmup. An evaluation pass (dropout disabled), cued by another realisation and scored against the frozen pattern, logs loss, precision, recall and F1 everynum_epochs // 64epochs. All realisations are seeded fromopt.seed, so a run is reproducible.- Parameters:
verbose – If
True, print periodic training logs.
- mnesis_chains.load(opt, model_filename, pattern_object=None)¶
Load a trained checkpoint into a fresh
HD_SNN.Rebuild the network (re-initialising the pattern generator), restore the saved
netstate dict and switch it to evaluation mode.- Parameters:
opt – A
Paramsinstance.model_filename – Path to a
.pthstate dict saved fromhd.net.pattern_object – Generator providing the targets; defaults to a
StochasticSpikingPattern.
- Returns:
The trained network in
eval()mode.- Return type:
mnesis_boilerplate — hyperparameters and utilities¶
Shared boilerplate for the MNESIS experiments.
Provides the entry-point imports (torch, snntorch, numpy, matplotlib, …),
automatic device detection (MPS -> CUDA -> CPU), the Params
dataclass that is the single source of hyperparameter truth, and the
utilities reused by mnesis_chains and all notebooks: random bit
flipping (flip_bits()), figure saving (printfig()), spike-score
metrics (get_scores(), get_f1score(),
SpikeF1scoreLoss), the F1 scores expected from theory for a degraded
trigger (get_f1_noisy_copy(), get_f1_ignition(), and the simulated
cascade get_f1_cascade()), the recall of each motif against time
(get_recall_time(), plot_recall_time()) and the cosine learning-rate
schedule (get_cosine_schedule_with_warmup()).
- class mnesis_boilerplate.Params(datetag='2026-09-07', N_neuron=1024, num_delay=41, N_pattern=16, N_time=1000, N_pretime=50, p_A=0.00016, p_flip=0.01, seed=2026, lif_beta=0.7, lif_threshold=0.75, learn_beta=False, learn_threshold=False, do_pinv=True, do_deconv=True, num_epochs=256, num_warmup_epochs=16, base_lr=0.04, final_lr=0.0004, delta1=0.003, delta2=1e-05, dropout=0.6, alpha_surrogate=5.0, surrogate_name='FastSigmoid', loss_name='SpikeF1scoreLoss', reset_mechanism='zero', optimizer='adadelta', verbose=False, fig_width=15.92, phi=1.61803, fig_height=9.839125356142963, N_time_show=1000, N_neuron_show=1024, i_pattern=1, N_scan=14, N_cv=11)¶
Bases:
objectSingle source of hyperparameter truth for the MNESIS experiments.
Instances also seed
torchandnumpy(in__post_init__) so that a givenseedreproduces a run. Field groups:- Parameters:
datetag (str)
N_neuron (int)
num_delay (int)
N_pattern (int)
N_time (int)
N_pretime (int)
p_A (float)
p_flip (float)
seed (int)
lif_beta (float)
lif_threshold (float)
learn_beta (bool)
learn_threshold (bool)
do_pinv (bool)
do_deconv (bool)
num_epochs (int)
num_warmup_epochs (int)
base_lr (float)
final_lr (float)
delta1 (float)
delta2 (float)
dropout (float)
alpha_surrogate (float)
surrogate_name (str)
loss_name (str)
reset_mechanism (str)
optimizer (str)
verbose (bool)
fig_width (float)
phi (float)
fig_height (float)
N_time_show (int)
N_neuron_show (int)
i_pattern (int)
N_scan (int)
N_cv (int)
- N_neuron, num_delay, N_pattern,
N_time, N_pretime, p_A, p_flip, seed: network size and statistics.
- lif_beta, lif_threshold, learn_beta, learn_threshold, do_pinv,
do_deconv: membrane dynamics and analytical-init flags.
- num_epochs, num_warmup_epochs, base_lr, final_lr, delta1, delta2,
dropout, alpha_surrogate, surrogate_name, loss_name, reset_mechanism, optimizer: learning dynamics.
- verbose, fig_width, fig_height, phi, N_time_show, N_neuron_show,
i_pattern, N_scan, N_cv: figure/scan settings.
- device = device(type='cpu')¶
- mnesis_boilerplate.pprint(s)¶
Print a headline surrounded by ‘=’ banners of the same length.
- mnesis_boilerplate.printfig(fig, name='', fig_width=12, fig_height=None, exts=['pdf', 'png', 'svg'], figpath=PosixPath('../figures'), dpi_exp=None, bbox=None, layout='constrained', verbose=True, do_overwrite=True)¶
Save a matplotlib figure to
figpathunder several extensions.Sizes the figure in centimetres, defaulting the height to
fig_width / phi(golden ratio). On the Jean Zay cluster (figpath is None) saving is silently skipped. Existing files are overwritten only ifdo_overwriteis true.- Parameters:
fig_width – Width of the saved figure (cm); match it to the width the paper gives to
\includegraphicsso fonts print at their nominal size.fig_height – Height of the saved figure (cm); defaults to
fig_width / phi.bbox – Passed to
savefig(bbox_inches=...). The defaultNonekeeps the exactfig_widthxfig_heightcanvas, whereas'tight'crops it to the artists and so changes the printed scale.layout – Layout engine set before saving (
'constrained'fits labels inside the canvas);Nonekeeps a manualsubplots_adjust.
- mnesis_boilerplate.flip_bits(a, p_flip, seed=None, verbose=False)¶
Balanced bit flipping preserving the marginal firing rate of
a.Each entry of the binary tensor
ais replaced, with probabilityp_flip, by a fresh Bernoulli draw of ratea.mean(), so the expected spike rate is preserved while the pattern is perturbed.- Parameters:
a (torch.Tensor) – binary tensor to perturb.
p_flip (float) – probability of redrawing an entry (dimensionless).
seed (int) – seed of the flips;
Nonedraws a fresh random seed. The generator is seeded with a value derived fromseed, not withseeditself, so that a flip seed equal to the seed of the frozen motif does not read the same uniform draws.verbose (bool) – if
True, report the number of flipped bits.
- Returns:
A new tensor of the same shape as
a.- Return type:
- mnesis_boilerplate.stop()¶
Raise an AssertionError on purpose: temporary end of the script.
- mnesis_boilerplate.approx_equals(series, value, rtol=1e-06, atol=1e-12)¶
Elementwise
np.isclosefor a pandas Series, falling back to==.- Returns:
Boolean mask selecting the entries close to
value.
- mnesis_boilerplate.cache_lock(filename)¶
Hold the
.locksentinel of a cache file while this file is computed.The lock is taken atomically (
O_EXCL), so two processes started together cannot both compute the same file. It is released in afinallyclause, so an exception or an interrupt during the computation does not leave a stale lock behind, which would make every later run skip the computation.- Parameters:
filename – Path of the cache file to compute; the lock is the same path with a
.locksuffix.- Yields:
True if this process now holds the lock and should compute the file; False if the lock already exists (another process is computing the file, or one died before releasing it), in which case nothing is removed.
- mnesis_boilerplate.purge_unfinished_scans(datetag=None, data_cache=PosixPath('../cached_data'), ignore_locks=False, remove_locks=False, dry_run=False)¶
Remove the placeholder rows left by interrupted scans, so they are recomputed.
A scan notebook reserves a row
loss=inf, time=0.0(stored asnullin JSON) before computing it, and overwrites it when done. A row still in that state means the process died in between, yet the scan loop treats it as “already computed” and never retries it. Deleting the row lifts that block. A failed evaluation also storesloss=infbut with a non-zerotime, so it is kept.- Parameters:
datetag – Cache-filename prefix of the batch to clean (ISO 8601 date); None cleans the scans of all batches.
data_cache – Directory holding the
{datetag}_*.jsonscan files.ignore_locks – If False, skip the scans that have a
.lockfile, as they may still be running.remove_locks – If True, also delete every
.lockfile of the selected batches, which lifts the block on resuming the scans. Only use it when no scan is running (e.g. at the start of the orchestrator), as it impliesignore_locks.dry_run – If True, only report what would be removed.
- Returns:
Dictionary mapping each file name to the number of rows removed (or to be removed).
- mnesis_boilerplate.get_scores(pred, target, epsilon=1e-12, dim=None)¶
Precision, recall and F1 between two (soft) spike tensors.
Sums the elementwise true/false positives and negatives; high precision means few false positives, high recall few false negatives.
epsilonavoids division by zero. High precision means few false positives (FP), high recall few false negatives (FN).- Parameters:
pred (torch.Tensor) – predicted spikes.
target (torch.Tensor) – target spikes, of the same shape.
epsilon (float) – regularisation of the divisions.
dim (int or tuple) – dimensions to sum over;
Nonesums over all of them,(1, 2)gives one score per motif for tensors of shape(N_pattern, N_neuron, N_time).
- Returns:
(precision, recall, f1_score), scalar tensors or tensors over the dimensions left by
dim.- Return type:
- mnesis_boilerplate.get_f1score(pred, target, epsilon=1e-12, dim=None)¶
F1 score: the harmonic mean of precision and recall.
High only when both precision and recall are high; one minus this value is the training loss (
SpikeF1scoreLoss).dimis passed toget_scores()((1, 2): one score per motif).
- mnesis_boilerplate.get_beta_errorbar(scores, quantiles=(0.05, 0.95), axis=1)¶
Mean and asymmetric error bars of repeated scores bounded in [0, 1].
An F1 score lives in [0, 1], so a symmetric mean +/- std bar can cross the bounds; instead a beta distribution is fitted to the repetitions by the method of moments (mean
m, variancev):k = m (1 - m) / v - 1,a = m k,b = (1 - m) k, and the bars span itsquantiles. Where no beta fit exists (v = 0, e.g. all repetitions at F1 = 0, ork <= 0for data piled at 0 and 1), the empirical quantiles are used instead (equal tomwhenv = 0).- Parameters:
- Returns:
(mean, yerr), ready for
ax.errorbar(x, mean, yerr=yerr);yerrhas shape(2, ...): distances from the mean down to the lower quantile and up to the upper one.- Return type:
- mnesis_boilerplate.get_f1_noisy_copy(p_flip, p_A)¶
F1 score of a balanced-flipped motif against the frozen one.
A balanced flip (
flip_bits()) keeps a spike of the motif with probabilityq = 1 - p_flip (1 - p_A)and turns an empty bin into a spike with probabilityp_flip p_A, so the expected precision and recall are both equal toq. This is the score of a readout that would copy the corrupted motif as is, without any pattern completion: it falls linearly from 1 to chance level (F1 = p_A) atp_flip = 1.
- mnesis_boilerplate.get_f1_from_ignition(R, precision_0=1.0, recall_0=1.0)¶
F1 score of the replay when a fraction
Rof the motifs ignites.An ignited motif is replayed with the precision and recall of the intact trigger, a silent one only adds false negatives. Per spike of the motifs, the true positives are
R recall_0, the false negatives1 - R recall_0and the false positivesR recall_0 (1 / precision_0 - 1), so thatF1 = 2 R recall_0 / (1 + R recall_0 / precision_0).
- mnesis_boilerplate.get_trigger_presence(p_flip, p_A, num_delay, fraction=1.0, N_trigger_time=None)¶
Probability that a spike of the spiking-motif window is present in a degraded trigger.
A spike of the motif lying in bin
iof the window (0 <= i < num_delay) is present if it falls in the part that the trigger shows, the lastN_trigger_timebins (a truncated trigger) on thefractionof neurons left active (a lesioned one), and survives the balanced flips, which keep it with probability1 - p_flip (1 - p_A).- Parameters:
p_flip (float or np.ndarray) – bit-flip probability of the trigger (dimensionless).
p_A (float) – firing probability of the motif (spike per time bin).
num_delay (int) – width of the spiking-motif window (time bins).
fraction (float or np.ndarray) – fraction of the neurons shown by the trigger (dimensionless, 1 for an intact trigger).
N_trigger_time (float or np.ndarray) – number of bins shown at the end of the window (time bins);
Noneshows the whole window.
- Returns:
presence probability, shaped like the broadcast of the arguments with a last axis of
num_delaybins.- Return type:
np.ndarray
- mnesis_boilerplate.get_f1_ignition(p_flip, p_A, N_neuron, num_delay, lif_threshold, precision_0=1.0, recall_0=1.0, fraction=1.0, N_trigger_time=None)¶
F1 score expected when a degraded trigger ignites, or not, the replay of each motif.
Mean-field model of the pseudo-inverse readout (
mnesis_chains.HD_SNN.get_W_init()): each spike of a motif is supported by theKspikes of that motif in thenum_delaybins before it. The minimum-norm solution gives these supporting spikes equal weights, so the membrane reaches 1 when all of them are present andk / Kwhen onlykof them are: the spike is emitted ifk >= ceil(lif_threshold K). A spurious spike of the trigger falls on a near-zero weight, as the motifs are sparse.The replay is a cascade, a positive feedback loop: each emitted spike joins the support of the next ones, so that once the first evoked spike of a motif is emitted, the following ones see more and more of their support and the replay ignites as a whole (the noise-free motif being a stable fixed point); if it fails, the support of the next spikes keeps shrinking and the replay dies out (
get_f1_cascade()simulates the whole cascade and checks that its first step decides it). The ignition probability is thus that of the first evoked spike. The motif firesmu = p_A N_neuronspikes per bin, so this spike comesjbins after the trigger with probabilityP(j) = exp(-mu j) (1 - exp(-mu)); its support then lies in the lastnum_delay - jbins of the trigger window, so thatKis Poisson of meanlam_j = mu (num_delay - j)and a supporting spike is present with the meanq_jofget_trigger_presence()over these bins. HenceR = sum_j P(j) sum_{K >= 1} Poisson(K; lam_j) P(Binomial(K, q_j) >= ceil(lif_threshold K)),normalised by its value for an intact trigger, whose failures (motifs with a gap longer than the window) are already counted in
recall_0. For scattered losses (flips, lesioned neurons),q_j = qdoes not depend onj; for a truncated trigger, the support of the first evoked spike is more recent than a whole window, and so better shown than the fractionN_trigger_time / num_delayof the window. The F1 score follows fromRbyget_f1_from_ignition().- Parameters:
p_flip (float or np.ndarray) – bit-flip probability of the trigger (dimensionless).
p_A (float) – firing probability of the motif (spike per time bin).
N_neuron (int) – number of neurons.
num_delay (int) – width of the spiking-motif window (time bins).
lif_threshold (float) – firing threshold, relative to the membrane potential reached on the motif (dimensionless).
precision_0 (float) – precision of the replay with the intact trigger.
recall_0 (float) – recall of the replay with the intact trigger.
fraction (float or np.ndarray) – fraction of the neurons shown by the trigger (dimensionless, 1 for an intact trigger).
N_trigger_time (float or np.ndarray) – number of bins shown at the end of the window (time bins);
Noneshows the whole window.
- Returns:
expected F1 score, shaped like the broadcast of
p_flip,fractionandN_trigger_time.- Return type:
np.ndarray
- mnesis_boilerplate.get_replay_hazard(p_drop, p_A, N_neuron, num_delay, lif_threshold)¶
Failure rate of a sustained replay under spike transmission failures.
During a sustained replay, the context of each spike of a motif is made of the network’s own output only. If every emitted spike fails to reach the recurrent input with probability
p_drop, independently, each spike of the motif is a new ignition test: the first evoked spike ofget_f1_ignition(), with a context spanning the whole window (KPoisson of meanp_A N_neuron num_delay) and a presence probabilityq = 1 - p_drop. A step holds a spike of the motif with probability1 - exp(-p_A N_neuron), and the first failed spike is taken to end the replay (the positive feedback loop then shrinks the next contexts), so that the replay surviveststeps with probabilityexp(-h t). The contexts withK = 0(a gap ofnum_delaysilent steps) are left out, as their failures are already counted in the recall of the intact replay.- Parameters:
p_drop (float or np.ndarray) – probability that an emitted spike is not transmitted to the recurrent input (dimensionless).
p_A (float) – firing probability of the motif (spike per time step).
N_neuron (int) – number of neurons.
num_delay (int) – width of the spiking-motif window (time steps).
lif_threshold (float) – firing threshold, relative to the membrane potential reached on the motif (dimensionless).
- Returns:
failure rate
h(per time step), shaped likep_drop.- Return type:
np.ndarray
- mnesis_boilerplate.simulate_cascade(counts, present_trigger, num_delay, lif_threshold)¶
Replay of motifs by the mean-field threshold readout, bin after bin (the cascade).
In the mean-field picture of the pseudo-inverse readout (see
get_f1_ignition()), all the spikes of a motif in bintshare the same support, theKspikes of the motif in thenum_delaybins beforet, with equal weights: they are emitted together if at leastceil(lif_threshold K)of theseKspikes are present, and never ifK = 0(a gap ofnum_delaysilent bins, which the replay cannot cross). The emitted spikes join the support of the next ones (the positive feedback loop); spurious spikes, which fall on near-zero weights, are left out, so that only the number of spikes per bin matters.- Parameters:
counts (np.ndarray) – spikes of each motif per bin,
(N_motif, N_time).present_trigger (np.ndarray) – spikes of each motif present in the trigger, per bin of the window,
(N_motif, num_delay).num_delay (int) – width of the spiking-motif window (time bins).
lif_threshold (float) – firing threshold, relative to the membrane potential reached on the motif (dimensionless).
- Returns:
emitted spikes per bin,
(N_motif, N_time); the firstnum_delaybins hold the trigger.- Return type:
np.ndarray
- mnesis_boilerplate.get_cascade_motifs(N_motif, N_neuron, N_time, p_A, num_delay, seed=2026)¶
Random motifs for the cascade model, with the identity of the trigger spikes.
Draws
Binomial(N_neuron, p_A)spikes per bin, as the frozen motifs of the network (mnesis_chains.StochasticSpikingPattern), and, for each spike of the trigger window, the neuron that fires it and a uniform number that decides whether a bit flip removes it: the identity of the neurons matters for a lesioned trigger, which always silences the same neurons.- Parameters:
- Returns:
counts(N_motif, N_time), and per trigger spike slot(N_motif, num_delay, n_max):in_bin(the slot holds a spike),neuronandu; input ofget_cascade_presence().- Return type:
- mnesis_boilerplate.get_cascade_presence(motifs, p_flip, p_A, n_lesion=0, N_trigger_time=None)¶
Spikes of each motif present in a degraded trigger, per bin of the window.
A spike of the trigger window is present if it falls in the last
N_trigger_timebins (a truncated trigger), is not fired by one of the firstn_lesionneurons (a lesioned trigger, as in notebook 16) and survives the balanced flips, which keep it with probability1 - p_flip (1 - p_A)(get_trigger_presence()gives the same probabilities, averaged over the neurons).- Parameters:
motifs (dict) – motifs drawn by
get_cascade_motifs().p_flip (float) – bit-flip probability of the trigger (dimensionless).
p_A (float) – firing probability of the motif (spike per time bin).
n_lesion (int) – number of silenced neurons.
N_trigger_time (int) – number of bins shown at the end of the window (time bins);
Noneshows the whole window.
- Returns:
present spikes per bin,
(N_motif, num_delay).- Return type:
np.ndarray
- mnesis_boilerplate.get_f1_cascade(p_flip, p_A, N_neuron, num_delay, lif_threshold, precision_0=1.0, recall_0=1.0, fraction=1.0, N_trigger_time=None, N_time=1000, N_motif=1000, seed=2026)¶
F1 score expected from the simulated cascade of the replay, on random motifs (Monte Carlo).
Simulates the threshold network that
get_f1_ignition()reduces to its first step (simulate_cascade()) onN_motifrandom motifs of the whole durationN_time(get_cascade_motifs()), so that it also checks that the first evoked spike decides the replay. The pooled recall of the motifs, normalised by its value for an intact trigger on the same motifs (which removes the failures at a gap ofnum_delaysilent bins, already counted inrecall_0), is the ignition probabilityR, and the F1 score follows fromget_f1_from_ignition(). All the degradation levels share the same motifs and draws (common random numbers), so that the curve is smooth.- Parameters:
p_flip (float or np.ndarray) – bit-flip probability of the trigger (dimensionless).
p_A (float) – firing probability of the motif (spike per time bin).
N_neuron (int) – number of neurons.
num_delay (int) – width of the spiking-motif window (time bins).
lif_threshold (float) – firing threshold, relative to the membrane potential reached on the motif (dimensionless).
precision_0 (float) – precision of the replay with the intact trigger.
recall_0 (float) – recall of the replay with the intact trigger.
fraction (float or np.ndarray) – fraction of the neurons shown by the trigger (dimensionless, 1 for an intact trigger); the
(1 - fraction) N_neuronfirst neurons are silenced.N_trigger_time (float or np.ndarray) – number of bins shown at the end of the window (time bins);
Noneshows the whole window.N_time (int) – duration of a motif (time bins).
N_motif (int) – number of simulated motifs.
seed (int) – seed of the random generator.
- Returns:
expected F1 score, shaped like the broadcast of
p_flip,fractionandN_trigger_time.- Return type:
np.ndarray
- mnesis_boilerplate.get_cascade_prediction(frozen_target, num_delay, lif_threshold, cue=None, n_lesion=0, N_trigger_time=None)¶
Replay of each frozen motif of the network predicted by the cascade model.
Applies
simulate_cascade()to the actual motifs, with no fitted parameter: a spike of the trigger window is present if it is shown (the lastN_trigger_timebins, not one of the firstn_lesionneurons) and, when a noisy realisationcueprovides the trigger, if this realisation kept it. The model predicts the recall of each motif, not its precision, as it leaves out the crosstalk between motifs.- Parameters:
frozen_target (torch.Tensor or np.ndarray) – frozen motifs,
(N_pattern, N_neuron, N_time).num_delay (int) – width of the spiking-motif window (time bins).
lif_threshold (float) – firing threshold, relative to the membrane potential reached on the motif (dimensionless).
cue (torch.Tensor or np.ndarray) – noisy realisation providing the trigger, of the same shape;
Nonefor the frozen motif itself.n_lesion (int) – number of silenced neurons (the first ones).
N_trigger_time (int) – number of bins shown at the end of the window (time bins);
Noneshows the whole window.
- Returns:
per motif,
recall(predicted recall of the evoked window),t_stop(first spike of the motif that is not replayed, in time bins from the onset of the motif,nanif the replay reaches the end) andt_gap(onset of the first gap ofnum_delaysilent bins in the evoked window,nanif there is none).- Return type:
- mnesis_boilerplate.get_recall_time(spikes, target, bin_width)¶
Recall of each motif in successive time bins of the evoked window.
Shows the dynamics of the replay: once ignited, the recall of a motif stays near that of the intact trigger; otherwise it falls to zero.
- Parameters:
spikes (torch.Tensor) – evoked spikes, of shape
(N_pattern, N_neuron, N_time).target (torch.Tensor) – target spikes, of the same shape.
bin_width (int) – width of a time bin (time bins); the last incomplete bin is left out.
- Returns:
recall of shape
(N_pattern, N_time // bin_width),nanin a bin without any target spike.- Return type:
np.ndarray
- mnesis_boilerplate.plot_recall_time(ax, recall_time, labels, recall_open=None, bin_width=1, cmap='viridis')¶
Plot the recall of each motif against time, one colour per degradation level.
Thin lines are single motifs (bistable: they stay near the recall of the intact trigger or fall to zero), thick lines their mean; the dashed black line is the mean recall of the open-loop control, and the grey dashed lines mark the extremal values 0 and 1.
- Parameters:
ax (matplotlib.axes.Axes) – axes to draw in.
recall_time (list of np.ndarray) – one
(N_pattern, N_bin)array per level, as returned byget_recall_time().recall_open (np.ndarray) – recall of the open-loop control, or
None.bin_width (float) – width of a time bin (ms).
cmap (str) – colormap of the levels.
- class mnesis_boilerplate.SpikeF1scoreLoss(epsilon=1e-12)¶
Bases:
ModuleTraining loss
L = 1 - F1between predicted and target spikes.Initialize internal Module state, shared by both nn.Module and ScriptModule.
- forward(pred, target)¶
Return
1 - F1score(pred, target), differentiable via the surrogate.
- mnesis_boilerplate.get_cosine_schedule_with_warmup(optimizer, num_warmup_epochs, num_epochs, rel_final_lr)¶
Cosine learning-rate decay with warmup, as a
torchLambdaLR.The learning-rate multiplier is constant (1) during
num_warmup_epochs, then follows a half-cosine from 1 down torel_final_lr(final_lr / base_lr) atnum_epochs.