YOLO26 热力图可视化完整教程:Grad-CAM、Grad-CAM++、XGrad-CAM、EigenCAM 一键生成

YOLO26 热力图可视化完整教程:Grad-CAM、Grad-CAM++、XGrad-CAM、EigenCAM 与检测框密度图一键生成

适用对象:YOLO26、Ultralytics YOLO、目标检测可解释性、论文可视化、模型改进消融分析。

本文配套脚本为路径即用版:通常只需要修改图片路径和模型路径,就能自动输出热力图、检测结果图、多方法对比图、不同层对比图和 metadata 记录。


一、为什么要做 YOLO26 热力图?

很多同学做 YOLO26 改进实验时,论文里只给 mAP、Precision、Recall、FPS 这些指标。指标当然重要,但如果你想说明模型为什么有效,只看表格是不够的主要是不够丰富!

热力图可视化能回答几个关键问题:

  1. 模型到底关注了图像的哪一块区域?
  2. 改进模块是否真的增强了目标区域响应?
  3. 小目标、遮挡目标、密集目标是否被模型捕获?
  4. 错检、漏检时,模型是没看到目标,还是看到了背景干扰?
  5. 论文消融实验中,改进前后关注区域是否更合理?

对于 YOLO26 这类端到端检测模型,热力图尤其有意义。因为 YOLO26 强调端到端、无 NMS、轻量部署和实时检测,如果只看最终检测框,很难解释中间特征到底学到了什么。


二、本文最终效果

运行脚本后,会自动生成以下结果:

text 复制代码
runs/yolo26_heatmap/
├── original.jpg                         # 原图
├── detection_result.jpg                 # 检测框结果
├── eigen_cam_raw.jpg                    # EigenCAM 原始热力图
├── eigen_cam_overlay.jpg                # EigenCAM 叠加图
├── grad_cam_raw.jpg                     # Grad-CAM 原始热力图
├── grad_cam_overlay.jpg                 # Grad-CAM 叠加图
├── grad_cam_plus_plus_raw.jpg           # Grad-CAM++ 原始热力图
├── grad_cam_plus_plus_overlay.jpg       # Grad-CAM++ 叠加图
├── xgrad_cam_raw.jpg                    # XGrad-CAM 原始热力图
├── xgrad_cam_overlay.jpg                # XGrad-CAM 叠加图
├── detection_density_raw.jpg            # 检测框密度热力图
├── detection_density_overlay.jpg        # 检测框密度叠加图
├── heatmap_methods_compare.jpg          # 多方法对比大图
└── metadata.json                        # 本次运行配置、检测框、目标层、输出路径

示例多方法对比图:

不同目标层对比图:

三、脚本改进目标

其他热力图脚本常见问题主要有三类:

第一,Grad-CAM 获取不到梯度。

很多 YOLO 脚本直接对 model(img) 的最终结果反传,但 YOLO 的最终结果往往已经经过后处理、top-k、NMS 或端到端筛选,部分张量已经不具备可用梯度。YOLO26 的端到端输出尤其容易遇到这个问题。

第二,热力图是"伪热力图"。

有些脚本在 Grad-CAM 失败后,用图像中心高斯图代替,这种图看起来像热力图,但并不来自模型特征,不能用于论文可解释性分析。

第三,只选最后一层,忽略 YOLO 多尺度检测。

YOLO 检测头通常接收多个尺度的特征层,例如小目标、中目标、大目标分别来自不同层。如果只解释最后一个特征层,可能会漏掉某些尺度的响应。

因此本文基于上述问题做了这些改进:

  1. 默认只需要改 MODEL_PATHIMAGE_PATH
  2. 自动从当前仓库导入本地 ultralytics,适合魔改 YOLO26 工程。
  3. 检测模型和解释模型分开加载,避免推理优化破坏 Grad-CAM 分支。
  4. 默认自动挂载 YOLO26 Detect 头输入的 3 个尺度层,例如 model.16 + model.19 + model.22
  5. 支持 EigenCAM、Grad-CAM、Grad-CAM++、XGrad-CAM、检测框密度图。
  6. 自动保存原图、检测图、每种方法的 raw 图、overlay 图、方法对比图。
  7. 自动保存 metadata.json,方便论文复现实验记录。

四、使用方法

4.1 文件位置

脚本路径:

text 复制代码
D:\Users\D\Desktop\ultralytics26-main6.20\YOLO26Heatmap.py

4.2 最简单用法:只改两个路径

打开 YOLO26Heatmap.py,修改文件顶部这两行:

python 复制代码
MODEL_PATH = ROOT / "yolo26n.pt"  # 改成你的 .pt 模型
IMAGE_PATH = ROOT / "test1.jpg"   # 改成你的图片

然后运行:

bash 复制代码
python YOLO26Heatmap.py

如果你的 Python 环境不是 base,而是某个 YOLO 环境,例如:

bash 复制代码
C:\Users\D\.conda\envs\yolov12\python.exe YOLO26Heatmap.py

4.3 命令行指定路径

不想改脚本,也可以直接命令行传参:

bash 复制代码
python YOLO26Heatmap.py ^
  --model D:\Users\D\Desktop\ultralytics26-main6.15\yolo26n.pt ^
  --image D:\Users\D\Desktop\ultralytics26-main6.15\test1.jpg ^
  --out runs\yolo26_heatmap ^
  --device cpu ^
  --conf 0.25

使用 GPU:

bash 复制代码
python YOLO26Heatmap.py --device cuda:0

只解释某一个类别,例如 COCO 中 person 类别为 0:

bash 复制代码
python YOLO26Heatmap.py --class-id 0

指定目标层:

bash 复制代码
python YOLO26Heatmap.py --layer 16
python YOLO26Heatmap.py --layer 19
python YOLO26Heatmap.py --layer 22

只生成部分方法:

bash 复制代码
python YOLO26Heatmap.py --methods eigen_cam grad_cam_plus_plus detection_density

查看模型层:

bash 复制代码
python YOLO26Heatmap.py --list-layers

五、环境配置

如果你的环境已经能正常训练或推理 YOLO26,一般直接运行即可。

如果缺少依赖,可以新建环境:

bash 复制代码
conda create -n yolo26_heatmap python=3.11 -y
conda activate yolo26_heatmap
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124
pip install ultralytics opencv-python matplotlib pillow numpy

CPU 环境可以安装 CPU 版 PyTorch:

bash 复制代码
pip install torch torchvision
pip install ultralytics opencv-python matplotlib pillow numpy

如果你使用的是本地魔改版 YOLO26 工程,建议在仓库目录运行脚本:

bash 复制代码
cd D:\Users\D\Desktop\ultralytics26-main6.15
python YOLO26Heatmap.py

这样脚本会优先导入当前目录里的 ultralytics 源码,而不是系统里另一个版本的 ultralytics。


六、核心代码说明

顶部配置如下:

python 复制代码
ROOT = Path(__file__).resolve().parent

MODEL_PATH = ROOT / "yolo26n.pt"
IMAGE_PATH = ROOT / "test1.jpg"

OUTPUT_DIR = ROOT / "runs" / "yolo26_heatmap"
IMG_SIZE = 640
DEVICE = "auto"

CONF_THRESHOLD = 0.25
TARGET_CLASS = None
TARGET_LAYER = "auto"

METHODS = ("eigen_cam", "grad_cam", "grad_cam_plus_plus", "xgrad_cam", "detection_density")

普通用户最常改的是:

python 复制代码
MODEL_PATH = ROOT / "你的模型.pt"
IMAGE_PATH = ROOT / "你的图片.jpg"

如果你是论文可视化,推荐保留默认:

python 复制代码
TARGET_LAYER = "auto"
METHODS = ("eigen_cam", "grad_cam", "grad_cam_plus_plus", "xgrad_cam", "detection_density")

默认的 auto 会自动读取 YOLO26 Detect 头的输入层。例如本次示例中自动选择:

text 复制代码
model.16
model.19
model.22

这三个层分别对应不同尺度的检测特征。脚本会分别计算 CAM,再融合成最终热力图。


七、为什么 YOLO26 热力图容易失败?

很多 YOLO 热力图代码在分类模型上能跑,在检测模型上却经常出错,原因主要有三个。

7.1 分类模型只有一个类别分数,检测模型有大量候选框

分类模型的 Grad-CAM 通常对某个类别 logit 反传,例如:

python 复制代码
score = output[:, class_id]
score.backward()

但是 YOLO 检测模型输出的是大量候选框,每个候选框还有坐标、类别分数、置信度等信息。直接对最终结果反传,往往不稳定。

7.2 YOLO26 是端到端检测,最终输出可能已经后处理

YOLO26 的最终输出可能类似:

text 复制代码
[1, 300, 6]

其中每行对应一个候选检测结果。这个结果已经接近最终预测,不一定适合作为 Grad-CAM 的反传目标。

因此脚本优先使用 YOLO26 的原始训练分支:

text 复制代码
one2many.scores

它是检测头原始分类 logits,更适合用于梯度反传。

7.3 推理优化会破坏可解释分支

Ultralytics 在预测时可能会做 fuse、strip、推理优化。这样可以提高速度,但可能让某些中间分支不再保留梯度。

所以本文脚本采用两个模型实例:

text 复制代码
detector:负责正常检测和画框
yolo/model:保留完整结构,负责 CAM 反传

这样既能得到标准检测框,又能保留 Grad-CAM 所需的原始分支。


八、各种热力图方法原理

8.1 EigenCAM

EigenCAM 不依赖梯度,而是对目标层的特征图做主成分分析。

简单理解:

  1. 取某一层输出特征,形状通常为 [C, H, W]
  2. 把每个空间位置看成一个特征向量。
  3. 做 PCA/SVD,取第一主成分。
  4. 第一主成分响应强的位置,就是热力图高亮区域。

优点:

  1. 不需要反向传播。
  2. 对端到端检测模型更稳定。
  3. 不容易因为梯度消失而变成空图。
  4. 适合作为默认可视化方法。

缺点:

  1. 不严格针对某一个类别。
  2. 更像"这一层整体特征响应",不是完全类别判别解释。

适合场景:

  1. YOLO26 这类检测模型的通用可视化。
  2. 梯度类 CAM 不稳定时。
  3. 论文展示模型关注区域。

8.2 Grad-CAM

Grad-CAM 的核心思想是:某个通道对目标类别越重要,它的梯度权重越大。

计算过程:

  1. 选择目标层特征图 A
  2. 选择目标分数 y,例如某类检测 logits。
  3. 计算 yA 的梯度。
  4. 对梯度做全局平均池化,得到每个通道权重。
  5. 用权重加权特征图,再 ReLU,得到热力图。

公式可以简化理解为:

text 复制代码
weight_k = mean(dy / dA_k)
CAM = ReLU(sum(weight_k * A_k))

优点:

  1. 类别相关性更强。
  2. 是经典方法,论文接受度高。
  3. 容易解释"这个类别为什么被预测出来"。

缺点:

  1. 依赖梯度。
  2. 检测模型中目标分数选择比较麻烦。
  3. 对多实例、小目标、密集目标有时不够细。

适合场景:

  1. 解释某一个类别的预测依据。
  2. 做改进前后类别响应对比。

8.3 Grad-CAM++

Grad-CAM++ 是 Grad-CAM 的增强版本,使用更高阶的梯度项,对多目标、多实例场景更友好。

优点:

  1. 多实例定位通常比 Grad-CAM 更细。
  2. 小目标或多个同类目标时更容易看到多个响应点。
  3. 适合密集检测场景。

缺点:

  1. 对梯度质量要求更高。
  2. 计算比 Grad-CAM 稍复杂。
  3. 在某些模型上可能出现噪声点更多。

适合场景:

  1. 一张图中有多个同类目标。
  2. 人群、车辆、遥感小目标、工业缺陷多目标检测。

8.4 XGrad-CAM

XGrad-CAM 可以理解为对 Grad-CAM 权重计算方式的改进。它用激活归一化后的梯度权重,让梯度和激活之间的关系更平衡。

优点:

  1. 有时比 Grad-CAM 更能保留空间细节。
  2. 对激活强度差异较大的层更友好。
  3. 适合和 Grad-CAM、Grad-CAM++ 一起做对比。

缺点:

  1. 不一定每个数据集都优于 Grad-CAM。
  2. 对目标层选择仍然敏感。

8.5 检测框密度热力图

检测框密度图不是 CAM。它不是模型中间特征解释,而是根据检测框位置和置信度画出的空间分布图。

脚本实现方式:

  1. 对每个检测框取中心点。
  2. 根据检测框宽高生成一个高斯核。
  3. 用置信度作为权重叠加。
  4. 得到目标分布密度图。

优点:

  1. 非常直观。
  2. 适合展示检测结果集中区域。
  3. 适合视频监控、客流分析、交通流量、工业缺陷分布。

缺点:

  1. 它不是模型解释热力图。
  2. 只依赖最终检测框,不反映中间特征。
  3. 如果模型漏检,密度图也不会显示漏检目标。

适合场景:

  1. 业务展示。
  2. 目标分布分析。
  3. 检测框结果统计。
  4. 和 CAM 图形成对照。

九、方法对比总结

方法 是否需要梯度 是否类别相关 是否适合 YOLO26 优点 缺点
EigenCAM 很适合 稳定,不容易空图 类别指向性弱
Grad-CAM 适合 经典,论文常用 对目标分数和层选择敏感
Grad-CAM++ 适合 多目标更细 可能噪声更多
XGrad-CAM 适合 细节更明显 不一定每次更好
检测框密度图 依赖检测类别 适合做对照 直观,适合业务展示 不是模型解释

我的建议:

  1. 论文主图优先用 EigenCAM + Grad-CAM++。
  2. 如果要解释类别判别,用 Grad-CAM 或 XGrad-CAM。
  3. 如果要展示目标分布,用检测框密度图。
  4. 如果你不知道选哪一层,先用 TARGET_LAYER = "auto"
  5. 如果你要做消融,固定同一张图、同一层、同一方法,再比较改进前后。

十、为什么默认采用三尺度融合?

YOLO 是多尺度检测模型。浅层特征分辨率高,适合小目标;深层特征语义强,适合大目标和全局信息。

本示例中,YOLO26 Detect 头输入了三个尺度:

text 复制代码
model.16
model.19
model.22

单层对比可以看到:

一般来说:

  1. layer16 更偏细节和小目标响应,图会更碎。
  2. layer19 兼顾中尺度目标和局部结构。
  3. layer22 更偏高层语义,区域更平滑。
  4. auto-3scale 将三个层融合,更适合作为默认展示图。

这就是为什么脚本默认不是只选最后一层,而是自动读取 Detect 头的输入层并融合。


十一、论文中怎么写热力图分析?

可以参考下面这段:

为进一步分析模型在目标区域上的关注能力,本文采用热力图可视化方法对 YOLO26 的中间特征响应进行解释。考虑到 YOLO 系列检测头具有多尺度特征输入,本文默认选取 Detect 头前的三个尺度特征层进行融合可视化。实验中对比了 EigenCAM、Grad-CAM、Grad-CAM++、XGrad-CAM 以及基于检测框的密度热力图。结果表明,EigenCAM 能够较稳定地反映模型整体特征响应,Grad-CAM++ 对密集目标区域具有更细粒度的响应,而检测框密度图则更适合展示最终预测框的空间分布。通过热力图可以观察到,模型在目标主体区域具有较高响应,说明检测结果并非仅依赖背景信息。

如果你做了改进模型,可以这样写:

与基线模型相比,改进后的模型在目标区域产生了更集中、更连续的热力响应,背景区域响应有所减弱。这说明所提出模块能够增强目标相关特征表达,降低复杂背景干扰,从而提高检测性能。

如果是小目标任务,可以这样写:

在小目标样本中,基线模型的热力响应较为分散,部分目标区域响应较弱;加入改进模块后,小目标附近的响应强度明显提升,说明模型对细粒度区域的感知能力得到增强。


十二、常见问题

12.1 运行时报错:No module named torch

说明当前 Python 环境没有 PyTorch。

解决:

bash 复制代码
conda activate 你的YOLO环境
python YOLO26Heatmap.py

或者直接指定环境里的 python:

bash 复制代码
C:\Users\D\.conda\envs\yolov12\python.exe YOLO26Heatmap.py

12.2 运行时报错:Could not read image

说明图片路径不对。

检查:

python 复制代码
IMAGE_PATH = ROOT / "test1.jpg"

如果图片不在脚本目录,要写绝对路径:

python 复制代码
IMAGE_PATH = Path(r"D:\your\data\image.jpg")

12.3 没有检测框怎么办?

可以降低置信度:

bash 复制代码
python YOLO26Heatmap.py --conf 0.1

也可以确认模型类别是否和图片匹配。

12.4 Grad-CAM 图很弱或者几乎全蓝怎么办?

这是检测模型里很常见的问题,不一定是脚本错了。

可以尝试:

bash 复制代码
python YOLO26Heatmap.py --layer 16
python YOLO26Heatmap.py --layer 19
python YOLO26Heatmap.py --layer 22

也可以优先使用 EigenCAM:

bash 复制代码
python YOLO26Heatmap.py --methods eigen_cam detection_density

12.5 为什么检测框密度图很漂亮,但文章说它不是 CAM?

因为检测框密度图来自最终检测框,而不是中间特征和梯度。

它能说明"模型最终把目标检测在什么位置",但不能说明"模型内部为什么这样判断"。

如果写论文,建议把它作为辅助图,不要把它当成 Grad-CAM。


十三、完整脚本位置

本文配套脚本已放在:

text 复制代码
D:\Users\D\Desktop\ultralytics26-main6.20\YOLO26Heatmap.py
  1. 路径即用。
  2. 支持多种 CAM 方法。
  3. 支持 YOLO26 端到端输出。
  4. 支持三尺度自动融合。
  5. 自动生成对比图。
  6. 自动保存 metadata。

十四、结语

热力图不是为了让图片看起来更炫,而是为了让实验结果更可解释。

对于 YOLO26 目标检测任务,建议把热力图作为三类分析工具:

  1. 用 EigenCAM 看整体特征响应是否覆盖目标区域。
  2. 用 Grad-CAM++ 或 XGrad-CAM 看类别相关响应是否更集中。
  3. 用检测框密度图看最终预测框的空间分布。

如果是论文实验,建议固定图片、固定方法、固定层,分别对 baseline 和改进模型生成热力图,然后进行并排对比。这样比单独放一张热力图更有说服力。