Framework adapters#
Native frameworks supply gradients; UnifiedIG supplies baseline handling,
path integration, output conventions, and completeness checks. Install the
framework appropriate for your model and device separately, or use the
torch, jax, or tensorflow extras for their standard dependency.
PyTorch#
Pass a torch.nn.Module directly. Inputs must be a single tensor per sample,
with one scalar or output vector per sample. UnifiedIG respects the module’s
device and floating dtype and restores its prior training/evaluation state.
import numpy as np
import torch
from cbaseline import background
import unifiedig as uig
torch.manual_seed(6)
model = torch.nn.Sequential(
torch.nn.Linear(3, 8),
torch.nn.Tanh(),
torch.nn.Linear(8, 1),
)
data = torch.tensor([[0.5, -0.2, 0.8]])
reference = torch.randn(200, 3)
with torch.no_grad():
reference_predictions = model(reference).numpy()[:, 0]
f0 = float(reference_predictions.mean())
bg = background(
predictions=reference_predictions,
f0=f0,
features=reference.numpy(),
weighting="calibrated",
)
# A deliberate single starting point is also valid: uig.Explainer(model, x0).
explanation = uig.Explainer(model, bg)(data)
print(explanation.values)
print(explanation.max_abs_completeness_error)
JAX#
Wrap a differentiable prediction function in uig.JaxModel. The function is
called with a batch by default. With explicit parameters, it receives
(params, X); otherwise it receives X. Use vectorize=True for a function
written for a single observation. Flax, NNX, Equinox, and Haiku models can be
exposed through this calling convention; no additional UnifiedIG adapter is
needed for each library.
import jax.numpy as jnp
import numpy as np
from cbaseline import background
import unifiedig as uig
def predict(params, X):
hidden = jnp.tanh(X @ params["hidden_weights"])
return hidden @ params["output_weights"]
params = {
"hidden_weights": jnp.array([[0.8, -0.3], [0.2, 0.7]]),
"output_weights": jnp.array([1.1, -0.6]),
}
rng = np.random.default_rng(4)
reference = rng.normal(size=(200, 2)).astype(np.float32)
reference_predictions = np.asarray(predict(params, jnp.asarray(reference)))
f0 = float(reference_predictions.mean())
bg = background(
predictions=reference_predictions,
f0=f0,
features=reference,
weighting="calibrated",
)
X_eval = np.array([[0.5, -0.2], [1.0, 0.4]], dtype=np.float32)
# JAX has no single fitted-model protocol: prediction functions may keep their
# parameters in a separate pytree, capture them in a closure, or belong to a
# framework such as Flax or Equinox. JaxModel is a lightweight adapter that
# records how UnifiedIG should call the function. It does not convert, copy,
# train, or otherwise modify the model or its parameters.
jax_model = uig.JaxModel(predict, params=params)
# A deliberate single starting point is also valid:
# uig.Explainer(jax_model, x0).
explanation = uig.Explainer(jax_model, bg)(X_eval)
print(explanation.values)
print(explanation.max_abs_completeness_error)
TensorFlow and Keras#
TensorFlow-backed Keras models work directly. Wrap an arbitrary differentiable
TensorFlow function with uig.TensorFlowModel. Keras 3 uses its configured
TensorFlow, JAX, or PyTorch backend; configure it before importing Keras.
import numpy as np
from tensorflow import keras
from cbaseline import background
import unifiedig as uig
keras.utils.set_random_seed(9)
model = keras.Sequential(
[
keras.Input((3,)),
keras.layers.Dense(8, activation="tanh"),
keras.layers.Dense(1),
]
)
data = np.array([[0.5, -0.2, 0.8]], dtype=np.float32)
rng = np.random.default_rng(9)
reference = rng.normal(size=(200, 3)).astype(np.float32)
reference_predictions = model(reference, training=False).numpy()[:, 0]
f0 = float(reference_predictions.mean())
bg = background(
predictions=reference_predictions,
f0=f0,
features=reference,
weighting="calibrated",
)
# A deliberate single starting point is also valid: uig.Explainer(model, x0).
explanation = uig.Explainer(model, bg)(data)
print(explanation.values)
print(explanation.max_abs_completeness_error)
Output contract#
Supply raw scores for classification. Visible sigmoid/softmax Keras heads are
rejected, but UnifiedIG cannot inspect every transformation hidden in a custom
function. Vector outputs default to class scores; use
output_kind="regression" for multiple regression outputs. Multiple input
tensors, dictionaries of outputs, and arbitrary structured outputs are outside
the supported contract. See output interpretation.
The docs example checker runs framework examples when their dependencies are installed. Optional-framework CI jobs also check these examples alongside the backend tests; the documentation build itself needs only core dependencies.