Skip to main content

mantissa-interpret

License Python Base Engine

Seeing what a CNN looks at. A trained classifier gives you a label; it does not tell you why. mantissa-interpret answers that with three classic attribution methods that turn a prediction into a heatmap over the input — bright where the pixels mattered for the class, dark where they did not.

Everything runs on a fitted mantissa_cnn.Sequential model, using the model's own forward and backward passes through the mantissa C engine — the same engine it was trained on. There is no PyTorch/TensorFlow dependency: the heatmaps come out of the same low-precision C kernels that produced the prediction.

The mantissa family

Part of the mantissa family: a low-precision engine written in C, with small Python packages built on top. Each package sits under the one it depends on — ⭐ marks where you are, and every other name links to its repo.

  • mantissa — low-precision neural-network engine in C (the core)
    • mantissa-perceptron — perceptron & ADALINE, the linear classics
    • mantissa-nn — shared neural-net primitives (layers, engine binding)
      • mantissa-cnn — convolutional networks for images
        • mantissa-auto-encoder — autoencoders for denoising & super-resolution
        • ⭐ mantissa-interpret — CNN interpretability (occlusion, saliency, Grad-CAM) (you are here)
        • mantissa-embed — CNN metric learning (image embeddings for similarity & retrieval)
      • mantissa-mlp — multilayer perceptrons, fully-connected nets

New to interpretability?

A CNN classifier turns an image into a label — but the label alone hides why. Interpretability (here, attribution) recovers the missing reason: it marks which parts of the input the model actually used for a given class, as a heatmap laid over the image. That matters because a model can be right for the wrong reason — keying on a watermark, a background, or a dataset artifact instead of the object — and a bare accuracy number will never tell you. A heatmap will.

The most direct way to see this is to hide part of the image and watch the prediction. If covering a region makes the class probability collapse, that region carried the evidence; if nothing changes, it did not:

covering the important strokes of an 8 drops P(8) from 1.00 to 0.00; covering empty space leaves it at 1.00

That single experiment is the first method. The three methods here are three answers to "what did the model use?", trading detail for cost and clarity:

  • Occlusion — exactly the picture above, done everywhere: slide a patch over the image and record how much each position, when hidden, drops the class probability. No math beyond running the model forward; the price is one forward pass per patch, and the resolution is patch-sized.
  • Saliency — instead of hiding pixels, ask calculus which pixels matter: the gradient of the class score with respect to each input pixel. A large gradient means "nudging this pixel would move the score a lot." It is per-pixel sharp but noisy, and needs a single backward pass.
  • Grad-CAM — work inside the network. At a convolutional layer each channel is a learned feature detector over a coarse grid; weight every channel by how much raising its activation would raise the target score (its gradient), add them up, and keep the positive part. The result is a smooth, class-discriminative region — ask about "3" vs "7" on the same image and the map moves — for one backward pass.

Occlusion and saliency answer which pixels; Grad-CAM answers which region, for this class. Together they are the standard first tools for debugging a model that is right for the wrong reason.

Install

pip install mantissa-interpret

Pulls in mantissa-cnn (and transitively mantissa-nn + the mantissa-core engine). For plotting the heatmaps, pip install mantissa-interpret[viz].

The three methods

method cost granularity class-discriminative needs
occlusion_map forward only, O(patches) coarse (patch) yes —
saliency_map one backward pass per-pixel (noisy) weakly input gradient
grad_cam one backward pass per-region (smooth) yes activations + their gradient at a conv layer

Each takes a fitted model and a single (C, H, W) image and returns a 2-D heatmap normalized to [0, 1], aligned to the input.

Occlusion — occlusion_map

Slide a patch×patch window (filled with fill) across the image; at each position, hide that window and re-run the model. If the target class probability drops a lot, those pixels were important. The heatmap is the per-pixel average drop (overlapping windows blend), normalized to [0, 1].

from mantissa_interpret import occlusion_map
heat = occlusion_map(net, image, target_class=7, patch=7, stride=3)

Only forward passes — model-agnostic and dead simple, but coarse (patch-sized) and its cost scales with the number of windows. All occluded copies are run in a single batched forward pass.

Saliency — saliency_map

The first-order sensitivity of the class score to each pixel is just its gradient. One forward pass primes the layers, we seed the gradient of the target logit (a one-hot vector), and backpropagate to the input — the same backward the model trains with, carried one step past the first layer's weights down to the pixels. The map is |gradient| reduced over channels.

from mantissa_interpret import saliency_map
heat = saliency_map(net, image, target_class=7)

Per-pixel and cheap (one backward pass), but high-frequency and noisy, and only weakly class-discriminative — good for "which strokes", not "which region".

Grad-CAM — grad_cam

At a convolutional layer, each channel is a learned feature detector over a coarse grid. Grad-CAM weights every channel by the average gradient of the target logit w.r.t. that channel's activation (how much "more of this feature" raises the class score), sums the channels with those weights, keeps the positive part, and upsamples to the image. We capture the layer's activation on the forward pass and backpropagate the logit down to that same layer for the gradient — then combine.

from mantissa_interpret import grad_cam
heat = grad_cam(net, image, target_class=7)      # last Conv2D by default

Coarse (conv-grid resolution) but smooth and genuinely class-discriminative — asking about different classes on the same image yields different maps. target_layer selects which conv layer to read (default: the last one).

Results

A LeNet-5 trained on an 8k-image MNIST subset with the mantissa C engine (3 epochs, 96% test accuracy), then explained on held-out digits. Reproduce with python examples/heatmaps_demo.py.

occlusion, saliency and Grad-CAM heatmaps on MNIST digits

Reading across a row, the three methods agree on the digit but differ exactly as their math predicts:

  • occlusion — coarse, patch-sized blobs on the strokes whose removal costs the class the most;
  • saliency — the finest detail, tracing individual strokes, but visibly noisy (the raw per-pixel gradient);
  • Grad-CAM — a smooth region over the class-defining strokes (the 7's diagonal, the 2's base, the 9's loop), with the least clutter.

Grad-CAM is also class-discriminative — ask it about a different target class on the same image and the map moves:

Grad-CAM for two different target classes on the same 7

All of this — feature maps, gradients, the optimization-free attribution — comes out of the same low-precision C kernels the model was trained on.

License

MIT — Tekin Ertekin.

Metadata

Release files for mantissa-interpret 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mantissa-interpret 0.1.0
File Size Uploaded Provenance
mantissa_interpret-0.1.0.tar.gz 9.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mantissa-interpret 0.1.0
File Interpreter ABI Platform
mantissa_interpret-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 20.8 kB

Release files / mantissa_interpret-0.1.0.tar.gz

Download URL mantissa_interpret-0.1.0.tar.gz
Size 9.5 kB
Tags Source
SHA-256 checksum
How to use checksums
4d999d93519be5bea6e6c32bd88030d480eed38027e3ca22515c7a00805ab7ef
BLAKE2b-256 checksum
How to use checksums
c50de6402f6deed2a8514ef0a546a7801d0cab2ed1f495ab81982bc50708d5cc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.

Transparency log

Release files / mantissa_interpret-0.1.0-py3-none-any.whl

Download URL mantissa_interpret-0.1.0-py3-none-any.whl
Size 11.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1f778262f92a7f20cc75b35300401306b8d3d328e628ab6e7ec7274933c1ec0f
BLAKE2b-256 checksum
How to use checksums
1b9b64cc76fbdd3b9a418e83303d8a858ec0a00d63931cb54c9d12775786b2a0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.

Transparency log

Security for mantissa-interpret 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for mantissa_interpret-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page