Configuring VNNLib Properties for Neural Network Verification in VERONA
VERONA translates neural network verification requests into VNNLib property files by orchestrating modular property generators that emit SMT-LIB constraints for targeted or untargeted robustness checks.
The VERONA framework (ada-research/verona) provides a structured pipeline for verifying neural network robustness. When configuring VNNLib properties for neural network verification in VERONA, users interact with a hierarchy of Python classes that abstract the complexity of SMT-LIB syntax while exposing fine-grained control over perturbation bounds and verification objectives.
Core Components for VNNLib Property Generation
VERONA’s architecture decouples property specification from persistence and execution. The following components collaborate to produce valid VNNLib files:
VNNLibProperty Dataclass
The VNNLibProperty class in ada_verona/database/vnnlib_property.py serves as a simple container for generated specifications. It stores the property name, the textual VNNLib content, and an optional file path. Instances of this class are what generators return and what backend solvers consume.
PropertyGenerator Abstract Base Class
All property generators inherit from PropertyGenerator defined in ada_verona/verification_module/property_generator/property_generator.py. This abstract base enforces a consistent interface:
create_vnnlib_property: Generates the actual VNNLib string given an input image, true label, and epsilon.get_dict_for_epsilon_result: Serializes results for database storage.to_dict/from_dict: Enables persistence of generator configuration.
Concrete Generator Implementations
VERONA ships with two primary implementations for robustness verification:
One2OnePropertyGenerator (ada_verona/verification_module/property_generator/one2one_property_generator.py) handles targeted verification. It generates a property that is violated when the network’s output for a specific target class exceeds that of the true class. This is useful for checking if an adversary can force a specific misclassification.
One2AnyPropertyGenerator (ada_verona/verification_module/property_generator/one2any_property_generator.py) handles untargeted verification. It generates a property that is violated when any class other than the true class achieves a higher score than the true class. This checks for any possible adversarial example without specifying the destination class.
VerificationContext Orchestration
The VerificationContext class in ada_verona/database/verification_context.py acts as the orchestration hub. It stores the network (ONNXNetwork), data point, temporary directory, and the chosen generator. Crucially, it provides save_vnnlib_property, which persists the generated property to disk and records the file path for downstream solver consumption.
How VERONA Constructs a VNNLib Property
When configuring VNNLib properties for neural network verification in VERONA, the framework executes a five-step pipeline to translate a raw image into SMT-LIB constraints:
-
Input preprocessing – The raw image (
np.ndarray) is clipped to user-specified data bounds (data_lb,data_ub) and optionally normalized using provided mean and standard deviation values. -
Variable declaration – For each input pixel, a real-valued variable
X_iis declared. For each output class, a real-valued variableY_iis declared. -
Input constraints – Upper- and lower-bound constraints are emitted for every
X_ibased on the perturbation magnitudeepsilon, creating a box constraint around the preprocessed input. -
Output constraint –
- One2One: Emits
(assert (or (and (>= Y_target Y_true))))– the property is falsified if the target class can be made at least as large as the true class. - One2Any: Emits an
orover all non-true classesiof(and (>= Y_i Y_true)).
- One2One: Emits
-
Packaging – The generated string is wrapped in a
VNNLibPropertyinstance, whichVerificationContext.save_vnnlib_propertycan persist to a temporary file for the backend solver.
Practical Example: Creating a VNNLib Property in Python
The following example demonstrates configuring VNNLib properties for neural network verification in VERONA using the One2OnePropertyGenerator for a targeted attack scenario:
# 1️⃣ Choose a property generator
from ada_verona.verification_module.property_generator.one2one_property_generator import One2OnePropertyGenerator
generator = One2OnePropertyGenerator(
target_class=3,
number_classes=10,
data_lb=0,
data_ub=1
)
# 2️⃣ Load a network and a data point (mocked here for brevity)
from ada_verona.database.machine_learning_model.onnx_network import ONNXNetwork
network = ONNXNetwork(name="mnist_onnx", path="models/mnist.onnx")
from ada_verona.database.dataset.data_point import DataPoint
dp = DataPoint(id="sample_001", label=7, data="path/to/image.npy")
# 3️⃣ Create a verification context with a temporary folder
from pathlib import Path
from ada_verona.database.verification_context import VerificationContext
tmp_dir = Path("/tmp/verona_run")
ctx = VerificationContext(
network=network,
data_point=dp,
tmp_path=tmp_dir,
property_generator=generator,
save_epsilon_results=True
)
# 4️⃣ Build a VNNLib property for a concrete epsilon
import numpy as np
image = np.load(dp.data) # shape (1, 28, 28) for MNIST
epsilon = 0.05
vnn_prop = generator.create_vnnlib_property(image, dp.label, epsilon)
# 5️⃣ Persist the property – the context records the file path automatically
ctx.save_vnnlib_property(vnn_prop)
print(f"Saved VNNLib file at: {vnn_prop.path}")
For untargeted verification, replace the generator import with One2AnyPropertyGenerator and omit the target_class parameter.
Summary
- VNNLibProperty (
ada_verona/database/vnnlib_property.py) stores the textual specification and file path. - PropertyGenerator defines the interface, with One2OnePropertyGenerator and One2AnyPropertyGenerator providing targeted and untargeted robustness checks respectively.
- VerificationContext (
ada_verona/database/verification_context.py) orchestrates the pipeline, handling temporary file persistence viasave_vnnlib_property. - The VNNLib construction pipeline preprocesses inputs, declares variables, emits box constraints for epsilon perturbations, and asserts output inequalities based on the verification objective.
Frequently Asked Questions
How do I choose between One2One and One2Any property generators?
Use One2OnePropertyGenerator when you want to verify whether an adversary can force the network to classify an input as a specific target class different from the true label. Use One2AnyPropertyGenerator for untargeted verification, which checks if any misclassification is possible regardless of the destination class. The former is stricter and useful for targeted attack analysis, while the latter provides a general robustness certificate.
What data bounds should I specify when instantiating a property generator?
The data_lb and data_ub parameters should match the valid input range of your dataset after any normalization. For standard image datasets like MNIST or CIFAR-10, use data_lb=0.0 and data_ub=1.0 if pixels are normalized to [0,1], or data_lb=0 and data_ub=255 for raw byte values. These bounds are used in ada_verona/verification_module/property_generator/property_generator.py to clip inputs and define valid perturbation ranges.
How does VERONA handle temporary file storage for VNNLib properties?
The VerificationContext class manages temporary directories through its tmp_path parameter. When you call ctx.save_vnnlib_property(vnn_prop), the context writes the VNNLib content to a file within that temporary directory and updates the path attribute of the VNNLibProperty instance. This ensures that backend solvers can locate the property file while keeping the filesystem organized during batch verification runs.
Can I extend VERONA to support custom verification properties beyond robustness?
Yes, by subclassing PropertyGenerator in ada_verona/verification_module/property_generator/property_generator.py and implementing the create_vnnlib_property method. Your subclass must emit valid SMT-LIB constraints following the VNNLib format. The modular design means you only need to implement the logic for declaring variables and asserting constraints; the VerificationContext will handle file I/O and result aggregation automatically.
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 →