一、注意力机制的由来与解决的问题1. 传统Seq2Seq模型的局限性在早期的机器翻译任务中通常采用Encoder-Decoder架构传统架构的问题问题1长序列瓶颈输入序列过长时固定长度的中间语义向量C无法存储所有信息导致长句子翻译准确率严重下降问题2语义模糊性无法处理一词多义现象同一单词在不同语境下没有区分度所有输入词对输出的贡献相同问题3信息丢失RNN类模型随着时间步增长早期信息逐渐被遗忘2. 注意力机制的提出2014年Bahdanau等人在机器翻译任务中首次将注意力机制引入NLP领域模拟人类视觉注意力机制——让机器学会聚焦重要信息忽略次要信息。核心思想在生成每个目标词时动态地关注源序列中相关的部分分配不同的注意力权重。这里可以理解为:编码器source,解码器target,target中目标单词对source每个单词的加权求和,然后我们的sofrmax(加权求和)就是source中对应的权重,代表着source中每个单词对target中目标单词的重要程度,source中通过加权求和全民投票,决定谁对target最重要二、注意力机制的本质与数学原理1. 三要素定义Q (Query - 查询向量)代表当前需要关注的内容如解码器当前步的状态K (Key - 键向量)代表被关注项的索引或提示信息如编码器各时间步的输出V (Value - 值向量)代表被关注项的实际内容通常与K相同或相关2. 本质思想公式Attention(Q, K, V) ∑(相似度(Q, K_i) × V_i)即通过Q与K的相似度作为权重对V进行加权求和3. 计算三阶段核心流程图阶段1Q与K计算相似度 → 阶段2Softmax归一化 → 阶段3加权求和得结果详细步骤相似度计算score F(Q, K)F可以是点积、拼接、加性等权重归一化α softmax(score)得到概率分布加权求和context ∑ α_i × V_i得到注意力输出4. 搜索引擎类比Query用户输入的搜索词Key文章的标题索引信息Value文章的全文内容过程用Query匹配Key得到相关性得分 → 筛选出相关文章 → 融合文章内容返回结果三、注意力机制的详细分类1. 按关注范围分类1软注意力Soft/Global Attention⭐最常见特点权重∈[0,1]对所有输入项都考虑但关注程度不同优点可微分可端到端训练缺点计算量大需计算所有位置2硬注意力Hard/Local Attention特点权重∈{0,1}0或1只选择部分输入项忽略其他实现方式取最大权重位置离散选择随机采样缺点不可导需用强化学习训练应用图像识别中的区域选择2. 按计算对象分类3自注意力Self/Intra Attention⭐Transformer核心定义QKV即同一序列内部元素之间的注意力优势并行计算无需像RNN那样逐步计算长距离依赖任意两个token直接建立联系无信息损耗全局感受野每个位置都能看到整个序列示例句子The animal didnt cross the street becauseitwas too tired自注意力能直接建立it与animal的指代关系3. 按计算方式分类4拼接5乘性注意力Multiplicative/点积 AttentionLuong等人提出计算效率高缩放因子√d_k防止点积结果过大导致softmax梯度消失四、注意力计算规则的数学表达1. 三种主流计算规则规则公式特点拼接线性Softmax(Linear([Q,K]))·V简单直观拼接tanhSoftmax(sum(tanh(Linear([Q,K]))))·V非线性增强(不常用)缩放点积Softmax(Q·K^T/√d_k)·V最常用效率高2. 缩放点积注意力的优势计算效率矩阵乘法并行优化梯度稳定除以√d_k控制方差3. 批处理运算bmm当处理批次数据时使用批量矩阵乘法batch matrix multiplication# 如果参数1形状是(b × n × m), 参数2形状是(b × m × p), 则输出为(b × n × p) input torch.randn(10, 3, 4) mat2 torch.randn(10, 4, 5) res torch.bmm(input, mat2) res.size() torch.Size([10, 3, 5])五、注意力机制在Seq2Seq中的应用1. 两种实现架构对比TensorFlow传统方式加性注意力Q解码器上一时间步的隐藏状态K/V编码器所有时间步的输出特点计算复杂但能处理不同维度PyTorch改进方式乘性注意力Q解码器当前步的输入如当前词嵌入K解码器上一步的隐藏状态V编码器所有时间步的输出特点计算简单效率更高2. 注意力机制在解码器中的作用# 生成目标词to时的注意力计算 1. Q 当前词welcome的嵌入向量 2. K 解码器上一隐藏状态 3. V 编码器对欢迎 来 北京的输出 4. 计算注意力权重 → 得到上下文向量 5. 拼接Q和上下文向量 → 预测to六、注意力机制的实现步骤与代码1. 完整代码实现带详细注释# -*-coding:utf-8-*- Q torch.randn((1, 1, 32)) K torch.randn((1, 1, 32)) V torch.randn((1, 32, 64)) 公式:Softmax(Linear([Q,K]))·V 注意力机制实现步骤: 第一步: 根据注意力计算规则, 对QKV进行相应的计算. 第二步: 根据第一步采用的计算方法, 如果是拼接方法则需要将Q与第二步的计算结果再进行拼接, 如果是转置点积, 一般是自注意力, Q与V相同, 则不需要进行与Q的拼接. 第三步: 最后为了使整个attention机制按照指定尺寸输出, 使用线性层作用在第二步的结果上做一个线性变换, 得到最终对Q的注意力表示. import torch import torch.nn as nn import torch.nn.functional as F # todo进行按照第一种规则实现注意力的计算按照讲义降维升维 class MyAttention(nn.Module): def __init__(self, query_size, key_size, value_size1, value_size2, output_size): super().__init__() # query_size:Q张量的最后一个维度 self.query_size query_size # key_size:K张量的最后一个维度 self.key_size key_size # value_size1:V张量的中间的维度 self.value_size1 value_size1 # value_size2:V张量的最后一个维度 self.value_size2 value_size2 # output_size:注意力指定最后输出维度 self. output_size output_size # 定义第一个全连接层计算注意力的权重值 # 输入特征注意Q和k要进行拼接然后在输入Q--[1, 1, 32],K--[1, 1, 32]--[1,1,64] # 输出特征注意因为Linear之后的结果要和V--》[1, 32, 64],所以输出的维度一定是32 self.att_weight nn.Linear(query_sizekey_size, value_size1) # 定义第二个全连接层计算最终的注意力结果 # 输入特征注意Q和第一步计算的结果要进行拼接然后在输入Q--[1, 1, 32],步骤1--[1, 1, 64]--[1,1,96] # 输出特征指定的输出output_size self.out nn.Linear(query_sizevalue_size2, output_size) def forward(self, Q, K, V): # Q--》shape--[1, 1, 32], K--》shape--[1, 1, 32], V--》shape--[1, 32, 64] # 按照注意力计算的步骤三步走开始实现注意力的运算 # 第一步按照第一种注意力计算规则来实现Q\KV的运算 # 1.1 将Q和K进行拼接;经过Linear得到权重 # Q[0]--[1, 32];K[0]--[1, 32]--concat--[1, 64] # concat--[1, 64]经过linear得到结果--》[1, 32] atten_weight F.softmax(self.att_weight(torch.cat((Q[0], K[0]), dim-1)), dim-1) # print(fatten_weight--》{atten_weight.shape}) # 1.2 将得到权重和V进行矩阵相乘 # atten_weight--[1, 32]--升维--[1, 1, 32], V--》[1, 32, 64] # temp_result --[1, 1, 64] temp_result torch.bmm(atten_weight.unsqueeze(dim0), V) # 第二步将Q和第一步计算的结果temp_result进行拼接 # Q[0]--[1, 32];temp_result[0]--[1, 64]--concat--[1, 96] cat_tensor torch.cat((Q[0], temp_result[0]), dim-1) # print(fcat_tensor--{cat_tensor.shape}) # 第三步将第二步拼接之后的结果按照指定尺寸输出 output self.out(cat_tensor).unsqueeze(dim0) # print(output.shape) return output, atten_weight # todo进行按照第一种规则实现注意力的计算不进行降维升维 class OriginalAttention(nn.Module): def __init__(self, query_size, key_size, value_size1, value_size2, output_size): super().__init__() # query_size:Q张量的最后一个维度 self.query_size query_size # key_size:K张量的最后一个维度 self.key_size key_size # value_size1:V张量的中间的维度 self.value_size1 value_size1 # value_size2:V张量的最后一个维度 self.value_size2 value_size2 # output_size:注意力指定最后输出维度 self. output_size output_size # 定义第一个全连接层计算注意力的权重值 # 输入特征注意Q和k要进行拼接然后在输入Q--[1, 1, 32],K--[1, 1, 32]--[1,1,64] # 输出特征注意因为Linear之后的结果要和V--》[1, 32, 64],所以输出的维度一定是32 self.att_weight nn.Linear(query_sizekey_size, value_size1) # 定义第二个全连接层计算最终的注意力结果 # 输入特征注意Q和第一步计算的结果要进行拼接然后在输入Q--[1, 1, 32],步骤1--[1, 1, 64]--[1,1,96] # 输出特征指定的输出output_size self.out nn.Linear(query_sizevalue_size2, output_size) def forward(self, Q, K, V): # Q--》shape--[1, 1, 32], K--》shape--[1, 1, 32], V--》shape--[1, 32, 64] # 按照注意力计算的步骤三步走开始实现注意力的运算 # 第一步按照第一种注意力计算规则来实现Q\KV的运算 # 1.1 将Q和K进行拼接;经过Linear得到权重 # Q--[1, 1, 32];K[0]--[1, 1, 32]--concat--[1,1, 64] # concat--[1, 1, 64]经过linear得到结果--》[1, 1, 32] atten_weight F.softmax(self.att_weight(torch.cat((Q, K), dim-1)), dim-1) # print(fatten_weight--》{atten_weight.shape}) # 1.2 将得到权重和V进行矩阵相乘 # atten_weight--[1, 1, 32], V--》[1, 32, 64] # temp_result --[1, 1, 64] temp_result torch.bmm(atten_weight, V) # 第二步将Q和第一步计算的结果temp_result进行拼接 # Q-[1, 1, 32];temp_result---[1,1, 64]--concat--[1, 1, 96] cat_tensor torch.cat((Q, temp_result), dim-1) # print(fcat_tensor--{cat_tensor.shape}) # 第三步将第二步拼接之后的结果按照指定尺寸输出 output self.out(cat_tensor) # print(output.shape) return output, atten_weight if __name__ __main__: query_size 32 key_size 32 value_size1 32 value_size2 64 output_size 32 my_atten1 MyAttention(query_size, key_size, value_size1, value_size2, output_size) print(my_atten1) Q torch.randn((1, 1, 32)) K torch.randn((1, 1, 32)) V torch.randn((1, 32, 64)) output1, atten_weight1 my_atten1(Q, K, V) print(foutput1--》{output1.shape}) print(fatten_weight1--》{atten_weight1.shape}) my_atten2 OriginalAttention(query_size, key_size, value_size1, value_size2, output_size) output, atten_weight my_atten2(Q, K, V) print(foutput--》{output.shape}) print(fatten_weight--》{atten_weight.shape})七、自注意力机制详解1. 为什么需要自注意力RNN/LSTM的局限顺序计算无法并行长距离信息衰减梯度消失/爆炸自注意力的优势并行计算所有位置同时计算全局连接任意两个位置直接相连计算复杂度O(n²·d) vs RNN的O(n·d²)2. 自注意力的计算过程假设输入序列 X [x1, x2, ..., xn] 1. 生成Q、K、V通过三个不同的线性变换 Q X·W_Q, K X·W_K, V X·W_V 2. 计算注意力分数 scores Q·K^T / √d_k 3. 权重归一化 attn softmax(scores) 4. 输出 output attn·V3. 多头注意力Multi-Head Attention思想从多个角度关注信息类似CNN的多通道实现将Q、K、V切分为h个头分别计算注意力再拼接head_i Attention(Q·W_i^Q, K·W_i^K, V·W_i^V) MultiHead Concat(head_1,...,head_h)·W_O八、注意力机制的作用总结1. 在解码器端动态聚焦生成每个词时关注源序列的不同部分信息选择从编码器输出中提取最相关信息对齐建模学习源语言和目标语言的词对齐关系2. 在编码器端特征增强通过自注意力强化重要特征上下文建模每个词包含全局上下文信息长距离依赖直接捕获远距离词间关系3. 通用作用可解释性注意力权重可解释模型关注点灵活性可应用于CNN、RNN、Transformer任意架构信息瓶颈突破打破固定长度向量的限制九、常见问题与解答Q1: Q、K、V维度必须相同吗A不一定。在加性注意力中可以不同在点积注意力中Q和K的最后一维需相同为了点积V的维度可不同。Q2: 为什么要除以√d_kA当d_k较大时点积结果方差变大softmax进入饱和区梯度极小。缩放后控制方差为1稳定梯度。Q3: 自注意力和一般注意力的区别A自注意力是QKV的特例用于建模序列内部关系一般注意力是Q与K、V来自不同序列用于建模序列间关系。Q4: 注意力机制有参数吗A有。计算Q、K、V的线性变换矩阵是参数计算相似度的网络也可能有参数如加性注意力中的W_q、W_k、v。十、经典案例seq2seq英法互译 待完善 十一、注意力机制的来时路2014Bahdanau提出NLP注意力机器翻译 2015Luong提出全局/局部注意力 2016自注意力在阅读理解任务中应用 2017Transformer提出多头自注意力成为主流 2018BERT、GPT等预训练模型全面采用注意力 至今注意力机制已成为NLP/CV/多模态的标准组件
详解注意力机制的前世今生
一、注意力机制的由来与解决的问题1. 传统Seq2Seq模型的局限性在早期的机器翻译任务中通常采用Encoder-Decoder架构传统架构的问题问题1长序列瓶颈输入序列过长时固定长度的中间语义向量C无法存储所有信息导致长句子翻译准确率严重下降问题2语义模糊性无法处理一词多义现象同一单词在不同语境下没有区分度所有输入词对输出的贡献相同问题3信息丢失RNN类模型随着时间步增长早期信息逐渐被遗忘2. 注意力机制的提出2014年Bahdanau等人在机器翻译任务中首次将注意力机制引入NLP领域模拟人类视觉注意力机制——让机器学会聚焦重要信息忽略次要信息。核心思想在生成每个目标词时动态地关注源序列中相关的部分分配不同的注意力权重。这里可以理解为:编码器source,解码器target,target中目标单词对source每个单词的加权求和,然后我们的sofrmax(加权求和)就是source中对应的权重,代表着source中每个单词对target中目标单词的重要程度,source中通过加权求和全民投票,决定谁对target最重要二、注意力机制的本质与数学原理1. 三要素定义Q (Query - 查询向量)代表当前需要关注的内容如解码器当前步的状态K (Key - 键向量)代表被关注项的索引或提示信息如编码器各时间步的输出V (Value - 值向量)代表被关注项的实际内容通常与K相同或相关2. 本质思想公式Attention(Q, K, V) ∑(相似度(Q, K_i) × V_i)即通过Q与K的相似度作为权重对V进行加权求和3. 计算三阶段核心流程图阶段1Q与K计算相似度 → 阶段2Softmax归一化 → 阶段3加权求和得结果详细步骤相似度计算score F(Q, K)F可以是点积、拼接、加性等权重归一化α softmax(score)得到概率分布加权求和context ∑ α_i × V_i得到注意力输出4. 搜索引擎类比Query用户输入的搜索词Key文章的标题索引信息Value文章的全文内容过程用Query匹配Key得到相关性得分 → 筛选出相关文章 → 融合文章内容返回结果三、注意力机制的详细分类1. 按关注范围分类1软注意力Soft/Global Attention⭐最常见特点权重∈[0,1]对所有输入项都考虑但关注程度不同优点可微分可端到端训练缺点计算量大需计算所有位置2硬注意力Hard/Local Attention特点权重∈{0,1}0或1只选择部分输入项忽略其他实现方式取最大权重位置离散选择随机采样缺点不可导需用强化学习训练应用图像识别中的区域选择2. 按计算对象分类3自注意力Self/Intra Attention⭐Transformer核心定义QKV即同一序列内部元素之间的注意力优势并行计算无需像RNN那样逐步计算长距离依赖任意两个token直接建立联系无信息损耗全局感受野每个位置都能看到整个序列示例句子The animal didnt cross the street becauseitwas too tired自注意力能直接建立it与animal的指代关系3. 按计算方式分类4拼接5乘性注意力Multiplicative/点积 AttentionLuong等人提出计算效率高缩放因子√d_k防止点积结果过大导致softmax梯度消失四、注意力计算规则的数学表达1. 三种主流计算规则规则公式特点拼接线性Softmax(Linear([Q,K]))·V简单直观拼接tanhSoftmax(sum(tanh(Linear([Q,K]))))·V非线性增强(不常用)缩放点积Softmax(Q·K^T/√d_k)·V最常用效率高2. 缩放点积注意力的优势计算效率矩阵乘法并行优化梯度稳定除以√d_k控制方差3. 批处理运算bmm当处理批次数据时使用批量矩阵乘法batch matrix multiplication# 如果参数1形状是(b × n × m), 参数2形状是(b × m × p), 则输出为(b × n × p) input torch.randn(10, 3, 4) mat2 torch.randn(10, 4, 5) res torch.bmm(input, mat2) res.size() torch.Size([10, 3, 5])五、注意力机制在Seq2Seq中的应用1. 两种实现架构对比TensorFlow传统方式加性注意力Q解码器上一时间步的隐藏状态K/V编码器所有时间步的输出特点计算复杂但能处理不同维度PyTorch改进方式乘性注意力Q解码器当前步的输入如当前词嵌入K解码器上一步的隐藏状态V编码器所有时间步的输出特点计算简单效率更高2. 注意力机制在解码器中的作用# 生成目标词to时的注意力计算 1. Q 当前词welcome的嵌入向量 2. K 解码器上一隐藏状态 3. V 编码器对欢迎 来 北京的输出 4. 计算注意力权重 → 得到上下文向量 5. 拼接Q和上下文向量 → 预测to六、注意力机制的实现步骤与代码1. 完整代码实现带详细注释# -*-coding:utf-8-*- Q torch.randn((1, 1, 32)) K torch.randn((1, 1, 32)) V torch.randn((1, 32, 64)) 公式:Softmax(Linear([Q,K]))·V 注意力机制实现步骤: 第一步: 根据注意力计算规则, 对QKV进行相应的计算. 第二步: 根据第一步采用的计算方法, 如果是拼接方法则需要将Q与第二步的计算结果再进行拼接, 如果是转置点积, 一般是自注意力, Q与V相同, 则不需要进行与Q的拼接. 第三步: 最后为了使整个attention机制按照指定尺寸输出, 使用线性层作用在第二步的结果上做一个线性变换, 得到最终对Q的注意力表示. import torch import torch.nn as nn import torch.nn.functional as F # todo进行按照第一种规则实现注意力的计算按照讲义降维升维 class MyAttention(nn.Module): def __init__(self, query_size, key_size, value_size1, value_size2, output_size): super().__init__() # query_size:Q张量的最后一个维度 self.query_size query_size # key_size:K张量的最后一个维度 self.key_size key_size # value_size1:V张量的中间的维度 self.value_size1 value_size1 # value_size2:V张量的最后一个维度 self.value_size2 value_size2 # output_size:注意力指定最后输出维度 self. output_size output_size # 定义第一个全连接层计算注意力的权重值 # 输入特征注意Q和k要进行拼接然后在输入Q--[1, 1, 32],K--[1, 1, 32]--[1,1,64] # 输出特征注意因为Linear之后的结果要和V--》[1, 32, 64],所以输出的维度一定是32 self.att_weight nn.Linear(query_sizekey_size, value_size1) # 定义第二个全连接层计算最终的注意力结果 # 输入特征注意Q和第一步计算的结果要进行拼接然后在输入Q--[1, 1, 32],步骤1--[1, 1, 64]--[1,1,96] # 输出特征指定的输出output_size self.out nn.Linear(query_sizevalue_size2, output_size) def forward(self, Q, K, V): # Q--》shape--[1, 1, 32], K--》shape--[1, 1, 32], V--》shape--[1, 32, 64] # 按照注意力计算的步骤三步走开始实现注意力的运算 # 第一步按照第一种注意力计算规则来实现Q\KV的运算 # 1.1 将Q和K进行拼接;经过Linear得到权重 # Q[0]--[1, 32];K[0]--[1, 32]--concat--[1, 64] # concat--[1, 64]经过linear得到结果--》[1, 32] atten_weight F.softmax(self.att_weight(torch.cat((Q[0], K[0]), dim-1)), dim-1) # print(fatten_weight--》{atten_weight.shape}) # 1.2 将得到权重和V进行矩阵相乘 # atten_weight--[1, 32]--升维--[1, 1, 32], V--》[1, 32, 64] # temp_result --[1, 1, 64] temp_result torch.bmm(atten_weight.unsqueeze(dim0), V) # 第二步将Q和第一步计算的结果temp_result进行拼接 # Q[0]--[1, 32];temp_result[0]--[1, 64]--concat--[1, 96] cat_tensor torch.cat((Q[0], temp_result[0]), dim-1) # print(fcat_tensor--{cat_tensor.shape}) # 第三步将第二步拼接之后的结果按照指定尺寸输出 output self.out(cat_tensor).unsqueeze(dim0) # print(output.shape) return output, atten_weight # todo进行按照第一种规则实现注意力的计算不进行降维升维 class OriginalAttention(nn.Module): def __init__(self, query_size, key_size, value_size1, value_size2, output_size): super().__init__() # query_size:Q张量的最后一个维度 self.query_size query_size # key_size:K张量的最后一个维度 self.key_size key_size # value_size1:V张量的中间的维度 self.value_size1 value_size1 # value_size2:V张量的最后一个维度 self.value_size2 value_size2 # output_size:注意力指定最后输出维度 self. output_size output_size # 定义第一个全连接层计算注意力的权重值 # 输入特征注意Q和k要进行拼接然后在输入Q--[1, 1, 32],K--[1, 1, 32]--[1,1,64] # 输出特征注意因为Linear之后的结果要和V--》[1, 32, 64],所以输出的维度一定是32 self.att_weight nn.Linear(query_sizekey_size, value_size1) # 定义第二个全连接层计算最终的注意力结果 # 输入特征注意Q和第一步计算的结果要进行拼接然后在输入Q--[1, 1, 32],步骤1--[1, 1, 64]--[1,1,96] # 输出特征指定的输出output_size self.out nn.Linear(query_sizevalue_size2, output_size) def forward(self, Q, K, V): # Q--》shape--[1, 1, 32], K--》shape--[1, 1, 32], V--》shape--[1, 32, 64] # 按照注意力计算的步骤三步走开始实现注意力的运算 # 第一步按照第一种注意力计算规则来实现Q\KV的运算 # 1.1 将Q和K进行拼接;经过Linear得到权重 # Q--[1, 1, 32];K[0]--[1, 1, 32]--concat--[1,1, 64] # concat--[1, 1, 64]经过linear得到结果--》[1, 1, 32] atten_weight F.softmax(self.att_weight(torch.cat((Q, K), dim-1)), dim-1) # print(fatten_weight--》{atten_weight.shape}) # 1.2 将得到权重和V进行矩阵相乘 # atten_weight--[1, 1, 32], V--》[1, 32, 64] # temp_result --[1, 1, 64] temp_result torch.bmm(atten_weight, V) # 第二步将Q和第一步计算的结果temp_result进行拼接 # Q-[1, 1, 32];temp_result---[1,1, 64]--concat--[1, 1, 96] cat_tensor torch.cat((Q, temp_result), dim-1) # print(fcat_tensor--{cat_tensor.shape}) # 第三步将第二步拼接之后的结果按照指定尺寸输出 output self.out(cat_tensor) # print(output.shape) return output, atten_weight if __name__ __main__: query_size 32 key_size 32 value_size1 32 value_size2 64 output_size 32 my_atten1 MyAttention(query_size, key_size, value_size1, value_size2, output_size) print(my_atten1) Q torch.randn((1, 1, 32)) K torch.randn((1, 1, 32)) V torch.randn((1, 32, 64)) output1, atten_weight1 my_atten1(Q, K, V) print(foutput1--》{output1.shape}) print(fatten_weight1--》{atten_weight1.shape}) my_atten2 OriginalAttention(query_size, key_size, value_size1, value_size2, output_size) output, atten_weight my_atten2(Q, K, V) print(foutput--》{output.shape}) print(fatten_weight--》{atten_weight.shape})七、自注意力机制详解1. 为什么需要自注意力RNN/LSTM的局限顺序计算无法并行长距离信息衰减梯度消失/爆炸自注意力的优势并行计算所有位置同时计算全局连接任意两个位置直接相连计算复杂度O(n²·d) vs RNN的O(n·d²)2. 自注意力的计算过程假设输入序列 X [x1, x2, ..., xn] 1. 生成Q、K、V通过三个不同的线性变换 Q X·W_Q, K X·W_K, V X·W_V 2. 计算注意力分数 scores Q·K^T / √d_k 3. 权重归一化 attn softmax(scores) 4. 输出 output attn·V3. 多头注意力Multi-Head Attention思想从多个角度关注信息类似CNN的多通道实现将Q、K、V切分为h个头分别计算注意力再拼接head_i Attention(Q·W_i^Q, K·W_i^K, V·W_i^V) MultiHead Concat(head_1,...,head_h)·W_O八、注意力机制的作用总结1. 在解码器端动态聚焦生成每个词时关注源序列的不同部分信息选择从编码器输出中提取最相关信息对齐建模学习源语言和目标语言的词对齐关系2. 在编码器端特征增强通过自注意力强化重要特征上下文建模每个词包含全局上下文信息长距离依赖直接捕获远距离词间关系3. 通用作用可解释性注意力权重可解释模型关注点灵活性可应用于CNN、RNN、Transformer任意架构信息瓶颈突破打破固定长度向量的限制九、常见问题与解答Q1: Q、K、V维度必须相同吗A不一定。在加性注意力中可以不同在点积注意力中Q和K的最后一维需相同为了点积V的维度可不同。Q2: 为什么要除以√d_kA当d_k较大时点积结果方差变大softmax进入饱和区梯度极小。缩放后控制方差为1稳定梯度。Q3: 自注意力和一般注意力的区别A自注意力是QKV的特例用于建模序列内部关系一般注意力是Q与K、V来自不同序列用于建模序列间关系。Q4: 注意力机制有参数吗A有。计算Q、K、V的线性变换矩阵是参数计算相似度的网络也可能有参数如加性注意力中的W_q、W_k、v。十、经典案例seq2seq英法互译 待完善 十一、注意力机制的来时路2014Bahdanau提出NLP注意力机器翻译 2015Luong提出全局/局部注意力 2016自注意力在阅读理解任务中应用 2017Transformer提出多头自注意力成为主流 2018BERT、GPT等预训练模型全面采用注意力 至今注意力机制已成为NLP/CV/多模态的标准组件