A minimal Spike Coding Network (SCN) implementation for comparing predictive coding-based spike coding against baseline population codes on simple 1D signal tracking tasks.
This project aims to build and study a minimal Spike Coding Network (SCN) – a "spike coding machine" in which:
- Membrane potentials represent prediction errors
- Spikes are emitted only if they reduce a well-defined coding error plus spike cost
The SCN is compared against a simpler baseline population code (e.g., independent Poisson or standard LIF + rate-based decoder) on a simple task: track a time-varying 1D signal with spikes that are as informative and sparse as possible.
In class-2 predictive coding / SCNs, the network is designed from an objective function:
- The network is derived from input signal (s(t)), decoder (X), error function (E), and cost function (C)
- Membrane potentials encode prediction error between s(t) and ŝ(t)
- A neuron spikes only if that spike is expected to reduce (E + C)
- Recurrent connectivity is derived from the decoder, rather than arbitrary
This entangles encoding and decoding: what counts as an efficient code depends on the decoder and the task.
Predictive-Coding-SNN/
├── .cursor/ # Cursor AI rules
│ └── rules/ # Project rules in MDC format
├── src/ # Source code
│ └── scn/ # Main package
│ ├── models/ # SCN and baseline models
│ ├── decoders/ # Decoder implementations
│ ├── signals/ # Input signal generators
│ └── utils/ # Utility functions
├── tests/ # Test suite
│ ├── test_models/
│ ├── test_decoders/
│ └── test_signals/
├── notebooks/ # Jupyter notebooks for exploration
├── experiments/ # Experiment scripts
└── docs/ # Documentation
Membrane Potential: Encodes prediction error
V_i(t) = w_i * (s(t) - ŝ(t))
Spike Rule: Neuron spikes only if it reduces error + cost
Spike if: V_i(t) > Θ_i, where Θ_i = (w_i² + C) / 2
Decoder: Linear decoder with exponential kernel
ŝ(t) = Σ_i w_i * r_i(t)
Connectivity: Derived from decoder weights
- Feedforward: proportional to w_i
- Recurrent: proportional to -w_i * w_j
- Independent Poisson: Each neuron fires according to a tuning curve, no error-based coordination
- LIF Population: Standard leaky integrate-and-fire neurons with fixed rates, no decoder-derived connectivity
- Python 3.8 or higher
- pip or conda
- Clone the repository:
git clone <repository-url>
cd Predictive-Coding-SNN- Create a virtual environment (recommended):
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate- Install dependencies:
pip install -r requirements.txt- Install the package in development mode:
pip install -e .# Run all tests
pytest
# Run with coverage
pytest --cov=src --cov-report=html
# Run specific test file
pytest tests/test_models/test_scn.py- Agree on SCN derivation variant (strict Box 3 vs simplified discrete)
- Choose baseline model (Poisson vs LIF)
- Confirm programming framework
- Implement discrete-time SCN with scalar s(t)
- Decoder W = (w_i)
- Rate dynamics r_i(t)
- SCN spike rule: V_i(t) > Θ_i
- Verify behavior for simple signals
- Implement chosen baseline (Poisson or LIF)
- Match overall firing rates to SCN
- Run side-by-side comparisons:
- Reconstruction error
- Spike efficiency
- Variability and coding degeneracy
- Robustness to neuron loss
- Vector inputs: extend SCN from scalar s(t) to mel-spectra s(t) ∈ R^D
- LibriSpeech log-mel frame autoencoder (train-clean-100 subset)
- Phase 3A: No-learning demo – fixed SCN decoder on speech chunks
- Phase 3B: Learned linear readout on top of fixed SCN
- Phase 3C: Trainable SCN decoder with surrogate gradients on speech
- Reconstruction Error: Mean squared error between s(t) and ŝ(t)
- Efficiency: Average number of spikes per neuron per second
- Variability: ISI CV, Fano factor, spike pattern variability
- Robustness: Performance degradation when neurons are silenced
- Scaling: How reconstruction error scales with network size
For LibriSpeech experiments (Phase 3), each run writes JSON summaries under
results/librispeech/:
phase3a_librispeech_scn_summary.json: reconstruction MSE, spike counts, example plots.phase3b_librispeech_readout_summary.json: epoch-wise MSE for the learned readout.phase3c_librispeech_scn_trainable_summary.json: epoch-wise reconstruction and spike costs.
Quick Start: See QUICK_START.md for detailed step-by-step instructions.
TL;DR - Quick test with dummy dataset:
python -m experiments.librispeech_autoencoder \
--use-hf-backend \
--phase 3a \
--max-batches 1 \
--batch-size 2-
Choose a LibriSpeech backend:
- Hugging Face backend (recommended for quick start):
- Defaults to tiny dummy dataset (
distil-whisper/librispeech_asr_dummy, ~18 MB) - No local download required
- Just add
--use-hf-backendflag
- Defaults to tiny dummy dataset (
- Local torchaudio: Install
torchaudioand download LibriSpeech, then point--rootto the LibriSpeech root directory.
- Hugging Face backend (recommended for quick start):
-
Run experiments:
# Quick test with dummy dataset (recommended first step)
python -m experiments.librispeech_autoencoder --use-hf-backend --phase 3a
# Full training with real LibriSpeech
python -m experiments.librispeech_autoencoder \
--use-hf-backend \
--hf-dataset-name "openslr/librispeech_asr" \
--hf-split "train_clean_100[:10%]" \
--phase all \
--batch-size 16- Inspect results: JSON summaries and plots are saved in
results/librispeech_real/(or your custom--results-dir). See QUICK_START.md for details.
- Primary: snnTorch for SNN implementation
- Base: PyTorch for tensor operations
- Testing: pytest with coverage
- Visualization: matplotlib
[To be determined]
[To be determined]
[To be added]