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:

  1. 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.

  2. Variable declaration – For each input pixel, a real-valued variable X_i is declared. For each output class, a real-valued variable Y_i is declared.

  3. Input constraints – Upper- and lower-bound constraints are emitted for every X_i based on the perturbation magnitude epsilon, creating a box constraint around the preprocessed input.

  4. 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 or over all non-true classes i of (and (>= Y_i Y_true)).
  5. Packaging – The generated string is wrapped in a VNNLibProperty instance, which VerificationContext.save_vnnlib_property can 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 via save_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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →