Skip to content

Latest commit

 

History

113 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

INR-Robustness [ICML 2026]

A research framework for studying adversarial robustness of Implicit Neural Representation (INR)-based classifiers. This project systematically evaluates how classifiers operating on INR weight-space features respond to adversarial attacks across multiple threat models — image space, INR weight space, and embedding space.

By: Jayoung Kim, Kookjin Lee, Noseong Park, and Sanghyun Hong


Table of Contents


Overview

INR-based classifiers encode images as neural network weights (SIRENs or Fourier Feature Networks) and classify them using architectures designed for weight-space or embedding-space processing. This project attacks these classifiers from three threat models:

Threat Model Description
Image space Adversarial perturbations applied to raw images before INR fitting
INR weight space Perturbations applied directly to fitted SIREN/FFN weights
Embedding space Perturbations applied to latent embeddings extracted from INRs

Supported victim models: NFT, NFN, DWS, ScaleGMN, MWT, INR2Vec

Supported datasets: MNIST, Fashion-MNIST, CIFAR-10

INR types: SIREN, FFN (Fourier Feature Networks)


Project Structure

INR-Robustness/
├── environment.yml                    # Conda environment
├── fourier-feature-networks/          # FFN generation scripts
│   ├── make_ffn.py
│   └── run_make_ffn.sh
└── src/
    ├── attacks/                       # Attack implementations
    │   ├── run_attacks.py             # Main Attacks orchestrator class
    │   ├── attack_methods.py          # Attack function implementations
    │   ├── model_loading.py           # Victim model loading utilities
    │   ├── utils.py                   # BatchedINRBuilder, WeightSpaceFeatures
    │   ├── evaluation.py              # Evaluation metrics
    │   ├── training.py                # Training utilities
    │   ├── data_loading.py            # Dataset loaders
    │   ├── hypernet/                  # Hypernetwork-based attack
    │   ├── surrogate/                 # Surrogate model training
    │   │   ├── train_surrogate.py     # SurrogateTrainer (MLP, FD loss, noise augmentation)
    │   │   └── utils.py               # SurrogateAttacker wrapper
    │   ├── transfer/                  # Transfer attack training
    │   └── torchattacks/              # PGD variants (Linf, L2, L1, weight-space, embedding)
    ├── basemodels/                    # Victim model architectures
    │   ├── nft.py                     # Neural Field Transformer
    │   ├── nfn.py                     # Neural Functional Networks
    │   ├── dws.py                     # Deep Weight Space
    │   ├── scalegmn.py                # ScaleGMN (graph neural network)
    │   ├── mwt.py                     # Meta-Weight Transformer
    │   ├── inr2array.py               # INR2Array encoder/decoder
    │   ├── inr2vec/                   # INR2Vec model
    │   └── configs/                   # Per-model YAML configs
    ├── defences/                      # Defense mechanisms
    ├── experiments/
    │   ├── suite_runner.py            # Experiment suite orchestrator
    │   ├── run.sh                     # Shell runner script
    │   └── configs/
    │       └── suites/
    │           ├── exp1/              # Base experiments (all models × datasets × attacks)
    │           ├── exp2/              # Ablation studies (INR config, embedding dim, #INRs)
    │           ├── exp3/              # Comprehensive cross-attack experiments
    │           ├── exp4/              # Attack space analysis
    │           ├── exp5/              # Adversarial training experiments
    │           └── transferability/   # Cross-model transferability
    ├── inr/                           # INR generation scripts
    └── utils/
        ├── path_config.py             # Centralized path management
        ├── inr_config.py              # INR configuration dataclass
        ├── config_utils.py            # YAML config loading (DictConfig)
        ├── results_collector.py       # CSV results aggregation
        └── wandb_manager.py           # Weights & Biases integration

Installation

conda env create -f environment.yml
conda activate inr

Key dependencies: Python 3.11, PyTorch (CUDA 12.4), torch_geometric, perceiver_pytorch, random-fourier-features-pytorch, wandb, einops, scikit-learn.


Data Preparation

1. Generate INRs (from scratch)

Run the INR generation pipeline before any experiments. Each dataset requires three initialization strategies, which are used by different victim models.

Init mode Used by Description
shared_init INR2Vec Single shared initialization; all images fitted from the same starting point
init_pool NFN, NFT Pool of N random inits; each image picks one at random
random_init DWS, ScaleGMN Independent random init per image; test samples reuse a training init

Submit all generation jobs (3 datasets × 3 init modes = 9 Slurm jobs):

# All datasets (mnist, fashion, cifar)
bash slurm/make_inrs.sh

# Single dataset only
bash slurm/make_inrs.sh mnist

Monitor progress:

squeue -u $USER

Generated files are saved to:

{NFS_ROOT}/assets/sirens/depth1_width32_scale30/{dataset}/
  inits/shared_init/shared_init.pth          # 1 file
  inits/init_pool/pool_id{0..N}.pth          # N files (10 for mnist/fashion, 20 for cifar)
  {init_mode}_{label}s/net{global_idx}.pth   # 70k files (mnist/fashion) or 60k (cifar) per mode

Verify generation completeness:

python src/inr/verify_inrs.py               # all datasets × all modes
python src/inr/verify_inrs.py --dataset mnist --init_mode shared_init

Alternative: Download Pre-fitted INRs

Pre-fitted SIREN weight datasets are available from Google Drive. Place them under the project root:

{base_path}/assets/sirens/depth{D}_width{W}_scale{S}/{dataset}/
{base_path}/assets/ffns/{dataset}/

SIREN configurations: depth ∈ {0,1,3}, width ∈ {16,32,64}, scale ∈ {10,30,60}

2. Pre-trained Victim Model Checkpoints

Place checkpoints under:

{base_path}/assets/basemodels/{model}/{dataset}/{inr_config}/

For adversarially-trained variants:

{base_path}/assets/basemodels/{model}/{dataset}/{inr_config}/at_{at_type}/

3. Configure the Base Path

The project root (base_path) is resolved in order of priority:

  1. CLI --config_base_path (highest priority): the src/ directory path. The project root is automatically derived as os.path.dirname(config_base_path).
  2. YAML defaults.base_path: used as fallback if --config_base_path is not set.

Running Experiments

Suite Runner (Recommended)

The suite runner is the primary way to run experiments. It reads a YAML config, expands it into a list of individual experiments, and runs them sequentially.

# Run by experiment number and model name
# Loads: src/experiments/configs/suites/exp{N}/exp{N}_{name}.yaml
python src/experiments/suite_runner.py --exp 1 --name nft

# Run a specific named config (no --exp, loads from configs/ directly)
python src/experiments/suite_runner.py --name suites/exp2/num_inrs/dws_mnist

# Enable WandB logging
python src/experiments/suite_runner.py --exp 1 --name dws --wandb

# Override project root (src/ path → parent is the project root)
python src/experiments/suite_runner.py --exp 1 --name nft --config_base_path /my/project/src

# Dry-run: print experiment plan without executing
python src/experiments/suite_runner.py --exp 1 --name nft --dry-run

Path resolution:

config_base_path (default: auto-detected src/ dir)
  └── experiments/configs/suites/exp{N}/exp{N}_{name}.yaml  ← suite config
  └── exp_results/exp{N}/                                    ← results output

base_path = os.path.dirname(config_base_path)               ← project root
  └── assets/sirens/...                                      ← INR data
  └── assets/basemodels/...                                  ← model checkpoints

CLI Arguments:

Argument Default Description
--exp Experiment number (1–5). Loads configs/suites/exp{N}/exp{N}_{name}.yaml
--name i2i-fd Suite config name or relative path to config
--config_base_path auto-detected src/ path Path to src/. Project root = parent dir
--wandb disabled Enable Weights & Biases experiment tracking
--dry-run disabled Print experiment plan without executing

Shell Script

# bash src/experiments/run.sh <device_id> <exp_num> <model_name>
bash src/experiments/run.sh 0 1 nft
bash src/experiments/run.sh 1 2 dws

Logs are written to logs/exp_{N}_{name}.log.

Programmatic API

from src.attacks.run_attacks import Attacks

mgr = Attacks(
    attack_space="image",       # "image", "inr", or "embedding"
    attack_type="gaussian",
    dataset_name="cifar",       # "mnist", "fashion", "cifar"
    victim_model="nft",         # "nft", "nfn", "dws", "scalegmn", "mwt", "inr2vec"
    base_path="/path/to/project/root",
)
result = mgr.run(eps=0.03, steps=100)
# result: {"clean_acc": ..., "adv_acc": ..., "total": ...}

Configuration

YAML Suite Config

suite_name: exp1_nft

defaults:
  base_path: /path/to/project/root   # Overridden by --config_base_path CLI arg

inr_config:
  depth: 1
  width: 32
  scale: 30
  inr_type: siren   # "siren" or "ffn"

models: [nft]
datasets: [mnist, fashion, cifar]

attacks:
  # Gaussian noise baseline
  - attack_space: image
    attack_type: gaussian
    params: {}

  # Transfer attack via ResNet18 surrogate
  - attack_space: image
    attack_type: transfer
    params:
      eps: 0.3
      steps: 100
      norm: Linf

  # Surrogate-based image attack (NI-GBMS adaptation)
  - attack_space: image
    attack_type: i2i-fd
    params:
      eps: 0.3          # L∞ budget in [0,1] scale (internally scaled ×2 for [-1,1] images)
      steps: 100        # PGD steps (default: 100)
      n_restarts: 5     # Multi-restart PGD, keep per-sample worst case (default: 5)
      aug_eps: 0.6      # Noise augmentation for surrogate OOD robustness (default: 0.0)
      norm: Linf

  # Direct PGD in INR weight space with image constraint
  - attack_space: inr
    attack_type: inr
    params:
      eps: 0.01
      steps: 100
      proj_mode: icop   # "weight_linf", "image_linf", or "icop"

results:
  csv_name: exp1_nft_results.csv

Experiment Generation Modes

The suite runner selects a generation strategy based on keys present in the YAML:

YAML Key Mode Description
inr_ablations INR Ablation Sweep over multiple INR configs (depth/width/scale)
attack_ablations Attack Ablation Parameter sweep for a single attack type
defenses Defense Cross-product with defense mechanisms
embedding_dims Embedding Dim Latent dimension ablation (NFT only)
inr_type: ffn FFN Experiments using Fourier Feature Networks
(none of the above) Standard Cartesian product: models × datasets × attacks

Victim Models

Model Space Description
NFT Embedding Neural Field Transformer. AutoEncoder maps INR → latent vector; Transformer classifies.
NFN Weight Neural Functional Networks. Permutation-equivariant processing of weight-space features (weights + biases).
DWS Weight Deep Weight Space. Set-abstraction layers for permutation-invariant weight classification.
ScaleGMN Weight (graph) Graph Neural Network over the computational graph of the INR.
MWT Meta-learning Meta-Weight Transformer. Meta-learner that adapts to new INRs in a few-shot manner.
INR2Vec Embedding Learns a vector embedding of INR weights; classifies with an MLP head.

Attack Types

Image Space (attack_space: image)

attack_type Description Key Params
gaussian Gaussian noise added to raw images eps, norm
transfer PGD attack optimized against a ResNet18 surrogate eps, steps, norm
e2e End-to-end PGD through the MWT meta-learner eps, steps

Surrogate-based Image Attack (i2i-fd, i2e-fd)

These attacks train an MLP surrogate S: image → INR weights (or embedding) and use it as a differentiable proxy for PGD. The surrogate is trained with:

  1. Reconstruction loss||S(x) - θ*(x)||²
  2. Derivative matching (FD)||J_S(x)·J_render·Δθ - Δθ||², adapted from NI-GBMS (arXiv:2405.02952) to train J_S ≈ dθ*/dx
  3. Classification lossCE(victim(S(x)), y)
Parameter Default Description
eps dataset default L∞ perturbation budget in [0,1] scale (scaled ×2 internally for [-1,1] images)
steps 100 PGD steps
n_restarts 5 Multi-restart PGD — runs n_restarts times from random start, keeps per-sample worst case
norm Linf Perturbation norm (Linf, L2, L1)
aug_eps 0.0 Noise augmentation eps for surrogate training. Trains J_S(x+noise) ≈ J_fit to reduce OOD error at adversarial inputs. Set to 2*eps (i.e., 0.6 for MNIST) for best effect.
lam_inr 1.0 Weight for reconstruction loss
lam_der 1.0 Weight for derivative matching loss
lam_cls 1.0 Weight for classification loss
epochs 100 Surrogate training epochs

INR Weight Space (attack_space: inr)

attack_type Description Key Params
i2i-naive Gaussian or L∞-bounded perturbation of SIREN weights eps
i2i-fd Feature deception: optimize INR weights to fool classifier while preserving image reconstruction eps, steps, aug_eps
i2i-hypernet Hypernetwork trained to generate adversarial SIREN weights eps, steps, latent_dim
inr Direct PGD on WeightSpaceFeatures (PGDWSFeat) eps, steps, proj_mode

proj_mode options for inr attack:

Mode Description
weight_linf Project perturbation to L∞ ball in weight space
image_linf Project to L∞ ball in rendered image space (iterative shrink)
icop ICOP: classification gradient orthogonalized w.r.t. image-space constraint gradient

Embedding Space (attack_space: embedding)

attack_type Description Key Params
i2e-naive Optimize embedding to fool classifier (std-normalized ε) eps, steps
i2e-fd Feature deception in embedding space with reconstruction constraint eps, steps, aug_eps
embedding Direct PGD in std-normalized embedding space (PGDEmbedding) eps, steps, norm

Norm options: Linf, L2, L1

Default epsilon values by dataset: MNIST → 0.3, Fashion-MNIST → 0.1, CIFAR-10 → 0.03

Note: Epsilon values are in [0,1] pixel scale. Internally, images are normalized to [-1,1], so the actual PGD budget is eps × 2.

Model × Attack Space compatibility:

Model Image INR weight Embedding
NFT
NFN
DWS
ScaleGMN
MWT gaussian, transfer only
INR2Vec

Defense Mechanisms

Defenses are specified via the defenses key in the suite YAML or via mgr.set_defense_config().

Defense Type Description
gaussian_noise Preprocessing Adds Gaussian noise to inputs before classification
diffusion Preprocessing Diffusion model denoiser applied to INR weights
embedding_at Adversarial Training Robust training with adversarial perturbations in embedding space
inr_at Adversarial Training Robust training with adversarial perturbations in INR weight space

INR Configuration

from src.utils.inr_config import INRConfig

# SIREN
cfg = INRConfig(depth=1, width=32, scale=30, inr_type="siren", augment_count=1)

# FFN
cfg = INRConfig(inr_type="ffn")
Parameter Values Description
depth 0, 1, 3 Number of hidden layers
width 16, 32, 64 Hidden features per layer
scale 10, 30, 60 first_omega_0 frequency scaling factor
augment_count 1, 5, 10, 20 Number of augmented INRs fitted per image
training_steps int SIREN fitting iterations (default: 5000)
inr_type "siren", "ffn" INR representation type

Asset paths:

{base_path}/assets/sirens/depth{D}_width{W}_scale{S}/{dataset}/   # SIREN
{base_path}/assets/ffns/{dataset}/                                  # FFN

Results

Results are saved as CSV files under:

{config_base_path}/exp_results/{exp_name}/{suite_name}_results.csv

Each row contains the full experiment configuration and the following metrics:

Column Description
clean_acc Accuracy on unperturbed inputs
adv_acc Accuracy on adversarial inputs
total Total number of evaluated samples
training_time_sec Wall-clock time for the experiment
status "success" or error message

With --wandb, runs are grouped by suite name and tagged with model, dataset, and attack type for easy filtering in the WandB dashboard.


Cite Our Work

Please cite our work if you find this source code helpful.

@inproceedings{kim2026adversarial,
    title={Adversarial Robustness of Implicit Neural Representation-Based Classifiers},
    author={Jayoung Kim and Kookjin Lee and Noseong Park and Sanghyun Hong},
    booktitle={Forty-third International Conference on Machine Learning},
    year={2026},
    url={https://openreview.net/forum?id=TEcKvsdzA3}
}

 


Please contact Jayoung Kim (jayoung.kim@kaist.ac.kr) and Sanghyun Hong (sanghyun.hong@oregonstate.edu) for any questions and recommendations.

About

This is the repository for assessing the robustness of INR-based classifiers.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages