Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Pytorch Serve Mnist Response Data

From Leeroopedia

Overview

Mnist_Response_Data is a JSON data artifact containing sample Captum model explanation output for the MNIST handwritten digit classification model. It provides a reference example of the attribution output format produced by TorchServe's /explanations endpoint, containing per-pixel feature importance scores in a 28x28 matrix matching the MNIST input image dimensions.

Knowledge Sources
Domains Model_Serving, Explainability
Last Updated 2026-02-13 18:52 GMT

Description

The mnist_response.json file (850 lines) is a reference data artifact in the examples/captum/ directory that captures the output of a Captum-based model explanation request against an MNIST digit classification model served by TorchServe. It serves as both test fixture data and as documentation of the explanation response format.

Data Structure

The JSON file contains a single top-level object with an explanations key:

{
  "explanations": [
    [
      [float, float, ..., float],   // row 0 (28 values)
      [float, float, ..., float],   // row 1 (28 values)
      ...
      [float, float, ..., float]    // row 27 (28 values)
    ]
  ]
}

Key Characteristics

  • Top-Level Structure: {"explanations": [[[...]]]} -- a list of explanations, each containing a 2D array of attribution scores
  • Attribution Matrix: 28x28 array of floating-point values matching the MNIST image dimensions (28 pixels wide by 28 pixels tall)
  • Attribution Values: Each float represents the feature importance (attribution score) for the corresponding pixel, as computed by Captum's attribution methods (e.g., IntegratedGradients, Saliency)
  • Positive Values: Pixels that positively contributed to the predicted class
  • Negative Values: Pixels that negatively contributed (pushed away from the predicted class)
  • Near-Zero Values: Pixels that had minimal influence on the prediction

Purpose

This data artifact serves multiple roles:

  1. Reference Example: Demonstrates the exact format of explanation responses from TorchServe's /explanations endpoint
  2. Test Fixture: Used as expected output for validating the explanation pipeline in automated tests
  3. Documentation: Helps developers understand the shape and semantics of Captum attribution output

Code Reference

Source Location

File Lines Repository
examples/captum/mnist_response.json L1-850 pytorch/serve

Schema

# JSON Schema (informal)
{
    "explanations": [          # list of explanations (one per input in batch)
        [                      # single explanation
            [                  # 2D attribution matrix (28 rows x 28 cols)
                [float] * 28   # attribution scores for one row of pixels
            ] * 28
        ]
    ]
}

# Python type annotation equivalent:
# dict[str, list[list[list[float]]]]
# Shape: {"explanations": [batch_size, height=28, width=28]}

I/O Contract

Aspect Description
File Format JSON
Top-Level Key "explanations"
Value Type list[list[list[float]]] -- nested 3D array
Outer List Batch dimension (one entry per input image in the explanation request)
Middle List 28 rows of the attribution matrix (matching MNIST image height)
Inner List 28 float values per row (matching MNIST image width)
Value Range Floating-point attribution scores (positive, negative, or near-zero)
Total Values 28 x 28 = 784 attribution scores per explanation

Relationship to API Response

API Endpoint Method Response Format
/explanations/{model_name} POST JSON body matching the structure in this file

The response from TorchServe's explanation endpoint follows the same schema:

# Request explanation for an MNIST image
curl -X POST http://localhost:8080/explanations/mnist \
    -T examples/captum/0.png

# Response body matches the structure in mnist_response.json

Usage Examples

Example 1: Loading and inspecting the reference data

import json
import numpy as np

# Load the reference response
with open("examples/captum/mnist_response.json", "r") as f:
    data = json.load(f)

# Extract the attribution matrix
attributions = np.array(data["explanations"][0])
print(f"Shape: {attributions.shape}")        # (28, 28)
print(f"Min: {attributions.min():.6f}")
print(f"Max: {attributions.max():.6f}")
print(f"Non-zero pixels: {np.count_nonzero(attributions)}")

Example 2: Visualizing attribution heatmap

import json
import numpy as np
import matplotlib.pyplot as plt

with open("examples/captum/mnist_response.json", "r") as f:
    data = json.load(f)

attributions = np.array(data["explanations"][0])

# Plot attribution heatmap
fig, ax = plt.subplots(1, 1, figsize=(6, 6))
im = ax.imshow(attributions, cmap="seismic", vmin=-abs(attributions).max(),
               vmax=abs(attributions).max())
ax.set_title("MNIST Attribution Heatmap (Captum)")
plt.colorbar(im, ax=ax, label="Attribution Score")
plt.savefig("mnist_attribution_heatmap.png")

Example 3: Using as test fixture

import json
import requests
import numpy as np

# Load expected reference output
with open("examples/captum/mnist_response.json", "r") as f:
    expected = json.load(f)

# Request explanation from running TorchServe
with open("examples/captum/0.png", "rb") as f:
    response = requests.post(
        "http://localhost:8080/explanations/mnist",
        data=f.read(),
        headers={"Content-Type": "application/octet-stream"},
    )

actual = response.json()

# Compare attributions
expected_attr = np.array(expected["explanations"][0])
actual_attr = np.array(actual["explanations"][0])

assert expected_attr.shape == actual_attr.shape == (28, 28)
np.testing.assert_allclose(actual_attr, expected_attr, atol=1e-4)

Example 4: Understanding attribution values

import json
import numpy as np

with open("examples/captum/mnist_response.json", "r") as f:
    data = json.load(f)

attributions = np.array(data["explanations"][0])

# Identify most important pixels
flat_indices = np.argsort(np.abs(attributions).flatten())[::-1]
top_10 = flat_indices[:10]

print("Top 10 most important pixels (by absolute attribution):")
for idx in top_10:
    row, col = divmod(idx, 28)
    score = attributions[row, col]
    direction = "positive" if score > 0 else "negative"
    print(f"  Pixel ({row}, {col}): {score:.6f} ({direction} contribution)")

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment