Example: Manual Bounds on an Affine + ReLU Graph#
This example builds the abstract value by hand — no model export — and invokes the zonotope ReLU handler directly.
import torch
from boundlab import Error
from boundlab.utils import ShapeDtype
from boundlab.zono import Zono, interpret
# x in center + [-1, 1]^4
center = torch.tensor([0.2, -0.5, 1.0, -1.2])
err = Error("input", ShapeDtype(center.shape, center.dtype))
x = Zono.error(err) + center
# One affine layer y = x @ W + b, exact on the zonotope.
W = torch.tensor([
[1.0, -0.5],
[-0.2, 0.8],
[0.4, 0.0],
[0.0, 1.1],
])
b = torch.tensor([0.1, -0.3])
y_lin = x @ W + b
# Apply the registered zonotope ReLU handler directly.
y = interpret.relu(y_lin)
lb, ub = y.lbub()
print("lb =", lb)
print("ub =", ub)
print("width =", ub - lb)
What this demonstrates#
Modeling uncertainty with an
Errorsymbol lifted byZono.error.Composing affine maps with
@and+— exact for zonotopes.Invoking a nonlinear handler from the interpreter by attribute (
interpret.relu).Concretizing a final expression via
lbub().