Foolbox

Bibliothèque Python pour fabriquer des exemples adversariaux contre des réseaux de neurones via des attaques basées sur le gradient et sur la décision, agnostique du framework grâce à EagerPy. Python library for crafting adversarial examples against neural networks using gradient-based and decision-based attacks, framework-agnostic via EagerPy.

↗ https://github.com/bethgelab/foolbox

Overview

Foolbox is a lightweight adversarial-example library built on top of EagerPy, so the same attack code runs unmodified against PyTorch, TensorFlow, or JAX models. It’s popular for research-grade robustness evaluation because its attacks are implemented to closely match the original papers, and it ships both white-box gradient attacks (FGSM, PGD, C&W) and black-box decision-based attacks (Boundary Attack) for when you only have query access to a target.

Installation

Install Foolbox and pick your backend (torch/tensorflow/jax) separately

pip install foolbox

Wrapping a Model

import foolbox as fb
import torch

# Wrap a PyTorch model as a Foolbox model (bounds = valid input range)
model = torchvision.models.resnet18(pretrained=True).eval()
fmodel = fb.PyTorchModel(model, bounds=(0, 1))

Gradient-Based Attacks

# FGSM — single-step, fast but coarse perturbation
attack = fb.attacks.FGSM()
raw, clipped, success = attack(fmodel, images, labels, epsilons=0.03)

# PGD — iterative, stronger and more commonly used as a baseline
attack = fb.attacks.LinfPGD()
raw, clipped, success = attack(fmodel, images, labels, epsilons=[0.01, 0.03, 0.1])

# Carlini & Wagner L2 — minimizes perturbation size, slower but very effective
attack = fb.attacks.L2CarliniWagnerAttack()
adv = attack(fmodel, images, labels, epsilons=None)

Black-Box / Decision-Based Attack

# Boundary Attack — only needs the model's final decision, no gradients
attack = fb.attacks.BoundaryAttack()
adv = attack(fmodel, images, labels, epsilons=None, starting_points=None)

Tips

  • epsilons=None returns the minimal perturbation found rather than testing fixed budgets — useful for measuring a model’s true robustness radius.
  • fb.utils.accuracy(fmodel, images, labels) gives a quick clean-accuracy baseline before comparing against adversarial accuracy.
Help / Man page
foolbox.PyTorchModel(model, bounds, preprocessing=None)
foolbox.TensorFlowModel(model, bounds)
foolbox.JAXModel(model, bounds)

foolbox.attacks.FGSM()
foolbox.attacks.LinfPGD()
foolbox.attacks.L2PGD()
foolbox.attacks.L2CarliniWagnerAttack()
foolbox.attacks.DeepFoolAttack()
foolbox.attacks.BoundaryAttack()
foolbox.attacks.HopSkipJumpAttack()
foolbox.attacks.SpatialAttack()

attack(fmodel, inputs, labels, epsilons)  # -> raw, clipped, is_adversarial

foolbox.utils.accuracy(fmodel, images, labels)
foolbox.utils.samples(fmodel, dataset="imagenet", batchsize=16)

Vue d’ensemble

Foolbox est une bibliothèque légère d’exemples adversariaux construite sur EagerPy, si bien que le même code d’attaque tourne sans modification contre des modèles PyTorch, TensorFlow ou JAX. Elle est populaire pour l’évaluation de robustesse de niveau recherche car ses attaques sont implémentées pour correspondre étroitement aux papiers originaux, et elle embarque à la fois des attaques white-box basées sur le gradient (FGSM, PGD, C&W) et des attaques black-box basées sur la décision (Boundary Attack) pour les cas où l’on n’a qu’un accès par requêtes à une cible.

Installation

# Installer Foolbox et choisir son backend (torch/tensorflow/jax) séparément
pip install foolbox

Encapsuler un modèle

import foolbox as fb
import torch

# Encapsuler un modèle PyTorch en tant que modèle Foolbox (bounds = plage d'entrée valide)
model = torchvision.models.resnet18(pretrained=True).eval()
fmodel = fb.PyTorchModel(model, bounds=(0, 1))

Attaques basées sur le gradient

# FGSM : une seule étape, rapide mais perturbation grossière
attack = fb.attacks.FGSM()
raw, clipped, success = attack(fmodel, images, labels, epsilons=0.03)

# PGD : itérative, plus forte et plus couramment utilisée comme référence
attack = fb.attacks.LinfPGD()
raw, clipped, success = attack(fmodel, images, labels, epsilons=[0.01, 0.03, 0.1])

# Carlini & Wagner L2 : minimise la taille de la perturbation, plus lente mais très efficace
attack = fb.attacks.L2CarliniWagnerAttack()
adv = attack(fmodel, images, labels, epsilons=None)

Attaque black-box / basée sur la décision

# Boundary Attack : n'a besoin que de la décision finale du modèle, pas de gradients
attack = fb.attacks.BoundaryAttack()
adv = attack(fmodel, images, labels, epsilons=None, starting_points=None)

Conseils

  • epsilons=None retourne la perturbation minimale trouvée plutôt que de tester des budgets fixes : utile pour mesurer le véritable rayon de robustesse d’un modèle.
  • fb.utils.accuracy(fmodel, images, labels) donne rapidement une référence de précision propre avant de la comparer à la précision adversariale.
Aide / Page de manuel
foolbox.PyTorchModel(model, bounds, preprocessing=None)
foolbox.TensorFlowModel(model, bounds)
foolbox.JAXModel(model, bounds)

foolbox.attacks.FGSM()
foolbox.attacks.LinfPGD()
foolbox.attacks.L2PGD()
foolbox.attacks.L2CarliniWagnerAttack()
foolbox.attacks.DeepFoolAttack()
foolbox.attacks.BoundaryAttack()
foolbox.attacks.HopSkipJumpAttack()
foolbox.attacks.SpatialAttack()

attack(fmodel, inputs, labels, epsilons)  # -> raw, clipped, is_adversarial

foolbox.utils.accuracy(fmodel, images, labels)
foolbox.utils.samples(fmodel, dataset="imagenet", batchsize=16)