Official repository for CVPR submission "Hidden Monotonicity: Explaining Deep Neural Networks via their DC Decomposition" (Paper ID 21029).
This repository provides implementations of SplitCAM, SplitLRP, and SplitGrad — novel attribution methods that decompose pretrained ReLU networks into two monotone and convex subnetworks (split-streams). By leveraging a numerically stabilized DC (Difference-of-Convex) decomposition, our methods achieve state-of-the-art explainability results on VGG16 and ResNet18 models across multiple evaluation metrics.
- Network Splitting: Transform any pretrained ReLU network into two monotone streams
gandhsuch thatf = g - h - SplitCAM: LayerCAM-inspired attribution on split networks
- SplitLRP: Layer-wise Relevance Propagation adapted for split-streams
- SplitGrad: Gradient-based explanations with improved signal flow
- Comprehensive Evaluation: Quantus benchmark suite across faithfulness, localization, and robustness metrics
- Pre-trained Models Support: Works with VGG16, ResNet18/34/50, and other ReLU-based architectures
Our methods achieve state-of-the-art performance on ImageNet-S validation:
- VGG16: SplitCAM achieves 0.938 Pointing Game accuracy (vs. 0.887 for Guided Backprop)
- ResNet18: Improvements in Selectivity and localization metrics over LayerCAM baseline
- Robustness: Lower sensitivity to input perturbations compared to standard methods
- Python 3.10+
- PyTorch 2.5.1+
- CUDA-capable GPU recommended (for large-scale experiments)
-
Clone the repository
git clone <repository-url> cd influence_splitting
-
Create virtual environment
python3 -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate
-
Install dependencies
pip install --upgrade pip pip install -r requirements.txt
-
Verify installation
python -c "import torch; import quantus; import captum; print('Installation successful!')"
For Zennit-based LRP implementations:
pip install zennit-
Download ImageNet ILSVRC2012 dataset
- Training set: http://www.image-net.org/challenges/LSVRC/2012/
- Validation set (required): 50,000 images
- Register and download from the official ImageNet website
-
Organize directory structure
data/imagenet/ ├── train/ │ ├── n01440764/ │ │ ├── n01440764_10026.JPEG │ │ └── ... │ └── ... └── val/ ├── n01440764/ │ ├── ILSVRC2012_val_00000293.JPEG │ └── ... └── ...
Required for localization metrics (Attribution Localization, Pointing Game).
-
Download ImageNet-S
- Paper: ImageNet-S Dataset
- Download link: https://github.com/LUSSeg/ImageNet-S
- We use ImageNetS50 split (50 classes with segmentation masks)
-
Extract and organize
data/imagenet-s/ └── ImageNetS50/ └── validation-segmentation/ ├── n01440764/ │ ├── ILSVRC2012_val_00000293.png │ └── ... └── ... -
Update paths in config
# Edit paths in xai/unified_xai_evaluation.py or pass as arguments: --imagenet-data-dir /path/to/data/imagenet --imagenet-s-data-dir /path/to/data/imagenet-s
For DIC/DM model experiments (Appendix):
# MNIST is downloaded automatically via torchvision
from torchvision import datasets
datasets.MNIST('./data/mnist', train=True, download=True)python xai/unified_xai_evaluation.py \
--phase maps \
--num-images 100 \
--model vgg16 \
--method-configs quantus_evaluation_configs/vgg_full_eval/classical_layerOptimized/python xai/unified_xai_evaluation.py \
--phase eval \
--output-dir <experiment-output-dir> \
--imagenet-data-dir ./data/imagenet \
--imagenet-s-data-dir ./data/imagenet-spython xai/unified_xai_evaluation.py \
--num-images 616 \
--model vgg16 \
--imagenet-data-dir ./data/imagenet \
--imagenet-s-data-dir ./data/imagenet-s \
--output-dir ./results/vgg16_full_evalMeasure computational overhead of split-stream processing:
python xai/unified_xai_evaluation.py \
--phase timing \
--timing-config-dir quantus_evaluation_configs/timing \
--output-dir ./timing_resultsdc_decomposition/ # Network splitting implementation
├── direct_split/ # Forward splitting (for inference & SplitCAM)
│ └── modules/ # Layer-wise split implementations
├── hybrid_split/ # Hybrid split (combines direct + TC)
├── tc_split/ # Backward stabilization (for SplitLRP/SplitGrad)
└── config/ # Splitting configuration
xai/ # XAI attribution methods
├── layerwise_split_saliency.py # SplitCAM implementation
├── lrp.py # SplitLRP implementation
├── gradient_alpha_comparison.py # SplitGrad experiments
├── evaluation/ # Evaluation framework
│ ├── map_generation.py # Saliency map generation
│ ├── unified_evaluator.py # Main evaluator class
│ ├── timing_evaluation.py # Timing benchmarks
│ ├── imagenet_s_dataset.py # ImageNet-S data loader
│ └── explanation_modules/ # Method implementations
└── unified_xai_evaluation.py # Main entry point
quantus_evaluation_configs/ # Experiment configurations
├── vgg_full_eval/ # VGG16 full evaluation
│ ├── classical_layerOptimized/ # Layer-wise configs
│ ├── hybridMethods_*/ # Split method configs
│ └── vgg_classical/ # Standard baselines
├── res_full_eval/ # ResNet18 evaluation
├── metrics/ # Quantus metric configurations
│ └── enabled/
│ ├── faithfulness/ # Pixel Flipping, Selectivity
│ ├── localization/ # Attribution Loc, Pointing Game
│ └── robustness/ # Max Sensitivity
└── timing/ # Timing experiment configs
tex/ # LaTeX paper source
├── sections/ # Main paper sections
│ ├── introduction.tex
│ ├── method.tex
│ └── experiments.tex
├── appendix/ # Supplementary material
└── figures/ # Paper figures
quantus_evaluation_results/ # Experiment outputs
xai_eval/ # Legacy evaluation scripts
from dc_decomposition.direct_split import DirectSplitModel
from xai.layerwise_split_saliency import compute_split_cam
import torch
from torchvision import models, transforms
# Load pretrained model
model = models.vgg16(pretrained=True).eval()
# Create split model
split_model = DirectSplitModel(
model=model,
alpha=0.4, # Stabilization parameter
input_dim=(1, 3, 224, 224)
)
# Load and preprocess image
transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
image = transform(your_image).unsqueeze(0)
# Compute SplitCAM
saliency_map = compute_split_cam(
split_model=split_model,
image=image,
target_class=target_class,
target_layer='features.28' # Layer selection
)# Evaluate all methods on validation set
python xai/unified_xai_evaluation.py \
--method-configs quantus_evaluation_configs/vgg_full_eval/ \
--num-images 50 \
--split val# Vary alpha parameter (backward stabilization)
for alpha in 0.0 0.2 0.3 0.4 0.5; do
python xai/unified_xai_evaluation.py \
--alpha $alpha \
--output-dir results/alpha_${alpha}
doneusage: unified_xai_evaluation.py [-h] [--phase PHASE [PHASE ...]]
[--num-images NUM_IMAGES]
[--model {vgg16,resnet18,resnet34,resnet50}]
[--method-configs METHOD_CONFIGS]
[--imagenet-data-dir PATH]
[--imagenet-s-data-dir PATH]
[--output-dir PATH]
[--random-seed SEED]
[--split {val,test}]
[--alpha ALPHA]
[--innerloop-n N]
[--device DEVICE]
Key Arguments:
--phase Execution phases: maps, eval, aggregate, timing
--num-images Number of images to evaluate (default: 616)
--model Model architecture (default: vgg16)
--method-configs Path to method configuration directory
--imagenet-data-dir ImageNet dataset root
--imagenet-s-data-dir ImageNet-S dataset root
--output-dir Results output directory
--alpha Backward stabilization parameter (0.0-0.5)
--split Dataset split: val (50 images) or test (566 images)
--random-seed Random seed for reproducibility
If you use this code in your research, please cite:
@inproceedings{zimmermann2026hidden,
title = {Hidden Monotonicity: Explaining Deep Neural Networks via their {DC} Decomposition},
author = {Zimmermann, Jakob Paul and Loho, Georg},
booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},
year = {2026},
note = {Highlight},
url = {https://openaccess.thecvf.com/content/CVPR2026/html/Zimmermann_Hidden_Monotonicity_Explaining_Deep_Neural_Networks_via_their_DC_Decomposition_CVPR_2026_paper.html}
}This code is released under MIT License for academic and non-commercial use.
This research builds upon:
- Quantus - XAI evaluation framework
- Captum - PyTorch interpretability library
- ImageNet-S - Segmentation annotations
- Zennit - LRP implementations