Using AutoAttackWrapper for Adversarial Robustness Evaluation in VERONA
The AutoAttackWrapper class in VERONA integrates the AutoAttack library into the framework's verification pipeline by implementing the abstract Attack interface, enabling standardized adversarial robustness evaluation with configurable norms and attack versions.
VERONA provides a ready-to-use wrapper that bridges the popular AutoAttack library with its modular verification architecture. The AutoAttackWrapper class, located in ada_verona/verification_module/attacks/auto_attack_wrapper.py, allows researchers to evaluate model robustness using state-of-the-art adversarial attacks without modifying the underlying framework code. This integration supports both standalone attack execution and seamless pipeline integration through a unified API.
Architecture and Implementation
The Attack Interface
All adversarial attacks in VERONA implement the abstract Attack class defined in ada_verona/verification_module/attacks/attack.py. This interface standardizes the execution API across different attack methods, requiring concrete implementations to define an execute(model, data, target, epsilon) method that returns perturbed data as a torch.Tensor.
AutoAttackWrapper Execution Flow
The AutoAttackWrapper class extends this interface to wrap the external AutoAttack library. During initialization, it stores the execution device, norm type (Linf or L2), attack version (standard by default), and verbosity settings. When execute() is called, the wrapper:
- Instantiates an
AutoAttackobject with the supplied model and parameters - Adds a batch dimension to the input data using
data.unsqueeze(0)to satisfy AutoAttack's NCHW format expectations - Invokes
run_standard_evaluationto generate adversarial examples - Normalizes the output by extracting the perturbed tensor if AutoAttack returns a tuple
(perturbed, predictions)
This normalization ensures backward compatibility while handling variations in the AutoAttack library return types.
How to Use AutoAttackWrapper
Basic Standalone Usage
You can instantiate and run the wrapper independently for single-sample adversarial robustness evaluation:
import torch
from ada_verona.verification_module.attacks.auto_attack_wrapper import AutoAttackWrapper
# Assume model is a torch.nn.Module and data is C×H×W format
model = my_model.eval()
data = test_data # Shape: (C, H, W)
target = test_target # Shape: (1,)
# Initialize the wrapper
attack = AutoAttackWrapper(
device="cpu",
norm="Linf",
version="standard",
verbose=False
)
# Execute attack with epsilon perturbation budget
epsilon = 0.05
perturbed = attack.execute(model, data, target, epsilon)
print("Perturbed shape:", perturbed.shape) # torch.Size([C, H, W])
Integration with Verification Pipeline
For batch evaluation across datasets, plug the wrapper into VERONA's AttackEstimationModule:
import torch
from ada_verona.verification_module.attacks.auto_attack_wrapper import AutoAttackWrapper
from ada_verona.verification_module.attack_estimation_module import AttackEstimationModule
from ada_verona.database.verification_context import VerificationContext
# Setup model and dataset
model = torch.load("my_model.pt").to("cuda")
dataset = ... # Dataset yielding (x, y) tuples
# Create verification context for specific sample
vc = VerificationContext(
model=model,
dataset=dataset,
sample_index=0,
)
# Configure estimator with AutoAttackWrapper
estimator = AttackEstimationModule(
attack=AutoAttackWrapper(
device="cuda",
norm="Linf",
version="standard",
verbose=False
)
)
# Estimate robustness
epsilon = 0.1
result = estimator.estimate(vc, epsilon)
print("Robustness result:", result)
The AttackEstimationModule internally invokes attack.execute() for each data point, making the wrapper interchangeable with other attack implementations. See the complete workflow in examples/scripts/create_robustness_dist_autoattack.py.
Testing and Validation
The implementation includes comprehensive unit tests in tests/test_verification_module/attacks/test_auto_attack_wrapper.py. These tests verify correct parameter initialization, device placement, and execution flow using monkey-patched AutoAttack instances to ensure reproducibility without external dependencies.
Summary
- AutoAttackWrapper provides a standardized interface between the AutoAttack library and VERONA's verification framework through the abstract
Attackclass inada_verona/verification_module/attacks/attack.py. - The wrapper handles data format conversion (adding batch dimensions via
unsqueeze(0)) and normalizes return values to ensure consistent tensor outputs. - Configuration options include
device,norm(Linf/L2),version, andverboseflags for flexible deployment across different hardware and attack specifications. - Integration with
AttackEstimationModuleenables large-scale adversarial robustness evaluation across entire datasets without pipeline modifications. - Reference implementations are available in
examples/scripts/create_robustness_dist_autoattack.pywith test coverage intests/test_verification_module/attacks/test_auto_attack_wrapper.py.
Frequently Asked Questions
What is the AutoAttackWrapper in VERONA?
The AutoAttackWrapper is a concrete implementation of VERONA's abstract Attack interface that integrates the AutoAttack library for adversarial robustness evaluation. According to the source code in ada_verona/verification_module/attacks/auto_attack_wrapper.py, it translates between VERONA's standardized verification pipeline and AutoAttack's specific API requirements, allowing researchers to use state-of-the-art adversarial attacks without modifying framework internals.
How does AutoAttackWrapper handle data formats?
The wrapper automatically adjusts input dimensions to match AutoAttack's expectations. In the execute() method implemented in auto_attack_wrapper.py, it applies data.unsqueeze(0) to add a batch dimension, converting single samples from (C, H, W) to (1, C, H, W) format. It also handles variable return types from AutoAttack, extracting the perturbed tensor when the library returns a tuple (perturbed, predictions) instead of a single tensor.
Can I use different attack norms with AutoAttackWrapper?
Yes, the wrapper supports configurable norm types through the norm parameter in its constructor. You can specify "Linf" for L-infinity norm attacks or "L2" for L2 norm attacks. The default is "Linf", which is the standard setting for most adversarial robustness benchmarks. This parameter is passed directly to the underlying AutoAttack instance during execution.
Where can I find examples of AutoAttackWrapper usage?
Practical examples are available in the repository at examples/scripts/create_robustness_dist_autoattack.py, which demonstrates end-to-end robustness distribution generation using the AttackEstimationModule. Additionally, unit tests in tests/test_verification_module/attacks/test_auto_attack_wrapper.py illustrate proper initialization and execution patterns, including mocking strategies for testing without requiring the full AutoAttack dependency.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →