SpikingResNet
Out-of-distribution (OoD) detectors, built on top of models trained on a single dataset (in-distribution, ID), should flag test-time inputs that don't belong to that distribution. Spike-like models replace standard ReLU activations with leaky integrate-and-fire (LIF) neurons on conventional ResNet backbones, operating at a single inference time step to achieve binary spike activations and substantially reduced arithmetic complexity, while remaining competitive with full-precision CNN baselines on OpenOOD benchmarks.
Full code: https://github.com/Alex-TLR/spikingResNet
About the OoD experiments
Two difficulties are evaluated: near-OoD (a semantically similar dataset, e.g. CIFAR-100 against a CIFAR-10 model) and far-OoD (a very different one, e.g. SVHN/MNIST). Detectors are scored by AUROC (higher is better) and FPR95 (false-positive rate at 95% true-positive rate, lower is better). The experiments conform to the OpenOoD benchmark.
How this repository is organized
The code includes the inference-only pipeline, the OoD benchmarks, and one folder per model "family" (architecture + dataset). Within each family, checkpoints are grouped by experiment (loss function + training time steps), then by expansion/seed:
spikingresnet/
├── code/ <- inference and OoD code
├── checkpoints.csv <- every checkpoint in this repo, one row each
└── <family>/<experiment>/T<T>_E<E>_S<seed>/
├── config.json
└── model.safetensors
495 checkpoints across 7 families:
resnet10-cifar10-- CIFAR10, 25 checkpointsresnet18-cifar10-- CIFAR10, 25 checkpointsresnet4-cifar10-- CIFAR10, 25 checkpointsspikingresnet4-cifar10-- CIFAR10, 75 checkpointsspikingresnet10-cifar10-- CIFAR10, 75 checkpointsspikingresnet18-cifar10-- CIFAR10, 150 checkpointsspikingresnet18-cifar100-- CIFAR100, 120 checkpoints
Every experiment sweeps all 5 seeds (42, 1987, 1991, 2020, 2024) across its listed expansions -- checkpoints.csv gives the exact seed of
every checkpoint -- see "Running an OoD benchmark" below to reproduce the results.
Quick start
Install the required packages:
pip install -r code/requirements.txt
See what models are available:
python code/run_example.py dsluga/spikingresnet --list
python code/run_example.py dsluga/spikingresnet --list resnet10-cifar10
Run one checkpoint:
python code/run_example.py dsluga/spikingresnet --subfolder resnet10-cifar10/cross-entropy-baseline/T1_E10_S1987
Running an OoD benchmark
The option --experiment picks which detector to run:
posthoc(default) -- scoring computed directly from a trained model's outputs, no extra training or feature bank needed: MSP (max softmax probability), Energy, MLS (max logit score), and ASH (activation shaping);knn-- a k-nearest-neighbors detector over penultimate-layer features.
Sample run of the knn OoD detection benchmark:
python code/run_example.py --experiment knn dsluga/spikingresnet --all-seeds \
--subfolder resnet10-cifar10/cross-entropy-baseline/T1_E10
Datasets
By default, the benchmark only uses datasets that torchvision downloads automatically (CIFAR-10/100, SVHN, MNIST). The full benchmark also evaluates on Textures (DTD), Places365, and Tiny-ImageNet-200; fetch those directly from their original hosts with:
python code/spikingresnet_code/download_datasets.py textures tiny_imagenet # ~850MB
python code/spikingresnet_code/download_datasets.py places365 # ~25-30GB
then edit code/run_example.py's NEAR_OOD/FAR_OOD lists to include them in a benchmark run, e.g.:
NEAR_OOD = ['CIFAR10', 'CIFAR100', 'tImage200']
FAR_OOD = ['MNIST', 'SVHN', 'Textures', 'Places365']
Model list
resnet10-cifar10
Dataset: CIFAR10
| experiment folder | type | backbone | loss | training | expansions | seeds | # checkpoints |
|---|---|---|---|---|---|---|---|
cross-entropy-baseline |
conv | resnet10 | cross_entropy | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
25 checkpoints total. The table above groups them by experiment; every individual subfolder/config/seed is listed in the repo-root checkpoints.csv.
Example: subfolder="resnet10-cifar10/cross-entropy-baseline/T1_E10_S1987"
resnet18-cifar10
Dataset: CIFAR10
| experiment folder | type | backbone | loss | training | expansions | seeds | # checkpoints |
|---|---|---|---|---|---|---|---|
cross-entropy-baseline |
conv | resnet18 | cross_entropy | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
25 checkpoints total. The table above groups them by experiment; every individual subfolder/config/seed is listed in the repo-root checkpoints.csv.
Example: subfolder="resnet18-cifar10/cross-entropy-baseline/T1_E1_S42"
resnet4-cifar10
Dataset: CIFAR10
| experiment folder | type | backbone | loss | training | expansions | seeds | # checkpoints |
|---|---|---|---|---|---|---|---|
cross-entropy-baseline |
conv | resnet4 | cross_entropy | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
25 checkpoints total. The table above groups them by experiment; every individual subfolder/config/seed is listed in the repo-root checkpoints.csv.
Example: subfolder="resnet4-cifar10/cross-entropy-baseline/T1_E10_S1987"
spikingresnet4-cifar10
Dataset: CIFAR10
| experiment folder | type | backbone | loss | training | expansions | seeds | # checkpoints |
|---|---|---|---|---|---|---|---|
count-loss-t1-train |
spike | resnet4 | count_loss | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
cross-entropy-t1-train |
spike | resnet4 | cross_entropy | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
mse-loss-t1-train |
spike | resnet4 | mse_count_loss | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
75 checkpoints total. The table above groups them by experiment; every individual subfolder/config/seed is listed in the repo-root checkpoints.csv.
Example: subfolder="spikingresnet4-cifar10/mse-loss-t1-train/T1_E10_S1987"
spikingresnet10-cifar10
Dataset: CIFAR10
| experiment folder | type | backbone | loss | training | expansions | seeds | # checkpoints |
|---|---|---|---|---|---|---|---|
count-loss-t1-train |
spike | resnet10 | count_loss | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
cross-entropy-t1-train |
spike | resnet10 | cross_entropy | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
mse-loss-t1-train |
spike | resnet10 | mse_count_loss | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
75 checkpoints total. The table above groups them by experiment; every individual subfolder/config/seed is listed in the repo-root checkpoints.csv.
Example: subfolder="spikingresnet10-cifar10/mse-loss-t1-train/T1_E10_S1987"
spikingresnet18-cifar10
Dataset: CIFAR10
| experiment folder | type | backbone | loss | training | expansions | seeds | # checkpoints |
|---|---|---|---|---|---|---|---|
count-loss-t1-train |
spike | resnet18 | count_loss | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
cross-entropy-t1-train |
spike | resnet18 | cross_entropy | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
mse-loss-t1-train |
spike | resnet18 | mse_count_loss | T=1 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
mse-loss-t2-train |
spike | resnet18 | mse_count_loss | T=2 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
mse-loss-t4-train |
spike | resnet18 | mse_count_loss | T=4 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
mse-loss-t8-train |
spike | resnet18 | mse_count_loss | T=8 | E in [1, 5, 10, 25, 50] | seeds [42, 1987, 1991, 2020, 2024] | 25 |
150 checkpoints total. The table above groups them by experiment; every individual subfolder/config/seed is listed in the repo-root checkpoints.csv.
Example: subfolder="spikingresnet18-cifar10/mse-loss-t1-train/T1_E5_S42"
spikingresnet18-cifar100
Dataset: CIFAR100
| experiment folder | type | backbone | loss | training | expansions | seeds | # checkpoints |
|---|---|---|---|---|---|---|---|
mse-loss-t1-train |
spike | resnet18 | mse_count_loss | T=1 | E in [25, 50, 100, 250, 500, 1000] | seeds [42, 1987, 1991, 2020, 2024] | 30 |
mse-loss-t2-train |
spike | resnet18 | mse_count_loss | T=2 | E in [25, 50, 100, 250, 500, 1000] | seeds [42, 1987, 1991, 2020, 2024] | 30 |
mse-loss-t4-train |
spike | resnet18 | mse_count_loss | T=4 | E in [25, 50, 100, 250, 500, 1000] | seeds [42, 1987, 1991, 2020, 2024] | 30 |
mse-loss-t8-train |
spike | resnet18 | mse_count_loss | T=8 | E in [25, 50, 100, 250, 500, 1000] | seeds [42, 1987, 1991, 2020, 2024] | 30 |
120 checkpoints total. The table above groups them by experiment; every individual subfolder/config/seed is listed in the repo-root checkpoints.csv.
Example: subfolder="spikingresnet18-cifar100/mse-loss-t1-train/T1_E50_S42"
Citation
@article{spikingresnet_ood,
title = {Out-of-Distribution Detection with Spike-Like Networks: Population Coding, Training Depth, and Single-Step Feature Representations},
author = {A. Avramović, S. Gajić, V. Jovanović, V. Risojević, D. Sluga},
journal = {},
}