Skip to content

Troubleshooting

The errors below are the ones most frequently reported on the issue tracker and in discussions. Each entry explains the cause and the fix.

RuntimeError: cannot register a hook on a tensor that doesn't require gradient

Also reported as element 0 of tensors does not require grad and does not have a grad_fn.

Gradient-based methods (GradCAM, GradCAMpp, SmoothGradCAMpp, XGradCAM, LayerCAM) backpropagate through the model, so the forward pass must build an autograd graph. The error is raised when autograd is disabled during the forward — almost always because it ran inside torch.no_grad() or torch.inference_mode() (or because every model parameter has requires_grad=False).

Disables autograd — the gradient hook cannot attach

from torchcam.methods import GradCAM

with GradCAM(model) as cam_extractor:
    with torch.inference_mode():            # ❌ no graph is built
        out = model(input_tensor)
    cams = cam_extractor(out.squeeze(0).argmax().item(), out)

Let autograd run during the forward

from torchcam.methods import GradCAM

with GradCAM(model) as cam_extractor:
    out = model(input_tensor)               # ✅ no no_grad / inference_mode
    cams = cam_extractor(out.squeeze(0).argmax().item(), out)

If your inference pipeline wraps everything in torch.no_grad() / torch.inference_mode() for speed, move just the CAM extraction (the hooked forward + the extractor call) outside that context — the rest of your pipeline can stay under no_grad if you like.

model.eval() and torch.no_grad() are orthogonal

eval() only switches dropout/batch-norm to inference behavior; it does not disable autograd, so it is safe — and recommended — for every method. The thing to avoid for gradient-based methods is no_grad()/inference_mode(), not eval(). You generally want model.eval() and autograd enabled.

Activation-based methods don't need gradients

CAM, ScoreCAM, SSCAM and ISCAM do not backpropagate, so you can keep their forward pass inside torch.inference_mode(). Only the gradient-based methods require autograd.

AssertionError: Inputs need to be forwarded in the model ...

The extractor reads activations through hooks that are only active while it is "open". Run the forward pass after creating the extractor (or inside its with block), not before:

with GradCAM(model) as cam_extractor:   # hooks registered here
    out = model(input_tensor)           # forward happens while hooks are live
    cams = cam_extractor(class_idx, out)

The activation map is all NaN

TorchCAM guards the normalization denominator with an epsilon, so a flat map yields zeros rather than NaN. A NaN map therefore almost always means the hooked activations or gradients already contained NaN/Inf coming from the model itself.

  • Check the output: assert torch.isfinite(out).all().
  • Run the CAM forward in float32 (avoid mixed-precision/autocast for this step).
  • Try a different target_layer, or a more numerically stable method (GradCAM, LayerCAM) — the higher-order terms in GradCAMpp/SmoothGradCAMpp are more prone to floating-point underflow.

The heatmap is blank / all zeros

Gradient methods apply a ReLU before normalization, so a layer with no positive contribution to the chosen class produces an empty map. Common causes:

  • class_idx is not the class the layer responds to — pass the prediction: out.squeeze(0).argmax().item().
  • The target layer is too shallow/deep — try LayerCAM (keeps pixel-wise positive contributions) or another layer.
  • The model is untrained or the input is out of distribution.
  • With the activation-based CAM, a fc_layer that doesn't match the chosen target_layer (its channel count or the head it feeds) yields a meaningless or empty map — let CAM resolve fc_layer automatically, or pass a compatible one (see Choosing the target layer).

The CAM changes on every run

The model is in training mode, so dropout / batch-norm add randomness. Switch to eval mode before extracting:

model.eval()

RuntimeError: Trying to backward through the graph a second time

This happens when you call the extractor more than once after a single forward pass (e.g. to compare several classes): the first backward frees the graph. Pass retain_graph=True on every call but the last, or re-run the forward before each call:

with GradCAM(model) as cam_extractor:
    out = model(input_tensor)
    cam_a = cam_extractor(class_a, out, retain_graph=True)
    cam_b = cam_extractor(class_b, out)

AttributeError: '...' object has no attribute 'enable_hooks' / errors when clearing hooks

This usually means a stale or mismatched install. The current API exposes enable_hooks(), disable_hooks(), remove_hooks() and reset_hooks(), and supports the context-manager form (with GradCAM(model) as ...:), which removes the hooks automatically on exit.

  • Upgrade first: pip install -U torchcam.
  • Prefer the with form so hooks are always cleaned up.
  • Use one extractor per model at a time — instantiating several extractors on the same model stacks hooks. Scope them with with, or call remove_hooks() when done.

ImportError: cannot import name '...' from 'torchcam'

The symbol exists in a newer release than the one installed. Upgrade with pip install -U torchcam, or install the latest unreleased version from source (see the installation guide).

Still stuck?

Open a discussion or an issue with a minimal snippet and the output of:

import torch, torchvision, torchcam
print(torchcam.__version__, torch.__version__, torchvision.__version__)