Converting Neural Networks to VNNLib Format with VERONA: A Complete Guide
VERONA converts ONNX neural networks into VNNLib property files using modular property generators, enabling formal verification of model robustness against adversarial perturbations.
VERONA (from the ada-research/verona repository) provides a streamlined pipeline for converting neural network classifiers into VNNLib specifications. Converting neural networks to VNNLib format for VERONA involves three core components that transform an input image, its true label, and a perturbation radius into a formal property file ready for verification tools like Marabou or ERAN.
The VERONA Conversion Architecture
The conversion pipeline relies on three interconnected components implemented in the VERONA source code:
- Property generators (
One2OnePropertyGeneratorandOne2AnyPropertyGenerator) located inada_verona/verification_module/property_generator/create the VNNLib logic VNNLibPropertydataclass inada_verona/database/vnnlib_property.pystores the generated specificationVerificationContextinada_verona/database/verification_context.pyorchestrates file I/O and workflow management
This modular design allows you to take any ONNX-compatible network, specify an input data point and epsilon radius, and obtain a .vnnlib file that encodes the robustness property.
Property Generators: Creating VNNLib Specifications
Property generators inherit from the abstract PropertyGenerator base class defined in ada_verona/verification_module/property_generator/property_generator.py. Each generator implements the create_vnnlib_property method to produce platform-agnostic verification constraints.
One2OnePropertyGenerator (Targeted Verification)
The One2OnePropertyGenerator creates properties that check whether a specific target class can outrank the true class under perturbation. Located in ada_verona/verification_module/property_generator/one2one_property_generator.py, this generator produces assertions like:
(assert (or (and (>= Y_target Y_true))))
Use this when verifying whether an adversary can force a specific misclassification (e.g., making the network classify a "7" as a "3").
One2AnyPropertyGenerator (Untargeted Verification)
The One2AnyPropertyGenerator in ada_verona/verification_module/property_generator/one2any_property_generator.py creates untargeted properties that are violated when any non-true class beats the true class:
(assert (or
(and (>= Y_i Y_true)) ; for every i ≠ true class
))
Both generators perform the same preprocessing steps: clipping and normalizing the image with epsilon bounds, declaring input variables X_i and output variables Y_i, and adding bound constraints for each input dimension before appending the output condition.
The VNNLibProperty Dataclass
Generated specifications are wrapped in the VNNLibProperty dataclass from ada_verona/database/vnnlib_property.py:
@dataclass
class VNNLibProperty:
name: str # e.g. "property_3_0_01"
content: str # raw VNNLib script
path: Path = None # populated after saving to disk
This lightweight structure is serializable and database-friendly, allowing properties to persist across process boundaries without losing their raw VNNLib text content.
Managing Workflows with VerificationContext
The VerificationContext class in ada_verona/database/verification_context.py bundles all verification metadata:
network: AnONNXNetworkinstance loaded fromada_verona/database/machine_learning_model/onnx_network.pydata_point: A labeled input fromada_verona/database/dataset/data_point.pytmp_path: Temporary directory for VNNLib file outputproperty_generator: The selected generator instancesave_epsilon_results: Boolean flag for CSV logging
Key methods include save_vnnlib_property(vnnlib_property), which writes the content to <tmp>/<name>.vnnlib and updates the path attribute, and get_dict_for_epsilon_result(), which merges context metadata with generator-specific dictionaries for epsilon-search logging.
The context is fully serializable via to_dict() and from_dict(), using dynamic imports to reconstruct the correct property generator class.
Step-by-Step: Converting an ONNX Model to VNNLib
Follow these steps to convert a neural network to VNNLib format using VERONA.
1. Load the ONNX Network
from pathlib import Path
from ada_verona.database.machine_learning_model.onnx_network import ONNXNetwork
network_path = Path("examples/example_experiment/data/networks/mnist-net_256x2.onnx")
network = ONNXNetwork(network_path) # lazy loading; model read on demand
2. Prepare the Data Point
from ada_verona.database.dataset.data_point import DataPoint
import numpy as np
image = np.load("examples/example_experiment/data/images/0.npy") # shape (1, 28, 28)
image = image.astype(np.float32)
data_point = DataPoint(id="img_0", label=7, data=image)
3. Select a Property Generator
from ada_verona.verification_module.property_generator.one2one_property_generator import One2OnePropertyGenerator
# Targeted: force misclassification to class 3
prop_gen = One2OnePropertyGenerator(target_class=3, number_classes=10)
# For untargeted verification, use:
# from ada_verona.verification_module.property_generator.one2any_property_generator import One2AnyPropertyGenerator
# prop_gen = One2AnyPropertyGenerator(number_classes=10)
4. Create the Verification Context
from ada_verona.database.verification_context import VerificationContext
tmp_dir = Path("tmp_verification")
ctx = VerificationContext(
network=network,
data_point=data_point,
tmp_path=tmp_dir,
property_generator=prop_gen,
save_epsilon_results=False
)
5. Generate and Save the Property
epsilon = 0.02
vnnlib = prop_gen.create_vnnlib_property(
image=data_point.data,
image_class=data_point.label,
epsilon=epsilon,
)
ctx.save_vnnlib_property(vnnlib) # writes tmp_verification/property_7_0_02.vnnlib
print(f"VNNLib file saved at: {vnnlib.path}")
6. Verify with a VNNLib-Compatible Tool
marabou tmp_verification/property_7_0_02.vnnlib network.onnx
7. Serialize for Later Reuse (Optional)
import json
ctx_dict = ctx.to_dict()
json.dump(ctx_dict, open("verif_config.json", "w"), indent=2)
# Reload later
loaded_ctx = VerificationContext.from_dict(json.load(open("verif_config.json")))
Summary
- VERONA's conversion pipeline uses property generators to create VNNLib text,
VNNLibPropertyto package results, andVerificationContextto handle file operations and serialization One2OnePropertyGeneratorcreates targeted properties for specific misclassifications, whileOne2AnyPropertyGeneratorhandles untargeted robustness verification- Generated
.vnnlibfiles comply with the VNNLib specification and work with verifiers like Marabou and ERAN - The entire verification configuration can be serialized and deserialized using the context's
to_dict()andfrom_dict()methods
Frequently Asked Questions
What is the VNNLib format used for in VERONA?
VNNLib is a standardized format for encoding neural network verification properties using SMT-LIB syntax. In VERONA, it expresses constraints that define whether a neural network is robust to epsilon-bounded perturbations for a specific input, allowing external verification engines to formally prove or disprove safety properties.
How does VERONA handle targeted versus untargeted verification?
VERONA handles targeted verification through One2OnePropertyGenerator, which generates properties asserting that a specific target class exceeds the true class score. For untargeted verification, One2AnyPropertyGenerator creates properties asserting that any non-true class can exceed the true class score, representing general adversarial robustness without specifying the destination class.
Can I reuse verification configurations across different machines?
Yes. The VerificationContext class provides to_dict() and from_dict() methods that serialize the entire verification setup, including the network reference, data point, property generator type, and parameters. The deserialization process dynamically imports the correct generator class, making configurations fully portable.
Which neural network formats does VERONA support for conversion?
VERONA primarily supports ONNX format through the ONNXNetwork wrapper in ada_verona/database/machine_learning_model/onnx_network.py. The system uses lazy loading and can convert ONNX models to PyTorch internally, but the VNNLib conversion pipeline accepts any network format that VERONA's Network abstract base class can wrap.
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 →