| name | spike-agreement-dependent-plasticity |
| description | Spike Agreement Dependent Plasticity (SADP) - biologically inspired learning rule for SNNs using population-level correlation metrics instead of precise spike timing. Activation triggers: spike agreement, synaptic plasticity, SNN learning, bio-inspired learning, population correlation, neuromorphic learning. |
Spike Agreement Dependent Plasticity (SADP)
Biologically inspired synaptic learning rule for Spiking Neural Networks that relies on the agreement between pre- and post-synaptic spike trains rather than precise spike-pair timing, achieving superior performance with linear-time complexity.
Metadata
- Source: arXiv:2508.16216 [cs.NE]
- Authors: Saptarshi Bej, Muhammed Sahad E, Gouri Lakshmi, Harshit Kumar, Pritam Kar, Bikas C Das
- Published: 2025-08-22
- Categories: cs.NE (Neural and Evolutionary Computing), cs.LG (Machine Learning)
Core Methodology
Key Innovation
Traditional STDP (Spike-Timing-Dependent Plasticity) relies on precise temporal correlations between individual pre- and post-synaptic spikes, which is computationally expensive and hardware-unfriendly. SADP generalizes STDP by:
- Replacing pairwise timing with population-level correlation metrics
- Using Cohen's kappa and other agreement statistics
- Achieving linear-time complexity $O(n)$ vs STDP's $O(n^2)$
- Enabling hardware-efficient implementation via bitwise logic
Technical Framework
1. Spike Train Representation
Instead of tracking individual spike times, SADP operates on spike train agreement:
- Binary representation: Spike trains as binary vectors
- Population view: Aggregated statistics over time windows
- Agreement metric: Statistical agreement between pre and post populations
2. Cohen's Kappa as Plasticity Signal
$$\kappa = \frac{p_o - p_e}{1 - p_e}$$
Where:
- $p_o$: Observed agreement between spike trains
- $p_e$: Expected agreement (chance level)
- $\kappa \in [-1, 1]$: Agreement strength
3. SADP Update Rule
$$\Delta w_{ij} = \eta \cdot \kappa(x_i, x_j) \cdot \text{spline}_w(t)$$
Where:
- $\eta$: Learning rate
- $\kappa(x_i, x_j)$: Agreement between pre ($x_i$) and post ($x_j$) spike trains
- $\text{spline}_w(t)$: Time-windowed spline kernel
4. Spline-Based Kernels
- Derived from experimental iontronic organic memtransistor device data
- Captures temporal dependencies without precise timing
- Hardware-friendly continuous approximation
Implementation Guide
Prerequisites
- Python 3.8+
- PyTorch or TensorFlow
- NumPy, SciPy
- Optional: Brian2 or other SNN framework
Step-by-Step Implementation
import numpy as np
import torch
import torch.nn as nn
from typing import Tuple, Optional
class SADPLearner:
"""
Spike Agreement Dependent Plasticity for SNN training
"""
def __init__(
self,
learning_rate: float = 0.01,
time_window: int = 20,
kernel_type: str = 'spline',
device: str = 'cpu'
):
self.learning_rate = learning_rate
self.time_window = time_window
self.kernel_type = kernel_type
self.device = device
self.kernel = self._create_spline_kernel(time_window)
def _create_spline_kernel(self, window_size: int) -> torch.Tensor:
"""
Create spline-based temporal kernel from memtransistor data
Args:
window_size: Temporal window size in time steps
Returns:
kernel: [window_size] spline kernel weights
"""
t = torch.linspace(0, 1, window_size)
kernel = torch.sin(np.pi * t) * torch.exp(- * t)
kernel = kernel / kernel.()
kernel
() -> torch.Tensor:
num_pre, T = pre_spikes.shape
num_post = post_spikes.shape[]
agreement = torch.zeros(num_pre, num_post, device=.device)
t (T):
pre_t = pre_spikes[:, t].unsqueeze()
post_t = post_spikes[:, t].unsqueeze()
agreement_t = (pre_t == post_t).()
t < (.kernel):
agreement += agreement_t * .kernel[t]
agreement = agreement / .kernel.()
p_o = agreement
pre_rate = pre_spikes.().mean(dim=, keepdim=)
post_rate = post_spikes.().mean(dim=, keepdim=)
p_e = pre_rate * post_rate + ( - pre_rate) * ( - post_rate)
kappa = (p_o - p_e) / ( - p_e + )
kappa
() -> torch.Tensor:
kappa = .compute_spike_agreement(pre_spikes, post_spikes)
delta_w = .learning_rate * kappa
spike_times :
time_weights = ._apply_temporal_kernel(spike_times)
delta_w = delta_w * time_weights
delta_w = torch.clamp(delta_w, -, )
delta_w
() -> torch.Tensor:
time_weights = torch.exp(-torch.(spike_times) / .time_window)
time_weights
(nn.Module):
():
().__init__()
.in_features = in_features
.out_features = out_features
.time_steps = time_steps
.threshold = threshold
.tau_mem = tau_mem
.weight = nn.Parameter(torch.randn(out_features, in_features) * )
.sadp = SADPLearner(**sadp_kwargs)
.reset_state()
():
.mem =
.pre_spike_history = []
.post_spike_history = []
() -> torch.Tensor:
batch_size = x.size()
.mem :
.mem = torch.zeros(batch_size, .out_features, device=x.device)
output_spikes = []
t (.time_steps):
x_t = x[:, t, :]
current = torch.matmul(x_t, .weight.t())
.mem = .mem * np.exp(- / .tau_mem) + current
spike = (.mem >= .threshold).()
.mem = .mem * ( - spike)
output_spikes.append(spike)
.training:
.pre_spike_history.append(x_t.mean(dim=))
.post_spike_history.append(spike.mean(dim=))
torch.stack(output_spikes, dim=)
():
(.pre_spike_history) == :
pre_spikes = torch.stack(.pre_spike_history, dim=)
post_spikes = torch.stack(.post_spike_history, dim=)
j (.out_features):
post_j = post_spikes[j:j+]
kappa = .sadp.compute_spike_agreement(
pre_spikes.t(),
post_j.t().expand(pre_spikes.size(), -).t()
)
.weight.data[j] += .sadp.learning_rate * kappa[]
.pre_spike_history = []
.post_spike_history = []
:
() -> :
disagreement = np.bitwise_xor(pre_spikes.astype(np.uint8),
post_spikes.astype(np.uint8))
p_o = - np.mean(disagreement)
p_pre = np.mean(pre_spikes)
p_post = np.mean(post_spikes)
p_e = p_pre * p_post + ( - p_pre) * ( - p_post)
kappa = (p_o - p_e) / ( - p_e + )
kappa
Training Loop
def train_sadp_snn(
model: SADPLayer,
train_loader,
epochs: int = 10,
device: str = 'cpu'
):
"""
Train SNN with SADP
Args:
model: SADP-enabled SNN layer
train_loader: DataLoader with (input_spikes, labels)
epochs: Number of training epochs
device: 'cpu' or 'cuda'
"""
model.to(device)
for epoch in range(epochs):
total_correct = 0
total_samples = 0
for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(device), target.to(device)
model.reset_state()
output = model(data)
model.learn()
spike_count = output.sum(dim=1)
predicted = spike_count.argmax(dim=1)
total_correct += (predicted == target).sum().item()
total_samples += target.size(0)
if batch_idx % 100 == 0:
acc = 100. * total_correct / total_samples
print(f'Epoch {epoch}, Batch {batch_idx}, Acc: {acc:.2f}%')
print(f'Epoch {epoch} complete, Accuracy: %')
Applications
1. Pattern Recognition
- MNIST Classification: High accuracy with minimal time steps
- Fashion-MNIST: Robust to image variations
- Spoken Digit Recognition: Audio processing with spikes
2. Neuromorphic Hardware
- Intel Loihi: Efficient on-chip learning
- IBM TrueNorth: Massive parallel processing
- Custom ASICs: Low-power edge devices
- Memristive Crossbars: In-memory computation
3. Edge AI
- Real-time Processing: Low latency inference
- Ultra-low Power: Event-driven computation
- Always-on Sensors: Battery-powered devices
4. Brain-Machine Interfaces
- Neural Decoding: Learn from biological spikes
- Adaptive Control: Online learning
- Long-term Stability: Reduced weight drift
Pitfalls
-
Hyperparameter Sensitivity: Time window and kernel parameters matter
- Mitigation: Cross-validation, grid search, or meta-learning
-
Hardware Variability: Memtransistor characteristics vary
- Mitigation: Device-specific kernel calibration, robust training
-
Sparse Activity: Very sparse spikes can lead to zero gradients
- Mitigation: Activity regularization, minimum spike rate constraints
-
Scaling Challenges: Large networks need careful initialization
- Mitigation: Layer-wise pre-training, weight normalization
-
Binary vs Analog: Pure binary spikes lose timing precision
- Mitigation: Multi-bit spike encoding, temporal binning
Related Skills
- stdp-learning: Traditional spike-timing-dependent plasticity
- snn-training: General SNN training methods
- neuromorphic-computing: Hardware implementations
- memristor-snn: Memristor-based SNN learning
References
@article{bej2025sadp,
title={Spike Agreement Dependent Plasticity: A scalable Bio-Inspired learning paradigm for Spiking Neural Networks},
author={Bej, Saptarshi and E, Muhammed Sahad and Lakshmi, Gouri and Kumar, Harshit and Kar, Pritam and Das, Bikas C},
journal={arXiv preprint arXiv:2508.16216},
year={2025}
}
Further Reading
- STDP: Bi & Poo, "Synaptic modification by correlated activity"
- Neuromorphic Hardware: Davies et al., "Loihi: A Neuromorphic Manycore Processor"
- Memtransistors: Yang et al., "Memristive Devices for Computation"
- Spline Kernels: de Boor, "A Practical Guide to Splines"