Explainability (XAI)

LibreYOLO includes built-in explainability methods to visualize what the model focuses on when making predictions.

Available CAM Methods

Method

Description

Gradient-Free

eigencam

SVD-based, fast and reliable

gradcam

Gradient-weighted class activation

gradcam++

Improved GradCAM with second-order gradients

xgradcam

Axiom-based GradCAM

hirescam

High-resolution CAM

layercam

Layer-wise CAM

eigengradcam

Eigen-based gradient CAM

Basic Usage

from libreyolo import LIBREYOLO

model = LIBREYOLO(model_path="weights/libreyolo8n.pt", size="n")

# Generate explanation
result = model.explain(
    image="image.jpg",
    method="gradcam",
    save=True
)

# Access the heatmap
heatmap = result["heatmap"]       # Grayscale [0, 1]
overlay = result["overlay"]       # RGB overlay image

Explain Method Parameters

result = model.explain(
    image="image.jpg",
    method="eigencam",           # CAM method
    target_layer="neck_c2f22",   # Layer to visualize
    eigen_smooth=False,          # SVD smoothing
    save=True,                   # Save to disk
    output_path="results/",      # Custom save location
    alpha=0.5,                   # Overlay blending factor
)

Target Layers

Use get_available_layer_names() to see available layers:

model = LIBREYOLO("weights/libreyolo8n.pt", size="n")
print(model.get_available_layer_names())

YOLO8 Layers

Layer

Description

backbone_p1

First convolution

backbone_c2f2_P3

C2F at P3 (Stride 8)

backbone_c2f3_P4

C2F at P4 (Stride 16)

backbone_sppf_P5

SPPF at P5 (Stride 32)

neck_c2f21

Neck C2F block 1

neck_c2f22

Neck C2F block 4 (default)

Choosing a Layer

  • Earlier layers (backbone_p1, p2): Low-level features (edges, textures)

  • Middle layers (c2f2, c2f3): Mid-level features (parts, patterns)

  • Later layers (neck_c2f22): High-level features (objects, semantics)

Auto-Save During Inference

Enable automatic CAM visualization during every inference:

model = LIBREYOLO(
    model_path="weights/libreyolo8n.pt",
    size="n",
    save_eigen_cam=True,      # Auto-save EigenCAM
    cam_method="eigencam",    # Default method
    cam_layer="neck_c2f22"    # Target layer
)

# CAM is automatically saved alongside detections
results = model(image="image.jpg", save=True)
print(results.get("eigen_cam_path"))

Feature Map Visualization

Save raw feature maps from model layers:

# Save all layers
model = LIBREYOLO(
    model_path="weights/libreyolo8n.pt",
    size="n",
    save_feature_maps=True
)

# Save specific layers only
model = LIBREYOLO(
    model_path="weights/libreyolo8n.pt",
    size="n",
    save_feature_maps=["backbone_p1", "neck_c2f22"]
)

results = model(image="image.jpg")
print(results.get("feature_maps_path"))

Output Format

The explain() method returns:

{
    "heatmap": np.ndarray,        # Shape (H, W), values [0, 1]
    "overlay": np.ndarray,        # Shape (H, W, 3), RGB uint8
    "original_image": PIL.Image,  # Original input image
    "method": "gradcam",          # Method used
    "target_layer": "neck_c2f22", # Layer used
    "saved_path": "runs/gradcam/..." # If save=True
}

Comparing Methods

methods = ["eigencam", "gradcam", "gradcam++", "xgradcam"]

for method in methods:
    result = model.explain(
        image="image.jpg",
        method=method,
        save=True
    )
    print(f"{method}: saved to {result['saved_path']}")