1️⃣背景介绍:
在深度学习中,卷积神经网络(CNN)和多模态模型通常会生成大量的中间特征图(Feature Map)。这些特征图包含了模型对输入数据的响应信息,是理解模型行为和调试的重要工具。
传统的可视化方法包括:
-
直接绘制灰度图
-
使用 Matplotlib 生成热力图
但当特征图在 GPU 上时,直接使用 Matplotlib 处理可能效率低下。本文将介绍如何利用 OpenCV 在 GPU 上可视化特征图热力图,既高效又直观。
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️⃣ 可视化效果
-
单通道热力图:可看到每个通道的特征响应分布
-
通道平均热力图:显示整体响应区域,突出模型重点关注的区域

8842

被折叠的 条评论
为什么被折叠?



