
스파이킹 신경망에 대한 rate, latency, jitter 트리거를 사용한 시간적 트리거 백도어 공격인 T-Backdoor를 구현한 연구 코드로, 공간적 교란 없이 동작한다.
백도어 공격은 심층 신경망(DNN)에 대한 심각한 보안 위협이며, 스파이킹 신경망(SNN)에 대해서는 대체로 충분히 연구되지 않은 상태로 남아 있습니다. 기존 공격은 주로 오염된 샘플의 스파이크 분포가 깨끗한 샘플에 비해 편차를 유발하는 시공간 트리거를 도입합니다. 이러한 한계를 해결하기 위해, 본 연구는 \textbf{T-Backdoor}라 명명된 SNN에 대한 새로운 백도어 공격을 제안하며, 이는 \textit{Rate}, \textit{Latency}, \textit{Jitter}와 같은 순수 시간적 트리거를 사용하여 어떠한 공간적 교란도 도입하지 않음으로써 스파이크 분포의 변화를 훨씬 더 탐지하기 어렵게 만듭니다. 세 가지 벤치마크 뉴로모픽 데이터셋(N-MNIST, CIFAR10-DVS, N-Caltech101)에 대한 광범위한 실험과 일곱 가지 기준 백도어 방어 방법에 대한 평가를 통해, T-Backdoor가 단일 타겟 및 다중 타겟 설정 모두에서 거의 완벽한 100% 공격 성공률(ASR)을 달성하면서도 깨끗한 정확도의 저하가 미미하며, 기존 백도어 탐지 및 완화 기법에 대해 견고하게 유지됨을 입증합니다.
├── 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
보고된 결과에 사용된 참조 환경:
원시 뉴로모픽 데이터셋을 다운로드하여 data/의 각 하위 디렉터리에 배치하며, 이름은 --dataset 값과 정확히 일치해야 합니다:
data/
├── mnist/ # N-MNIST
├── cifar10/ # CIFAR10-DVS
├── caltech/ # N-Caltech101
└── gesture/ # DVS128-Gesture
data/는 작업 디렉터리에 실제 디렉터리로 존재해야 합니다main_single.py)하나의 트리거, 하나의 타겟 클래스.
python main_single.py --dataset cifar10 --type latency --delay_frames 1 \
--T 10 --epochs 100 --epsilon 0.1 --data_dir 'data/'
핵심 인자
트리거별 인자
--epsilon 0.0으로 설정하면 깨끗한 기준 모델을 훈련합니다.
main_multi_target.py)하나의 트리거 유형, 트리거의 매개변수 값으로 구분되는 N개의 타겟 클래스.
# 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/'
타겟별 매개변수. 명시적으로 지정하거나, 범위에 대해 np.linspace로 자동 할당되도록 할 수 있습니다. 명시적 리스트는 길이가 --n_targets와 같아야 하며 범위 인자를 재정의합니다.
자동 할당된 정수 매개변수(latency, jitter_fixed)는 충돌 시 증가시켜 중복을 제거하므로, 두 타겟이 같은 값을 공유하지 않습니다.
static의 경우, 타겟은 어떤 프레임이 패치를 운반하는지로 구분됩니다 — 패치 모양이 아니라 시간 축이 이들을 구분합니다.
타겟별 ASR은 깨끗한 정확도와 함께 매 에포크마다 출력됩니다.
main_mtmt.py)타겟마다 다른 트리거 유형을 사용합니다.
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/'
유형별 매개변수 리스트. 각 리스트는 해당 유형의 타겟마다 하나의 항목을 가집니다 — --target_types latency latency rate rate jitter_fixed의 경우 두 개의 지연, 두 개의 비율, 하나의 시프트를 전달합니다:
리스트를 생략하면 일치하는 *_min / *_max 범위에서 자동 할당됩니다.
내장 프리셋 (--target_types가 주어지지 않았을 때 사용됨):
--n_targets 3 — static (프레임 0..T/3), latency (--delay), rate (--scale_factor)--n_targets 5 — 두 개의 static (다른 프레임 그룹과 위치), 두 개의 latency
(--delay, --delay_2), 하나의 rate다른 --n_targets 값은 --target_types를 반드시 요구합니다.
모든 실행은 공유 CSV에 행을 기록하고 자체 포함된 실험 디렉터리를 생성합니다.
트리거 매개변수는 디렉터리 이름에 인코딩되므로(df1 = delay 1, sf0.1 = rate
0.1, ns3 = 3 swaps), 트리거 매개변수만 다른 실행이 서로를 덮어쓰지 않습니다.
이 코드베이스의 일부는 Gorka Abad 등이 "Sneaky Spikes: Uncovering Stealthy Backdoor Attacks in Spiking Neural Networks with Neuromorphic Data" (NDSS 2024) 논문과 함께 제공한 Sneaky Spikes 저장소에서 각색되었습니다. 코드를 공개해 주신 저자들에게 감사드립니다.
이 연구가 유용하다고 생각되시면 다음을 인용해 주시기 바랍니다:
@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}
}
코드에 관한 질문이나 문제가 있으시면 GitHub 이슈를 열거나 다음으로 연락해 주십시오:
| 패키지 | 버전 |
|---|
| 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 | latest from source |
| 인자 | 기본값 | 설명 |
|---|
--dataset | gesture | mnist, cifar10, caltech, gesture |
--type | static | static, moving, smart, latency, rate, jitter, jitter_fixed |
--epsilon | 0.1 | 오염시킬 훈련 세트의 비율 |
--trigger_label | 0 | 타겟 클래스 |
--T | 10 | 시뮬레이션 시간 단계 |
--epochs | 10 | 훈련 에포크 |
--batch_size | 16 | 배치 크기 |
--lr | 0.001 | 학습률 |
--loss | mse | mse 또는 cross |
--optim | adam | adam 또는 sgd |
--amp | off | 자동 혼합 정밀도 활성화 |
--seed | 42 | 랜덤 시드 |
--data_dir | data/ | 데이터셋 루트 |
--save_path | experiments_single | 출력 루트 |
--model_path | None | 사전 훈련된 체크포인트에서 시작 |
| 인자 | 기본값 | 적용 대상 |
|---|
--delay_frames | 2 | latency — 지연 프레임 수 |
--scale_factor | 0.5 | rate — <1 느리게, >1 빠르게 |
--n_shift | 3 | jitter_fixed — 교환할 프레임 쌍 수 |
--trigger_size | 0.1 | static/moving/smart — 너비 대비 패치 크기 비율 |
--pos | top-left | static — top-left, top-right, bottom-left, bottom-right, middle, random |
--polarity | 3 | static/moving/smart — 0=검정, 1=진한 파랑, 2=초록, 3=연한 파랑 |
--n_masks | 2 | smart — 후보 영역 수 |
--least | off | smart — 가장 활성화된 영역 대신 가장 덜 활성화된 영역을 타겟으로 |
--most_polarity | off | smart — 영역에서 가장 활성화된 극성 사용 |
| 인자 | 기본값 | 설명 |
|---|
--type | rate | static, latency, rate, jitter, jitter_fixed |
--n_targets | 3 | 타겟 클래스 수 |
--trigger_labels | [0..n-1] | 명시적 타겟 레이블; 길이는 --n_targets와 같아야 함 |
--epsilon | 0.1 | 총 예산, 타겟에 균등 분할 |
| 트리거 | 명시적 | 자동 범위 | 자동 기본값 |
|---|
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를 n_targets개의 프레임 그룹으로 분할 |
| 인자 | 기본값 | 설명 |
|---|
--n_targets | 3 | 타겟 수; 3과 5는 내장 프리셋이 있음 |
--target_types | None | 타겟별 트리거 유형 — static, latency, rate, jitter, jitter_fixed. 길이는 --n_targets와 같아야 함. 프리셋을 재정의함 |
--trigger_labels | [0..n-1] | 타겟 레이블 |
--epsilon | 0.2 | 총 예산, 타겟에 균등 분할 |
| 인자 | 적용 대상 |
|---|
--latency_delays 1 2 | 각 latency 타겟 |
--rate_scales 0.5 2.0 | 각 rate 타겟 |
--jitter_fixed_shifts 3 | 각 jitter_fixed 타겟 |
--jitter_stds 0.1 0.3 | 각 jitter 타겟 |
--static_positions top-left bottom-right | 각 static 타겟 |
--static_polarities 3 1 | 각 static 타겟 |
| 설정 | 요약 CSV | 실험 디렉터리 |
|---|
| Single | <save_path>/results.csv | <dataset>_<type>_<eps>_<size>_<param>_<seed>/ |
| Multi-target | <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>/ |