
Código de investigación que implementa T-Backdoor, ataques de puerta trasera con activador temporal en redes neuronales de impulsos utilizando activadores de tasa, latencia y jitter sin perturbación espacial.
Los ataques de puerta trasera son una amenaza de seguridad grave para las redes neuronales profundas (DNN) y siguen estando en gran medida poco explorados en las redes neuronales de picos (SNN). Los ataques existentes introducen principalmente disparadores espaciotemporales que inducen desviaciones en la distribución de picos de las muestras envenenadas respecto a sus contrapartes limpias. Para abordar esta limitación, este trabajo propone un novedoso ataque de puerta trasera sobre SNN, denominado \textbf{T-Backdoor}, que opera utilizando disparadores puramente temporales como \textit{Rate}, \textit{Latency} y \textit{Jitter} sin introducir ninguna perturbación espacial, lo que hace que el cambio en las distribuciones de picos sea significativamente más difícil de detectar. Mediante experimentos exhaustivos en tres conjuntos de datos neuromórficos de referencia: N-MNIST, CIFAR10-DVS y N-Caltech101, y la evaluación frente a siete métodos de defensa de puerta trasera de referencia, demostramos que T-Backdoor alcanza una tasa de éxito de ataque (ASR) casi perfecta del 100% tanto en configuraciones de objetivo único como de objetivos múltiples, con solo una degradación menor en la precisión limpia, a la vez que se mantiene robusto frente a las técnicas existentes de detección y mitigación de puertas traseras.
├── models.py # Architectures for all datasets (shared)
├── datasets.py # Neuromorphic dataset loading (shared)
│
├── main_single.py # 1. Single-target entry point
├── single_poisoned_dataset.py # Trigger implementations + loaders
├── single_utils.py # Train/eval loop, saving, plots
├── single_target.sh # Paper runs
│
├── main_multi_target.py # 2. Multi-target entry point
├── multi_target_poisoned_dataset.py # Per-target parameter assignment
├── multi_target_utils.py # Per-target ASR tracking, saving
├── multi_target.sh # Paper runs
│
├── main_mtmt.py # 3. Multi-trigger multi-target entry point
├── mtmt_poisoned_dataset.py # Per-target trigger-type config
├── mtmt_utils.py # Per-target ASR tracking, saving
└── mtmt.sh # Paper runs
python -m venv venv
source venv/bin/activate
pip install torch torchvision # CUDA build matching your driver
pip install spikingjelly
pip install numpy scipy matplotlib seaborn tqdm
Entorno de referencia utilizado para los resultados reportados:
Descargue los conjuntos de datos neuromórficos sin procesar y coloque cada uno en su propio subdirectorio de
data/, nombrado exactamente como el valor de --dataset:
data/
├── mnist/ # N-MNIST
├── cifar10/ # CIFAR10-DVS
├── caltech/ # N-Caltech101
└── gesture/ # DVS128-Gesture
data/ debe ser un directorio literal en su directorio de trabajomain_single.py)Un disparador, una clase objetivo.
python main_single.py --dataset cifar10 --type latency --delay_frames 1 \
--T 10 --epochs 100 --epsilon 0.1 --data_dir 'data/'
Argumentos principales
Argumentos específicos del disparador
Establecer --epsilon 0.0 entrena un modelo de referencia limpio.
main_multi_target.py)Un tipo de disparador, N clases objetivo separadas por el valor del parámetro del disparador.
# Latency: delay 1 -> class 0, delay 3 -> class 1, delay 5 -> class 2
python main_multi_target.py --dataset mnist --type latency --n_targets 3 \
--trigger_labels 0 1 2 --delay_params 1 3 5 \
--epsilon 0.2 --T 10 --epochs 10 --data_dir 'data/'
Parámetros por objetivo. Proporciónelos explícitamente, o deje que se asignen automáticamente mediante
np.linspace sobre un rango. Las listas explícitas deben tener longitud --n_targets y anulan
los argumentos de rango.
Los parámetros enteros asignados automáticamente (latency, jitter_fixed) se deduplican
incrementando las colisiones, de modo que dos objetivos no comparten un valor.
Para static, los objetivos se separan por qué fotogramas portan el parche — el eje temporal
los distingue en lugar de la apariencia del parche.
La ASR por objetivo se imprime en cada época, junto con la precisión limpia.
main_mtmt.py)Un tipo de disparador diferente por objetivo.
python main_mtmt.py --dataset mnist --T 10 --n_targets 5 \
--target_types latency latency rate rate jitter_fixed \
--trigger_labels 0 1 2 3 4 \
--latency_delays 1 2 --rate_scales 0.5 2.0 --jitter_fixed_shifts 3 \
--epsilon 0.3 --epochs 100 --data_dir 'data/'
Listas de parámetros por tipo. Cada lista tiene una entrada por objetivo de ese tipo — con
--target_types latency latency rate rate jitter_fixed se pasan dos retardos, dos tasas
y un desplazamiento:
Omitir una lista asigna automáticamente desde el rango correspondiente *_min / *_max.
Preajustes integrados (utilizados cuando no se proporciona --target_types):
--n_targets 3 — static (fotogramas 0..T/3), latency (--delay), rate (--scale_factor)--n_targets 5 — dos static (diferentes grupos de fotogramas y posiciones), dos latency
(--delay, --delay_2), uno rateCualquier otro valor de --n_targets requiere --target_types.
Cada ejecución escribe una fila en un CSV compartido más un directorio de experimento autocontenido.
Los parámetros del disparador se codifican en el nombre del directorio (df1 = retardo 1, sf0.1 = tasa
0.1, ns3 = 3 intercambios), de modo que las ejecuciones que difieren solo en un parámetro del disparador no se sobrescriben
entre sí.
Partes de esta base de código están adaptadas del repositorio Sneaky Spikes de Gorka Abad et al., que acompaña al artículo "Sneaky Spikes: Uncovering Stealthy Backdoor Attacks in Spiking Neural Networks with Neuromorphic Data" (NDSS 2024). Agradecemos a los autores por hacer su código públicamente disponible.
Si este trabajo le resulta útil en su investigación, considere citarlo:
@article{miah2026tbackdoor,
title = {T-Backdoor: Exploiting Temporal Redundancy in Neuromorphic Data for Spike-preserving Backdoor Attacks on SNNs},
author = {Miah, Abdullah Arafat and Vu, Kevin and Bi, Yu},
journal = {arXiv},
year = {2026}
}
Para preguntas o problemas relacionados con el código, abra un issue en GitHub o contacte a:
| Paquete | Versión |
|---|
| Python | 3.11.10 |
| torch | 2.11.0+cu128 |
| torchvision | 0.26.0+cu128 |
| numpy | 2.2.6 |
| scipy | 1.16.0 |
| matplotlib | 3.8.4 |
| seaborn | 0.13.2 |
| spikingjelly | última desde el código fuente |
| Argumento | Predeterminado | Descripción |
|---|
--dataset | gesture | mnist, cifar10, caltech, gesture |
--type | static | static, moving, smart, latency, rate, jitter, jitter_fixed |
--epsilon | 0.1 | Fracción del conjunto de entrenamiento a envenenar |
--trigger_label | 0 | Clase objetivo |
--T | 10 | Pasos de tiempo de simulación |
--epochs | 10 | Épocas de entrenamiento |
--batch_size | 16 | Tamaño del lote |
--lr | 0.001 | Tasa de aprendizaje |
--loss | mse | mse o cross |
--optim | adam | adam o sgd |
--amp | desactivado | Habilitar precisión mixta automática |
--seed | 42 | Semilla aleatoria |
--data_dir | data/ | Raíz del conjunto de datos |
--save_path | experiments_single | Raíz de salida |
--model_path | None | Comenzar desde un checkpoint preentrenado |
| Argumento | Predeterminado | Se aplica a |
|---|
--delay_frames | 2 | latency — fotogramas de retardo |
--scale_factor | 0.5 | rate — <1 más lento, >1 más rápido |
--n_shift | 3 | jitter_fixed — número de pares de fotogramas intercambiados |
--trigger_size | 0.1 | static/moving/smart — tamaño del parche como fracción del ancho |
--pos | top-left | static — top-left, top-right, bottom-left, bottom-right, middle, random |
--polarity | 3 | static/moving/smart — 0=negro, 1=azul oscuro, 2=verde, 3=azul claro |
--n_masks | 2 | smart — número de regiones candidatas |
--least | desactivado | smart — apuntar a la región menos activa en lugar de la más activa |
--most_polarity | desactivado | smart — usar la polaridad más activa en la región |
| Argumento | Predeterminado | Descripción |
|---|
--type | rate | static, latency, rate, jitter, jitter_fixed |
--n_targets | 3 | Número de clases objetivo |
--trigger_labels | [0..n-1] | Etiquetas objetivo explícitas; la longitud debe ser igual a --n_targets |
--epsilon | 0.1 | Presupuesto total, dividido equitativamente entre los objetivos |
| Disparador | Explícito | Rango automático | Predeterminado automático |
|---|
latency | --delay_params 1 3 5 | --delay_min, --delay_max | 1 … T//2 |
rate | --rate_params 0.3 0.6 0.9 | --rate_min, --rate_max | 0.1 … 6.0 |
jitter | --jitter_params 0.05 0.15 0.25 | --jitter_std_min, --jitter_std_max | 0.05 … 0.3 |
jitter_fixed | --nshift_params 1 3 5 | --n_shift_min, --n_shift_max | 1 … max(n_shift_min+1, T//4) |
static | — | — | T dividido en n_targets grupos de fotogramas |
| Argumento | Predeterminado | Descripción |
|---|
--n_targets | 3 | Número de objetivos; 3 y 5 tienen preajustes integrados |
--target_types | None | Tipo de disparador por objetivo — static, latency, rate, jitter, jitter_fixed. La longitud debe ser igual a --n_targets. Anula los preajustes |
--trigger_labels | [0..n-1] | Etiquetas objetivo |
--epsilon | 0.2 | Presupuesto total, dividido equitativamente entre los objetivos |
| Argumento | Se aplica a |
|---|
--latency_delays 1 2 | cada objetivo latency |
--rate_scales 0.5 2.0 | cada objetivo rate |
--jitter_fixed_shifts 3 | cada objetivo jitter_fixed |
--jitter_stds 0.1 0.3 | cada objetivo jitter |
--static_positions top-left bottom-right | cada objetivo static |
--static_polarities 3 1 | cada objetivo static |
| Configuración | CSV de resumen | Directorio de experimento |
|---|
| Único | <save_path>/results.csv | <dataset>_<type>_<eps>_<size>_<param>_<seed>/ |
| Objetivos múltiples | <save_path>/multi_target_results.csv | multi_<type>_<dataset>_<n>targets_<labels>_eps<eps>_<params>_seed<seed>/ |
| MTMT | <save_path>/mtmt_results.csv | mtmt_<dataset>_<n>t_<params>_eps<eps>_seed<seed>/ |