如何可视化Keras注意力模型attention_weights层分析日期预测注意力分布
我来帮你梳理下怎么实现这个注意力权重的可视化,刚好我之前做过类似的日期格式化任务,思路应该能帮到你~
可视化日期格式化模型的注意力权重
先明确下你的任务背景:
- 模型输入:最长30字符的模糊日期(比如
Saturday, 17th November, 1979) - 模型输出:固定10字符的
YYYY-mm-dd格式日期 - 核心需求:绘制
attention_weights层的数值,观察模型预测YYYY/mm/dd各部分时对输入的关注区域,验证是否会忽略星期这类无关内容
1. 提取注意力权重
首先得在模型推理时把attention_weights层的输出保存下来,这里分两种主流框架给出实现思路:
TensorFlow/Keras
如果是Keras搭建的模型,你可以创建一个专门的"注意力提取模型",直接输出目标层的结果:
from tensorflow.keras.models import Model # 假设原始模型为model,attention_weights层的名称是'attention_weights' attention_extractor = Model(inputs=model.input, outputs=model.get_layer('attention_weights').output) # 预处理测试输入(要和训练时的预处理逻辑一致,比如转字符索引) test_input = ["Saturday, 17th November, 1979"] processed_input = your_preprocess_function(test_input) # 获取注意力权重 attention_weights = attention_extractor.predict(processed_input)
PyTorch
PyTorch可以通过注册前向钩子来获取目标层的输出:
import torch # 加载你的模型并设为评估模式 model = YourDateFormatModel() model.eval() # 定义钩子函数保存注意力权重 attention_weights = None def attention_hook(module, input, output): global attention_weights attention_weights = output.detach().cpu().numpy() # 给attention_weights层注册钩子 model.attention_weights.register_forward_hook(attention_hook) # 预处理输入并推理 test_input = your_preprocess_function(["Saturday, 17th November, 1979"]) with torch.no_grad(): model(test_input) # 此时attention_weights就是当前样本的注意力权重矩阵
2. 对齐输入字符与权重
把输入字符串拆分成单个字符,和注意力权重的维度对应上。比如输入Saturday, 17th November, 1979拆成:['S','a','t','u','r','d','a','y',',',' ','1','7','t','h',' ','N','o','v','e','m','b','e','r',',',' ','1','9','7','9']
你的输出是10字符的YYYY-mm-dd,所以注意力权重通常是[10, 输入字符数]的二维矩阵——每个输出位置对应输入所有字符的关注程度。
3. 绘制注意力热力图
用Matplotlib或Seaborn绘制热力图,直观展示注意力分布:
import matplotlib.pyplot as plt import seaborn as sns # 输入字符列表 input_chars = list("Saturday, 17th November, 1979") # 输出位置标签,对应YYYY-mm-dd的每个字符 output_labels = list("YYYY-mm-dd") # 绘制热力图 plt.figure(figsize=(14, 6)) sns.heatmap(attention_weights, xticklabels=input_chars, yticklabels=output_labels, cmap='Blues', annot=True, fmt='.2f', cbar=True) plt.xlabel('Input Characters') plt.ylabel('Output Positions (YYYY-mm-dd)') plt.title('Attention Weights Distribution for Date Formatting') plt.xticks(rotation=45) plt.tight_layout() plt.show()
4. 验证预期结果
从热力图里你应该能看到符合预期的规律:
- 输出
YYYY对应的前4个位置,注意力会高度集中在输入的1979部分 - 输出
mm对应的第6-7个位置,注意力会集中在November(或月份相关的字符) - 输出
dd对应的第9-10个位置,注意力会集中在17部分 - 输入里的
Saturday,这类星期相关字符,对应的注意力权重会非常低,模型确实会自动忽略这些无关内容
如果你的模型用了多头注意力,可以拆分每个头的权重分别绘制,能看到不同注意力头可能侧重关注输入的不同区域,更细致地分析模型行为。
内容的提问来源于stack exchange,提问作者opyate
相关产品推荐
相关产品推荐

