1️⃣背景介绍:

在深度学习中,卷积神经网络(CNN)和多模态模型通常会生成大量的中间特征图(Feature Map)。这些特征图包含了模型对输入数据的响应信息,是理解模型行为和调试的重要工具。

传统的可视化方法包括:

  • 直接绘制灰度图

  • 使用 Matplotlib 生成热力图

但当特征图在 GPU 上时,直接使用 Matplotlib 处理可能效率低下。本文将介绍如何利用 OpenCV 在 GPU 上可视化特征图热力图,既高效又直观。


2️⃣ 功能说明

本文提供两种可视化方法:

  1. 单通道热力图可视化

    • 对每个通道生成一张热力图

    • 适合观察每个通道的响应分布

    • 支持阈值过滤、大小调整、彩色映射

  2. 通道平均热力图可视化

    • 将所有通道求平均,生成一张整体热力图

    • 适合快速查看特征整体响应区域


3️⃣ 代码解析

3.1 单通道热力图函数

def visualize_heatmap_opencv(feature_map, sample_idx, save_dir, width=16, height=16, output_size=(1000, 880), threshold=0):
    """
    使用 OpenCV 在 GPU 上可视化特征图的热力图。

    参数:
    - feature_map: 4D 张量,形状为 [batch_size, C, H, W],并在 GPU 上
    - sample_idx: 选择要可视化的样本在 batch 中的索引
    - save_dir: 保存热力图的文件目录
    - width: 子图的列数
    - height: 子图的行数
    - threshold: 用于调整热力图的显示阈值
    """
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    # 选择指定样本,形状为 [C, H, W]
    feature_map = feature_map[sample_idx]

    for i in range(width * height):
        if i >= feature_map.size(0):  # 如果通道数少于子图数量,提前结束
            break

        # 在 GPU 上归一化每个特征图
        img = feature_map[i]
        img_min, img_max = img.min(), img.max()

        # 应用阈值调整
        img = torch.where(img < img_min + threshold * (img_max - img_min), img_min + threshold * (img_max - img_min), img)

        # 归一化到0-255范围
        img = ((img - img_min) / (img_max - img_min + 1e-6) * 255).to(torch.uint8)  # 归一化到0-255范围

        # 将图像转为 CPU 后使用 OpenCV 生成热力图
        img = img.cpu().numpy()  # 转到 CPU 并转成 NumPy

        # 使用高斯模糊平滑图像
        img = cv2.GaussianBlur(img, (1, 1), 1.0)

        # 调整热力图尺寸
        img_resized = cv2.resize(img, output_size)  # 调整热力图大小

        img_colormap = cv2.applyColorMap(img_resized, cv2.COLORMAP_HOT)  # 生成彩色热力图

        # 保存热力图
        cv2.imwrite(os.path.join(save_dir, f'feature_{i}.png'), img_colormap)

解析:

  • feature_map[sample_idx]:选择 batch 中的样本

  • torch.where + threshold:忽略低响应区域,提高热力图可读性

  • cv2.applyColorMap:将灰度图转换为彩色热力图

  • cv2.imwrite:保存热力图


3.2 通道平均热力图函数

def visualize_heatmap_opencv_1(feature_map, sample_idx, save_dir, output_size=(1000, 880), threshold=0):
    """
    使用 OpenCV 在 GPU 上可视化特征图的热力图(将所有通道取平均生成一张图像)。

    参数:
    - feature_map: 4D 张量,形状为 [batch_size, C, H, W],并在 GPU 上
    - sample_idx: 选择要可视化的样本在 batch 中的索引
    - save_dir: 保存热力图的文件目录
    - threshold: 用于调整热力图的显示阈值
    """
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    # 选择指定样本,形状为 [C, H, W]
    feature_map = feature_map[sample_idx]

    # 对通道进行平均,生成 [H, W] 的单张图像
    avg_feature_map = feature_map.mean(dim=0)  # 在通道维度上求平均

    # 在 GPU 上归一化
    img_min, img_max = avg_feature_map.min(), avg_feature_map.max()

    # 应用阈值调整
    avg_feature_map = torch.where(
        avg_feature_map < img_min + threshold * (img_max - img_min),
        img_min + threshold * (img_max - img_min),
        avg_feature_map
    )

    # 归一化到0-255范围
    img = ((avg_feature_map - img_min) / (img_max - img_min + 1e-6) * 255).to(torch.uint8)

    # 将图像转为 CPU 后使用 OpenCV 生成热力图
    img = img.cpu().numpy()  # 转到 CPU 并转成 NumPy

    # 使用高斯模糊平滑图像
    img = cv2.GaussianBlur(img, (3, 3), 0)

    # 调整热力图尺寸
    img_resized = cv2.resize(img, output_size)  # 调整热力图大小

    # 生成彩色热力图
    img_colormap = cv2.applyColorMap(img_resized, cv2.COLORMAP_HOT)

    # 保存热力图
    cv2.imwrite(os.path.join(save_dir, 'average_feature_heatmap.png'), img_colormap)

解析:

  • feature_map.mean(dim=0):对所有通道取平均

  • 生成一张综合热力图,快速观察模型对输入的响应热点


4️⃣ 可视化效果

  • 单通道热力图:可看到每个通道的特征响应分布

  • 通道平均热力图:显示整体响应区域,突出模型重点关注的区域​​​​​​

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐