Mesh-aware explainability for DiffusionNet on triangular meshes.
Integrated Gradients on 4 SHREC11 meshes (2 men, 2 women), using a lightly diffused heat baseline.
GeoInspect is an XAI toolkit designed for geometric deep learning on meshes. It provides explainability methods that are adapted to mesh geometry through mass weighting, Laplace-Beltrami operators, and spectral/heat smoothing.
It is built to work directly with DiffusionNet checkpoints.
- Mesh-aware Saliency
- Mesh-aware Integrated Gradients (including heat/spectral baselines)
- Intrinsic Grad-CAM for mesh activations
- Interactive Polyscope visualization with map/method selection and
t (tau)slider - End-to-end script for trained DiffusionNet models
From repository root:
python -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -e .Recommended extras:
pip install -e ".[diffusionnet,viz,test]"Let:
- mesh vertices/features be
$X \in \mathbb{R}^{N \times C}$ - mass vector be
$m \in \mathbb{R}^{N}_{+}$ - Laplace-Beltrami discretization be
$L$ - target class logit be
$f_c(X)$
Heat-based smoothing (implicit discretization):
This is the discrete counterpart of heat diffusion and is used as a smooth baseline or post-processing operator.
All explainers use the same call pattern:
result = explainer.explain(
features=features, # torch.Tensor, typically [N, C]
operators=operators, # MeshOperators
target=target_idx, # class index, callable, or target spec
)from geoinspect import SaliencyConfig, SaliencyExplainer
saliency = SaliencyExplainer(
model,
SaliencyConfig(
aggregation="l2",
mass_normalize=True,
smooth="heat",
smooth_tau=0.02,
smooth_num_modes=64,
normalize=None,
prefer_operator_signature=True,
forward_kwargs={"faces": faces},
),
)
result = saliency.explain(features=features, operators=operators, target=target_idx)Key options:
aggregation:l2,l1,abs_sum, orsignedmass_normalize: divide vertex gradients by local massbaseline: withaggregation="signed", choosezero,mean,heat, orspectral_lowpasssmooth:none,heat, orhelmholtz(smooth_tau,smooth_num_modes)
Heat baseline:
Integrated gradients:
Mass-weighted completeness check:
from geoinspect import IntegratedGradientsConfig, IntegratedGradientsExplainer
ig = IntegratedGradientsExplainer(
model,
IntegratedGradientsConfig(
steps=48,
baseline="heat",
baseline_kwargs={"tau": 0.03, "num_modes": 64},
mass_normalize_gradients=True,
return_channelwise=False,
smooth="heat",
smooth_tau=0.01,
prefer_operator_signature=True,
forward_kwargs={"faces": faces},
),
)
result = ig.explain(features=features, operators=operators, target=target_idx)Key options:
steps: number of integration points along the pathbaseline:zero,mean,heat, orspectral_lowpassbaseline_kwargs: for exampletauandnum_modesmass_normalize_gradients: mass-aware gradient normalization before integrationreturn_channelwise: keep channel-level IG instead of collapsing to scalar per vertex
For layer activations
from geoinspect import GradCAMConfig, IntrinsicGradCAMExplainer
gradcam = IntrinsicGradCAMExplainer(
model,
GradCAMConfig(
target_layer="block_3.mlp", # adapt to your model module path
mass_weighted=True,
signed=True,
use_relu=False,
smooth="heat",
smooth_tau=0.02,
return_channel_weights=True,
prefer_operator_signature=True,
forward_kwargs={"faces": faces},
),
)
result = gradcam.explain(features=features, operators=operators, target=target_idx)Key options:
target_layer: module path where activations are capturedmass_weighted: use mass-weighted averaging for channel importancesigned/use_relu: signed CAM or positive-only CAM behaviorreturn_channel_weights: expose per-channel weights inresult.metadata
src/geoinspect/: core library codeexamples/: runnable examples and sanity scriptstests/: teststhird_party/diffusion-net/: DiffusionNet source used for experimentsimages/: README assets
For a compact command-by-command guide:
Sharp, N., Attaiki, S., Crane, K., and Ovsjanikov, M. 2022. DiffusionNet: Discretization Agnostic Learning on Surfaces. ACM Transactions on Graphics 41(3), 27:1-27:16. https://doi.org/10.1145/3507905
pytest tests -q