Internals

These objects are not part of the stable public API: they live in private modules and may change. They are documented here because you need them when extending the library, for example when writing a new attribution method or surrogate (see Adding a new surrogate).

Attribution base class

class causalig.attr._core.attribution.Attribution(forward_func)[source]

Abstract base class for all attribution methods in this package.

Subclasses implement attribute() and inherit input validation and shape-normalisation utilities. The convention throughout is that a single sample may be passed as a 1-D tensor (d,); the base class promotes it to (1, d) before computation and squeezes it back on return so callers never need to manage the batch dimension themselves.

Parameters:

forward_func – Model or callable to attribute. Must accept a (batch, d) float tensor and return a (batch, C) or (batch,) tensor.

abstractmethod attribute(inputs, **kwargs)[source]

Compute attributions for the given inputs.

Parameters:
  • inputs (Tensor) – Input tensor of shape (d,) or (batch, d).

  • **kwargs – Additional arguments specific to each subclass.

Returns:

Attribution tensor of the same shape as inputs, or a tuple (direct, indirect) when separate_effects=True.

Return type:

Tensor | tuple[Tensor, …]

_format_input(inputs)[source]

Promote a 1-D tensor to (1, d) and record whether it was 1-D.

Parameters:

inputs (Tensor) – Tensor of shape (d,) or (batch, d).

Returns:

(normalized, was_single) where normalized is always (batch, d) and was_single is True when the original tensor was 1-D.

Return type:

tuple[Tensor, bool]

_format_output(attributions, was_single)[source]

Squeeze the batch dimension when the original input was 1-D.

Parameters:
Returns:

Tensor (d,) / (batch, d) or matching tuple.

Return type:

Tensor | tuple[Tensor, …]

_validate_inputs(inputs, ordering, baselines=None)[source]

Sanity-check inputs before attribution begins.

Checks that inputs is a non-empty tensor, that ordering length matches the feature dimension, and that baselines (if provided) has a compatible feature dimension and lives on the same device.

Parameters:
  • inputs (Tensor) – Input tensor.

  • ordering (list[int]) – Topological ordering of feature indices.

  • baselines (Tensor | None) – Optional baseline tensor.

Raises:

ValueError – On any shape or device mismatch.

_convergence_delta(input_normalized, baselines_normalized, target, total_attributions)[source]

Completeness (convergence) delta.

Measures how well the summed attributions account for the model output difference between input and the average baseline:

delta = sum_i(attributions_i) - (f(input) - mean_b f(baseline_b))

A delta close to zero indicates the completeness axiom holds; for finite n_steps / single-step sampling this is only approximately satisfied.

Parameters:
  • input_normalized (Tensor) – Input tensor (batch, d).

  • baselines_normalized (Tensor) – Baseline tensor (n_baselines, d).

  • target (int | None) – Output index attributed, or None if the full model output was used.

  • total_attributions (Tensor) – Direct + indirect attributions, summed shape (batch, d, C) (before any C == 1 squeeze).

Returns:

Delta tensor of shape (batch, C), matching total_attributions with the feature dimension reduced.

Return type:

Tensor

Surrogate contract and Jacobians

class causalig.attr._utils.surrogate.ModelInterface[source]

Abstract interface for models used in attribution methods.

This interface decouples attribution methods from specific model implementations, allowing for different model types. Subclassing it is optional: any callable with the same behaviour can be used as a surrogate.

A surrogate maps (batch, d) to (batch, d), where output column j predicts feature j from its causal parents. On the default autograd path, features that are not parents of j arrive set to MASK_VAL.

abstractmethod forward(x)[source]

Forward pass of the model.

Parameters:

x (Tensor) – Input tensor of shape (batch, features)

Returns:

Reconstructed output tensor of shape (batch, features)

Return type:

Tensor

causalig.attr._utils.surrogate.MASK_VAL = 0.0

Convert a string or number to a floating-point number, if possible.

causalig.attr._utils.surrogate.compute_surrogate_gradients(autoencoder, x_flat, ordering, d, device, adjacency_matrix=None, skip_gradients=False, dim_start=0, dim_chunk_size=None, has_closed_form_jacobian=False)[source]

Evaluate a surrogate and its input Jacobian for a chunk of output features.

For every output feature j in [dim_start, dim_start + dim_chunk_size), returns the surrogate’s prediction of x_j and its gradient with respect to the inputs j may depend on: its parents in adjacency_matrix or, if no adjacency is given, every feature before j in ordering. Features without parents get a zero prediction and a zero Jacobian row.

Two strategies are supported:

  • Autograd (default): for each child j the input is copied, every non-parent of j is set to MASK_VAL, the surrogate is called on the masked copies and column j of its output is differentiated.

  • Closed form (has_closed_form_jacobian=True): the surrogate is called once on the unmasked input and must provide compute_input_jacobian(x, dim_start, dim_end) -> (N, chunk, d). The surrogate itself must then ensure output j reads only parents.

Parameters:
  • autoencoder (ModelInterface) – The surrogate, a callable mapping (N, d) to (N, d).

  • x_flat (Tensor) – Points at which to evaluate it, (N, d).

  • ordering (list[int]) – Topological ordering of feature indices, used to build the dependency mask only when adjacency_matrix is None.

  • d (int) – Number of features.

  • device (device) – Device for the outputs.

  • adjacency_matrix (Tensor | None) – Optional (d, d) tensor, [i, j] true if feature i causes feature j.

  • skip_gradients (bool) – If True only compute the predictions and return None for the Jacobian.

  • dim_start (int | None) – First output feature of the chunk.

  • dim_chunk_size (int | None) – Number of output features in the chunk. None means all remaining features.

  • has_closed_form_jacobian (bool) – Use the surrogate’s compute_input_jacobian instead of autograd.

Returns:

(jacobian, predictions) – the masked Jacobian (N, chunk, d) with entry [n, j - dim_start, i] equal to d surrogate(x)[n, j] / d x[n, i] (or None when skip_gradients), and the detached predictions (N, chunk).

Raises:
  • TypeError – If has_closed_form_jacobian is True and the surrogate has no compute_input_jacobian.

  • ValueError – If has_closed_form_jacobian is True and the Jacobian it returns is non-zero for a feature that is not a parent of the output. Only the reported Jacobian is checked, so a surrogate whose compute_input_jacobian misreports its forward pass is not caught. The check is skipped when skip_gradients is True.

Return type:

tuple[Tensor, Tensor]

Path sampling

class causalig.attr._utils.path.PathSampler[source]

Abstract base class for path sampling strategies.

abstractmethod sample(baseline, input, n_steps)[source]

Generate path samples between baseline and input.

Parameters:
  • baseline (Tensor) – Baseline tensor of shape (d,) or (batch, d)

  • input (Tensor) – Input tensor of shape (d,) or (batch, d)

  • n_steps (int) – Number of steps along the path

Returns:

Path samples tensor of shape (n_steps, batch, d) or (n_steps, d)

Return type:

Tensor

class causalig.attr._utils.path.LinearPathSampler[source]

Linear interpolation path sampler.

sample(baseline, input, n_steps, return_alphas=False)[source]

Generate deterministic linear path samples using evenly spaced interpolation in alpha.

Parameters:
  • baseline (Tensor) – Baseline tensor of shape (d,) or (B, d)

  • input (Tensor) – Input tensor of shape (d,) or (I, d)

  • n_steps (int) – Number of interpolation steps

Returns:

Pairwise path samples tensor of shape (n_steps, B, I, d), where each baseline is paired with each input.

Return type:

Tensor

sample_pairwise_stochastic(baseline, input, n_steps, alpha_min=0.0, seed=None, ordered=True, include_endpoints=False, stratified=False)[source]

Generate stochastic linear path samples between each baseline and every input using independent uniform samples per baseline.

For each baseline b and step s:

alpha[s, b] ~ Uniform(0, 1)

Paths are generated as:

baseline[b] + alpha[s, b] * (input[j] - baseline[b])

Parameters:
  • baseline (Tensor) – Baseline tensor of shape (d,) or (B, d)

  • input (Tensor) – Input tensor of shape (d,) or (I, d)

  • n_steps (int) – Number of stochastic samples per baseline

  • alpha_min (float) – Minimum alpha value to ensure samples are not too close to baseline

  • seed (int) – Optional random seed for reproducibility

  • ordered (bool) – Whether to order the samples

  • include_endpoints (bool) – Whether to force alpha=0 and alpha=1 as first/last samples

  • stratified (bool) – Whether to sample one alpha per bin (reduces tiny interval gaps)

Returns:

Path samples tensor of shape (n_steps, B, I, d)

Return type:

Tensor

causalig.attr._utils.path.linear_path_samples(baseline, input, n_steps)[source]

Generate linear path samples between baseline and input.

This is a convenience function that uses LinearPathSampler. Maintains backward compatibility with the original function.

Parameters:
  • baseline (Tensor) – Baseline tensor of shape (d,) or (batch, d)

  • input (Tensor) – Input tensor of shape (d,) or (batch, d)

  • n_steps (int) – Number of steps along the path

Returns:

Path samples tensor of shape (n_steps, batch, d) or (n_steps, d)

Return type:

Tensor