我们先从理论角度来解释QKV机制,QKV机制是注意力机制的核心,尤其在Transformer模型中,注意力机制源于人类感知世界的方式:在处理信息时,我们会选择性地关注一部分信息,而忽略其他信息。在机器学习中,注意力机制允许模型在处理序列数据时,对不同的部分赋予不同的权重,从而更有效地利用信息。


1. QKV的定义
在注意力机制中,每个输入元素会生成三个向量:Query(查询)、Key(键)和Value(值)。这些向量是通过对输入进行线性变换得到的。

Query(Q):表示当前元素想要查询其他元素的信息。它类似于一个提问,用来匹配其他元素的Key。
Key(K):表示当前元素的标识,用于被其他元素的Query匹配。Query和Key的匹配程度决定了注意力权重。
Value(V):表示当前元素实际提供的信息。注意力权重会作用在Value上,从而得到加权的输出。
2. 直观理解
结合图书馆来理解,好比我们去图示馆借阅书籍:

Value:图书馆里所有的书籍本身,包含丰富的知识和信息
Key:每本书的索引卡,简要描述了书的内容特征
Query:我们的借阅请求,比如"我想找一本关于人工智能入门的书"
借书过程就是QKV机制:

1. 管理员将我们的Query与所有Key进行匹配
2. 找到最相关的几本书(计算匹配度)
3. 根据匹配程度决定每本书的"重要性权重"
4. 把这些书的Value按照权重组合起来给你
二、计算过程
给定输入序列X ∈ R^(n×d) ,其中n是序列长度,d是特征维度。我们通过线性变换得到Q、K、V,然后计算注意力权重,公式偏数学理论,先了解大概,记住公式内容,在示例中对比逐步领悟。

1. 输入表示:X ∈ R^(n×d)
n:序列长度(如一句话有10个词,n=10)
d:每个token的嵌入维度(如BERT-base中d=768)
 X = [[x₁₁, x₁₂, ..., x₁d],   # 第1个token的d维向量
        [x₂₁, x₂₂, ..., x₂d],   # 第2个token的d维向量  
         ...
        [xₙ₁, xₙ₂, ..., xₙd]]   # 第n个token的d维向量
 # 假设句子:"I love AI" 有3个token,每个token用4维向量表示
 X = [[0.1, 0.2, 0.3, 0.4],  # "I"的向量表示
        [0.5, 0.6, 0.7, 0.8],  # "love"的向量表示
        [0.9, 0.1, 0.2, 0.3]]  # "AI"的向量表示
 # 这里 n=3, d=4

2. 线性变换:生成Q, K, V
每个权重矩阵的作用:

W_Q - Query权重矩阵:     
学习如何提问
将原始输入映射到查询空间
决定每个token应该关注什么类型的信息
W_K - Key权重矩阵:     
学习如何被识别
将原始输入映射到键空间
决定每个token如何被其他token识别和匹配
W_V - Value权重矩阵:     
学习"提供什么信息"
将原始输入映射到值空间
决定每个token在被关注时应该贡献什么信息
实际计算示例:

 # 假设 d=4, d_k=3, d_v=3
 W_Q = [[0.1, 0.2, 0.3],
        [0.4, 0.5, 0.6], 
        [0.7, 0.8, 0.9],
        [0.2, 0.3, 0.4]]  # 4×3
 # 计算第一个token的Query向量
 token1 = [0.1, 0.2, 0.3, 0.4]
 Q1 = [0.1×0.1 + 0.2×0.4 + 0.3×0.7 + 0.4×0.2,
       0.1×0.2 + 0.2×0.5 + 0.3×0.8 + 0.4×0.3, 
       0.1×0.3 + 0.2×0.6 + 0.3×0.9 + 0.4×0.4]
    = [0.01 + 0.08 + 0.21 + 0.08, 
       0.02 + 0.10 + 0.24 + 0.12,
       0.03 + 0.12 + 0.27 + 0.16]
    = [0.38, 0.48, 0.58]

3. 注意力分数:
数学含义:

点积相似度:

测量Query向量和Key向量之间的相似性
值越大表示两个token之间的关联性越强
缩放因子 1/√d_k:

防止点积值过大导致softmax梯度消失
当d_k很大时,点积的方差也会变大,缩放保持数值稳定性
实际意义:

S矩阵是关联强度矩阵:
S[i,j]:第i个token对第j个token的关注程度
对角线元素 S[i,i]:token对自己的关注度
非对角线元素 S[i,j]:token之间的相互关注度
 # 示例:3个token的关联矩阵
 S = [[0.9, 0.3, 0.1],   # token1: 很关注自己,不太关注其他
      [0.2, 0.8, 0.6],   # token2: 关注自己和token3  
      [0.1, 0.5, 0.7]]   # token3: 比较关注token2

4. 注意力权重:
数学含义:

Softmax操作:

将注意力分数转换为概率分布
确保每行的权重和为1
放大较大值,抑制较小值
概率解释:

A[i,j] = P(关注token_j | 当前是token_i)
即:给定当前处理的是第i个token,它应该以多大概率关注第j个token
实际效果:

 # Softmax前
 S = [[1.0, 0.5, 0.1],
      [0.2, 2.0, 0.3], 
      [0.1, 0.4, 0.8]]
 # Softmax后(每行和为1)
 A = [[0.57, 0.29, 0.14],   # 主要关注自己
      [0.12, 0.73, 0.15],   # 强烈关注自己
      [0.18, 0.27, 0.55]]   # 主要关注自己,也关注其他

5. 输出计算:Z = A × V
实际意义:

上下文感知的表示:

原始输入X:每个token的独立表示
输出Z:每个token包含全局上下文信息的表示
 # 示例:代词消解
 句子:"The cat ate the fish because it was hungry"
 # 计算"it"的输出时:
 Z_it = 0.02 × V_The + 0.01 × V_cat + 0.01 × V_ate + 
        0.02 × V_the + 0.01 × V_fish + 0.90 × V_cat +  # 主要关注"cat"
        0.03 × V_was + 0.00 × V_hungry

6. 计算过程示例      
6.1 输入准备
假设我们有3个词的句子:"猫 吃 鱼",每个词用4维向量表示:

猫: [0.8, 0.2, 0.4, 0.1]
吃: [0.1, 0.9, 0.3, 0.7]  
鱼: [0.3, 0.1, 0.9, 0.2]
计算得出输入矩阵 X = [[0.8, 0.2, 0.4, 0.1], [0.1, 0.9, 0.3, 0.7], [0.3, 0.1, 0.9, 0.2]]

6.2 生成Q、K、V
模型有三个可学习的权重矩阵(开始时是随机值,通过训练学习):

W_Q = [[0.5, 0.2], [0.1, 0.3], [0.4, 0.6], [0.2, 0.1]] ,形状: [4, 2]
W_K = [[0.1, 0.5], [0.3, 0.2], [0.6, 0.4], [0.2, 0.3]]  ,形状: [4, 2]
W_V = [[0.2, 0.4], [0.5, 0.1], [0.3, 0.6], [0.1, 0.2]]  ,形状: [4, 2]
计算过程:

Q = X × W_Q
K = X × W_K  
V = X × W_V
让我们手动计算"猫"这个词的Q向量:

猫的Q = [0.8, 0.2, 0.4, 0.1] × [[0.5, 0.2], [0.1, 0.3], [0.4, 0.6], [0.2, 0.1]]
       = [0.8×0.5 + 0.2×0.1 + 0.4×0.4 + 0.1×0.2, 0.8×0.2 + 0.2×0.3 + 0.4×0.6 + 0.1×0.1]
       = [0.4 + 0.02 + 0.16 + 0.02, 0.16 + 0.06 + 0.24 + 0.01]
       = [0.6, 0.47]

计算最终得到:

Q = [[0.60, 0.47],   # 猫的Query
         [0.58, 0.90],   # 吃的Query  
         [0.72, 0.65]]   # 鱼的Query

K = [[0.32, 0.56],   # 猫的Key
         [0.50, 0.71],   # 吃的Key
         [0.68, 0.42]]   # 鱼的Key

V = [[0.35, 0.42],   # 猫的Value
         [0.62, 0.28],   # 吃的Value
         [0.54, 0.63]]   # 鱼的Value

6.3 计算注意力分数
现在计算每个Query与所有Key的匹配度:

注意力分数 = Q × K^T
K^T = [[0.32, 0.50, 0.68], [0.56, 0.71, 0.42]]
计算过程:

分数[0,0] = [0.60,0.47]·[0.32,0.56] = 0.60×0.32 + 0.47×0.56 = 0.192 + 0.263 = 0.455
分数[0,1] = [0.60,0.47]·[0.50,0.71] = 0.60×0.50 + 0.47×0.71 = 0.300 + 0.334 = 0.634
分数[0,2] = [0.60,0.47]·[0.68,0.42] = 0.60×0.68 + 0.47×0.42 = 0.408 + 0.197 = 0.605
... 以此计算所有组合
得到注意力分数矩阵:

注意力分数 = [[0.455, 0.634, 0.605],   # 猫对猫/吃/鱼的关注度
                        [0.572, 0.869, 0.753],   # 吃对猫/吃/鱼的关注度  
                        [0.533, 0.767, 0.763]]   # 鱼对猫/吃/鱼的关注度

6.4 Softmax归一化
对每一行进行Softmax,使得每行之和为1:

第一行: [0.455, 0.634, 0.605]
exp: [e^0.455, e^0.634, e^0.605] ≈ [1.576, 1.886, 1.831]
和: 1.576 + 1.886 + 1.831 = 5.293
Softmax: [1.576/5.293, 1.886/5.293, 1.831/5.293] ≈ [0.298, 0.356, 0.346]
最终注意力权重:

注意力权重 = [[0.298, 0.356, 0.346],   # 猫: 35.6%关注"吃", 34.6%关注"鱼"
                       [0.246, 0.422, 0.332],   # 吃: 最关注自己(42.2%) 
                       [0.276, 0.354, 0.370]]   # 鱼: 37.0%关注自己, 35.4%关注"吃"

6.5 加权求和得到输出
最后用注意力权重对Value进行加权求和:

对于"猫"这个词的输出:

输出[0] = 0.298×[0.35,0.42] + 0.356×[0.62,0.28] + 0.346×[0.54,0.63]
             = [0.104,0.125] + [0.221,0.100] + [0.187,0.218] 
             = [0.512, 0.443]

最终输出:

输出 = [[0.512, 0.443],   # 猫的上下文感知表示
             [0.527, 0.422],   # 吃的上下文感知表示
             [0.519, 0.468]]   # 鱼的上下文感知表示

7. 完整流程总结
整个流程包括输入、线性变换(生成Q、K、V)、计算注意力分数、Softmax归一化、加权求和得到输出。


流程详细说明:

1. 输入阶段     
X: 原始输入序列,形状为 n×d
n = 序列长度(如10个词)
d = 每个词的向量维度(如768维)
2. 线性变换阶段     
通过三个不同的权重矩阵生成Q、K、V:
Q (Query): 学习"如何提问" - 形状 n×d_k
K (Key): 学习"如何被识别" - 形状 n×d_k
V (Value): 学习"提供什么信息" - 形状 n×d_v
3. 注意力计算阶段     
S: 关联强度矩阵,形状 n×n
计算每个位置对其他所有位置的关注程度
S[i,j] 表示第i个位置对第j个位置的关注度
4. 归一化阶段     
A: 注意力权重矩阵,形状 n×n
通过Softmax确保每行的权重和为1
将关注度转换为概率分布
5. 输出生成阶段     
Z: 最终输出序列,形状 n×d_v
每个位置都是所有Value向量的加权和
权重由注意力矩阵A决定
每个token都包含了整个序列的上下文信息
三、体现的价值
1. 实际作用示例
示例1:代词消解

句子:"李华看见张明,他笑了"
计算过程:     
- "他"的Query会与所有词的Key匹配
- 发现与"李华"、"张明"的匹配度都很高
- 但通过训练,模型学会"他"通常指向前面最近的人名"张明"
- 因此给"张明"的Value更高权重
示例2:多义词理解

句子1:"苹果很好吃"  
句子2:"苹果股价上涨"
在句子1中:"苹果"的Query主要与"好吃"、"水果"等Key高匹配
在句子2中:"苹果"的Query主要与"股价"、"公司"等Key高匹配
2. 多头注意力机制
实际中大模型使用多头注意力,让模型同时从多个角度关注信息:


比如在分析"我去银行取钱"时:

头1关注:"取"→"钱"(动作-对象关系)
头2关注:"银行"→"取钱"(地点-活动关系)
头3关注:"我"→"取"(主体-动作关系)
四、代码实现推导
代码语言:python
AI代码解释
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np

class SimpleSelfAttention(nn.Module):
    """简单的自注意力机制实现"""
    
    def __init__(self, d_model=4, d_k=2, d_v=2):
        super(SimpleSelfAttention, self).__init__()
        self.d_model = d_model  # 输入维度
        self.d_k = d_k          # Query和Key的维度
        self.d_v = d_v          # Value的维度
        
        # 定义Q、K、V的线性变换层
        # 注意:nn.Linear的权重形状是 (out_features, in_features)
        self.W_Q = nn.Linear(d_model, d_k, bias=False)
        self.W_K = nn.Linear(d_model, d_k, bias=False)
        self.W_V = nn.Linear(d_model, d_v, bias=False)
        
        # 初始化权重,便于理解计算过程
        self._initialize_weights()
    
    def _initialize_weights(self):
        """手动初始化权重,便于跟踪计算过程"""
        # 预设的权重值,注意形状要与nn.Linear匹配
        # nn.Linear权重形状是 (out_features, in_features) = (d_k, d_model)
        preset_W_Q = torch.tensor([[0.5, 0.1, 0.4, 0.2],  # 第一行对应第一个输出维度
                                   [0.2, 0.3, 0.6, 0.1]], dtype=torch.float32)  # 第二行对应第二个输出维度
        
        preset_W_K = torch.tensor([[0.1, 0.3, 0.6, 0.2],
                                   [0.5, 0.2, 0.4, 0.3]], dtype=torch.float32)
        
        preset_W_V = torch.tensor([[0.2, 0.5, 0.3, 0.1],
                                   [0.4, 0.1, 0.6, 0.2]], dtype=torch.float32)
        
        self.W_Q.weight.data = preset_W_Q
        self.W_K.weight.data = preset_W_K
        self.W_V.weight.data = preset_W_V
    
    def forward(self, X, verbose=False):
        """
        前向传播
        Args:
            X: 输入张量 [seq_len, d_model]
            verbose: 是否打印详细计算过程
        """
        if verbose:
            print("=" * 60)
            print("QKV自注意力机制详细计算过程")
            print("=" * 60)
            print(f"输入 X (shape: {X.shape}):")
            print(X)
            print()
        
        # 步骤1: 生成Q, K, V
        Q = self.W_Q(X)  # [seq_len, d_k]
        K = self.W_K(X)  # [seq_len, d_k] 
        V = self.W_V(X)  # [seq_len, d_v]
        
        if verbose:
            print("步骤1: 生成Q, K, V")
            print(f"Q (shape: {Q.shape}):")
            print(Q)
            print(f"K (shape: {K.shape}):")
            print(K)
            print(f"V (shape: {V.shape}):")
            print(V)
            print()
        
        # 步骤2: 计算注意力分数 Q × K^T
        attention_scores = torch.matmul(Q, K.transpose(0, 1))  # [seq_len, seq_len]
        
        if verbose:
            print("步骤2: 计算注意力分数 Q × K^T")
            print(f"注意力分数矩阵 (shape: {attention_scores.shape}):")
            print(attention_scores)
            print()
            
            # 打印详细的计算过程
            print("详细点积计算:")
            for i in range(Q.shape[0]):
                for j in range(K.shape[0]):
                    dot_product = torch.dot(Q[i], K[j])
                    print(f"Q[{i}] · K[{j}] = {Q[i].detach().numpy()} · {K[j].detach().numpy()} = {dot_product:.3f}")
            print()
        
        # 步骤3: 缩放
        scaled_scores = attention_scores / np.sqrt(self.d_k)
        
        if verbose:
            print("步骤3: 缩放")
            print(f"缩放因子: 1/sqrt(d_k) = 1/sqrt({self.d_k}) = {1/np.sqrt(self.d_k):.3f}")
            print(f"缩放后的分数矩阵:")
            print(scaled_scores)
            print()
        
        # 步骤4: Softmax归一化
        attention_weights = F.softmax(scaled_scores, dim=-1)  # [seq_len, seq_len]
        
        if verbose:
            print("步骤4: Softmax归一化")
            print("对每一行进行Softmax:")
            for i in range(scaled_scores.shape[0]):
                row = scaled_scores[i]
                exp_row = torch.exp(row)
                sum_exp = torch.sum(exp_row)
                softmax_row = exp_row / sum_exp
                print(f"第{i}行: {row.detach().numpy()} -> exp: {exp_row.detach().numpy()} -> "
                      f"softmax: {softmax_row.detach().numpy()} (sum: {sum_exp:.3f})")
            print()
            
            print(f"注意力权重矩阵 (每行和为1):")
            print(attention_weights)
            print()
        
        # 步骤5: 加权求和得到输出
        output = torch.matmul(attention_weights, V)  # [seq_len, d_v]
        
        if verbose:
            print("步骤5: 加权求和得到输出")
            print("每个位置的输出计算:")
            for i in range(attention_weights.shape[0]):
                weights = attention_weights[i]
                weighted_sum = torch.zeros_like(V[0])
                for j in range(V.shape[0]):
                    contribution = weights[j] * V[j]
                    weighted_sum += contribution
                    print(f"  位置 {i}: {weights[j]:.3f} × V[{j}] {V[j].detach().numpy()} = {contribution.detach().numpy()}")
                print(f"  → 输出[{i}] = {weighted_sum.detach().numpy()}")
            print()
            
            print(f"最终输出 (shape: {output.shape}):")
            print(output)
            print("=" * 60)
        
        return output, attention_weights

def demonstrate_attention():
    """演示自注意力机制的工作过程"""
    
    # 创建模型
    attention = SimpleSelfAttention(d_model=4, d_k=2, d_v=2)
    
    # 示例输入:3个词的序列,每个词用4维向量表示
    # "猫" [0.8, 0.2, 0.4, 0.1]
    # "吃" [0.1, 0.9, 0.3, 0.7]  
    # "鱼" [0.3, 0.1, 0.9, 0.2]
    X = torch.tensor([
        [0.8, 0.2, 0.4, 0.1],  # 猫
        [0.1, 0.9, 0.3, 0.7],  # 吃
        [0.3, 0.1, 0.9, 0.2]   # 鱼
    ], dtype=torch.float32)
    
    print("输入句子: ['猫', '吃', '鱼']")
    print("每个词的向量表示:")
    words = ["猫", "吃", "鱼"]
    for i, word in enumerate(words):
        print(f"  '{word}': {X[i].numpy()}")
    print()
    
    # 前向传播,显示详细计算过程
    output, attention_weights = attention(X, verbose=True)
    
    # 可视化注意力权重
    print("\n注意力权重热力图解释:")
    print("行: 当前词(Query), 列: 被关注的词(Key)")
    print("    猫     吃     鱼")
    for i, word in enumerate(words):
        weights = attention_weights[i].detach().numpy()
        print(f"{word} {weights}")
    
    return output, attention_weights

def demonstrate_multihead_attention():
    """演示多头注意力的概念"""
    print("\n" + "=" * 70)
    print("多头注意力机制概念演示")
    print("=" * 70)
    
    # 使用PyTorch内置的多头注意力
    multihead_attn = nn.MultiheadAttention(embed_dim=4, num_heads=2, batch_first=True)
    
    # 同样的输入,但增加batch维度
    X = torch.tensor([[
        [0.8, 0.2, 0.4, 0.1],  # 猫
        [0.1, 0.9, 0.3, 0.7],  # 吃  
        [0.3, 0.1, 0.9, 0.2]   # 鱼
    ]], dtype=torch.float32)  # [batch_size=1, seq_len=3, embed_dim=4]
    
    print("输入形状:", X.shape)
    
    # 前向传播
    output, attention_weights = multihead_attn(X, X, X)
    
    print("输出形状:", output.shape)
    print("注意力权重形状:", attention_weights.shape)
    print("\n多头注意力的优势:")
    print("- 每个头可以关注不同类型的信息")
    print("- 头1可能关注: 语法关系(主谓宾)")  
    print("- 头2可能关注: 语义关系(猫→吃→鱼)")
    print("- 最终融合所有头的信息,获得更丰富的表示")

if __name__ == "__main__":
    # 演示基础自注意力
    output, weights = demonstrate_attention()
    
    # 演示多头注意力
    demonstrate_multihead_attention()
输出结果:

 输入句子: ['猫', '吃', '鱼']
 每个词的向量表示:
   '猫': [0.8 0.2 0.4 0.1]
   '吃': [0.1 0.9 0.3 0.7]
   '鱼': [0.3 0.1 0.9 0.2]
 ============================================================
 QKV自注意力机制详细计算过程
 ============================================================
 输入 X (shape: torch.Size([3, 4])):
 tensor([[0.8000, 0.2000, 0.4000, 0.1000],
         [0.1000, 0.9000, 0.3000, 0.7000],
         [0.3000, 0.1000, 0.9000, 0.2000]])
 步骤1: 生成Q, K, V
 Q (shape: torch.Size([3, 2])):
 tensor([[0.6000, 0.4700],
         [0.4000, 0.5400],
         [0.5600, 0.6500]], grad_fn=<MmBackward0>)
 K (shape: torch.Size([3, 2])):
 tensor([[0.4000, 0.6300],
         [0.6000, 0.5600],
         [0.6400, 0.5900]], grad_fn=<MmBackward0>)
 V (shape: torch.Size([3, 2])):
 tensor([[0.3900, 0.6000],
         [0.6300, 0.4500],
         [0.4000, 0.7100]], grad_fn=<MmBackward0>)
 步骤2: 计算注意力分数 Q × K^T
 注意力分数矩阵 (shape: torch.Size([3, 3])):
 tensor([[0.5361, 0.6232, 0.6613],
         [0.5002, 0.5424, 0.5746],
         [0.6335, 0.7000, 0.7419]], grad_fn=<MmBackward0>)
 详细点积计算:
 Q[0] · K[0] = [0.6        0.47000003] · [0.40000004 0.63      ] = 0.536
 Q[0] · K[1] = [0.6        0.47000003] · [0.6  0.56] = 0.623
 Q[0] · K[2] = [0.6        0.47000003] · [0.64000005 0.59      ] = 0.661
 Q[1] · K[0] = [0.39999998 0.54      ] · [0.40000004 0.63      ] = 0.500
 Q[1] · K[1] = [0.39999998 0.54      ] · [0.6  0.56] = 0.542
 Q[1] · K[2] = [0.39999998 0.54      ] · [0.64000005 0.59      ] = 0.575
 Q[2] · K[0] = [0.56       0.65000004] · [0.40000004 0.63      ] = 0.634
 Q[2] · K[1] = [0.56       0.65000004] · [0.6  0.56] = 0.700
 Q[2] · K[2] = [0.56       0.65000004] · [0.64000005 0.59      ] = 0.742
 步骤3: 缩放
 缩放因子: 1/sqrt(d_k) = 1/sqrt(2) = 0.707
 缩放后的分数矩阵:
 tensor([[0.3791, 0.4407, 0.4676],
         [0.3537, 0.3835, 0.4063],
         [0.4480, 0.4950, 0.5246]], grad_fn=<DivBackward0>)
 步骤4: Softmax归一化
 对每一行进行Softmax:
 第0行: [0.37907997 0.440669   0.46760976] -> exp: [1.4609399 1.5537463 1.5961744] -> softmax: [0.31684756 0.33697537 0.34617713] (sum: 4.611)
 第1行: [0.35369486 0.38353473 0.40630355] -> exp: [1.4243205 1.4674625 1.5012583] -> softmax: [0.32422197 0.33404252 0.34173554] (sum: 4.393)
 第2行: [0.44795218 0.4949748  0.52460253] -> exp: [1.5651039 1.6404569 1.689787 ] -> softmax: [0.31971252 0.3351053  0.34518224] (sum: 4.895)
 注意力权重矩阵 (每行和为1):
 tensor([[0.3168, 0.3370, 0.3462],
         [0.3242, 0.3340, 0.3417],
         [0.3197, 0.3351, 0.3452]], grad_fn=<SoftmaxBackward0>)
 步骤5: 加权求和得到输出
 每个位置的输出计算:
   位置 0: 0.317 × V[0] [0.39000005 0.6000001 ] = [0.12357055 0.19010855]
   位置 0: 0.337 × V[1] [0.63 0.45] = [0.21229446 0.1516389 ]
   位置 0: 0.346 × V[2] [0.4        0.71000004] = [0.13847084 0.24578576]
   → 输出[0] = [0.47433585 0.58753324]
   位置 1: 0.324 × V[0] [0.39000005 0.6000001 ] = [0.12644659 0.19453323]
   位置 1: 0.334 × V[1] [0.63 0.45] = [0.21044679 0.15031913]
   位置 1: 0.342 × V[2] [0.4        0.71000004] = [0.13669422 0.24263225]
   → 输出[1] = [0.4735876 0.5874846]
   位置 2: 0.320 × V[0] [0.39000005 0.6000001 ] = [0.12468789 0.19182752]
   位置 2: 0.335 × V[1] [0.63 0.45] = [0.21111631 0.15079737]
   位置 2: 0.345 × V[2] [0.4        0.71000004] = [0.1380729 0.2450794]
   → 输出[2] = [0.47387707 0.5877043 ]
 最终输出 (shape: torch.Size([3, 2])):
 tensor([[0.4743, 0.5875],
         [0.4736, 0.5875],
         [0.4739, 0.5877]], grad_fn=<MmBackward0>)
 ============================================================
 注意力权重热力图解释:
 行: 当前词(Query), 列: 被关注的词(Key)
     猫     吃     鱼
 猫 [0.31684753 0.33697534 0.3461771 ]
 吃 [0.324222   0.33404252 0.34173554]
 鱼 [0.3197125  0.33510527 0.34518224]
 =====================================================================
 多头注意力机制概念演示
 =====================================================================
 输入形状: torch.Size([1, 3, 4])
 输出形状: torch.Size([1, 3, 4])
 注意力权重形状: torch.Size([1, 3, 3])
 多头注意力的优势:
 - 每个头可以关注不同类型的信息
 - 头1可能关注: 语法关系(主谓宾)
 - 头2可能关注: 语义关系(猫→吃→鱼)
 - 最终融合所有头的信息,获得更丰富的表示

五、Token钱包官网|Token钱包下载安装 - 安全加密数字货币钱包www.jnjtjx.com
        QKV注意力机制是现代Transformer架构的核心突破,其本质是一个高效的信息检索与融合系统。该机制通过线性变换将输入序列转化为三组向量:

Query代表当前需要信息的"提问者"
Key作为其他位置的"身份标识"
Value则是实际承载的"信息内容"
        核心计算流程首先通过Query与所有Key的点积相似度建立关联矩阵,再经Softmax归一化为概率分布,最终对Value进行加权融合。QKV机制赋予模型动态上下文感知能力,每个位置的输出都融合了全局相关信息,而非固定窗口内的局部特征,这使模型能有效处理代词指代、一词多义等复杂语言现象。相比传统循环神经网络的序列处理,注意力机制能直接捕获任意距离的依赖关系,且完全并行化计算。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐