You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Transformer的视觉-语言模型:输入重要区域可视化问询

关于Transformer模型输入关键区域可视化的建议

你的判断不正确,ViTSelfOutput的Linear层(dense)是对注意力聚合后的特征做线性投影,它的权重无法直接对应输入图像的关键区域。要定位输入中对预测重要的部分,核心是可视化ViTSelfAttention层生成的注意力权重,以下是具体说明和建议:

一、核心可视化目标:ViTSelfAttention的注意力权重

ViTSelfAttention层计算时会生成形状为[batch_size, num_heads, num_patches, num_patches]的注意力权重矩阵(num_patches是图像分块数量,若包含CLS token需注意索引):

  • 若关注**全局预测(如分类)**对应的图像区域:提取每个注意力头中CLS token对应的行(通常CLS token是第一个patch,对应索引0,即取[:, :, 0, 1:]),将这些权重映射回原图像的patch位置,就能得到模型重点关注的区域。
  • 若关注解码器生成的具体文本token对应的图像区域:提取解码器对编码器输出的交叉注意力权重,同样映射到图像patch上,可看到生成该文本时模型关注的图像部分。

二、辅助可视化方向

  • 单注意力头的模式差异:每个注意力头可能学习到不同的视觉模式(比如有的关注边缘、有的关注物体纹理),单独可视化每个头的注意力分布,能发现模型的多样化关注点;也可以对所有头的权重取平均,观察整体关注趋势。
  • 不同层的注意力演化:ViT的浅层通常关注局部细节,深层更偏向全局语义信息,对比不同层的注意力分布,能理解模型从细节到整体的特征提取过程。

三、避坑提醒:不要可视化线性层权重

诸如ViTSelfOutput的dense、ViTIntermediate的dense这类线性层,它们的权重是高维特征空间的投影参数,没有直接的图像空间对应关系,可视化这些权重无法得到有意义的区域指向性。

四、PyTorch中提取注意力权重的示例

修改ViTSelfAttention类,在推理时保存注意力权重:

import torch
import torch.nn as nn
import math

class ViTSelfAttention(nn.Module):
    def __init__(self, in_features=768, head_dim=64):
        super().__init__()
        self.query = nn.Linear(in_features, in_features, bias=False)
        self.key = nn.Linear(in_features, in_features, bias=False)
        self.value = nn.Linear(in_features, in_features, bias=False)
        self.dropout = nn.Dropout(p=0.0)
        self.num_heads = in_features // head_dim
        self.head_dim = head_dim
        # 添加保存开关
        self.save_attn_weights = True
        self.attn_weights = None

    def forward(self, hidden_states):
        batch_size, seq_len, _ = hidden_states.size()
        # 拆分多头
        query = self.query(hidden_states).view(batch_size, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
        key = self.key(hidden_states).view(batch_size, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
        value = self.value(hidden_states).view(batch_size, seq_len, self.num_heads, self.head_dim).transpose(1, 2)

        # 计算注意力得分与权重
        attn_scores = torch.matmul(query, key.transpose(-1, -2)) / math.sqrt(self.head_dim)
        attn_probs = nn.functional.softmax(attn_scores, dim=-1)
        attn_probs = self.dropout(attn_probs)

        # 保存权重
        if self.save_attn_weights:
            self.attn_weights = attn_probs.detach()

        # 计算输出
        output = torch.matmul(attn_probs, value).transpose(1, 2).contiguous().view(batch_size, seq_len, -1)
        return output

推理时,取出指定层的注意力权重:

# 假设model是你的完整模型
model.eval()
with torch.no_grad():
    outputs = model(input_image)
# 提取第0层ViTSelfAttention的注意力权重
attn_weights = model.encoder.layers[0].attention.attention.attn_weights

之后可根据图像patch的尺寸(比如224x224图像分16x16patch,每个patch14x14像素),将权重映射回原图像尺寸,用热力图可视化。

内容的提问来源于stack exchange,提问作者sr__

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 08:25:31