小白也能懂---Transformer中Look-Ahead Mask 的实现

我们来用最真实的计算过程拆解下三角掩码矩阵(Look-Ahead Mask)到底做了什么,如何确保预测时模型​​只能看前面的词,不能看自己和未来的词​ ​。我们用生成句子 "我爱吃苹果" 中第三个词 ​ ​ 的位置 (假设位置索引是 2) 作为例子。


🔍 场景设定

  1. ​序列状态(训练阶段):​

    假设模型正在训练,我们喂给它完整的正确目标序列:

    • ​位置索引:​0: <SOS>, 1: 我, 2: 吃, 3: 苹果, 4: <EOS>

    • ​向量:​ ​ 每个位置都有一个 d_model 维的向量(比如 d_model=3,简化计算):

      • x0 = [0.1, 0.2, 0.3] // <SOS>
      • x1 = [0.4, 0.5, 0.6] //
      • x2 = [0.7, 0.8, 0.9] // (当前关注的位置!)
      • x3 = [1.0, 1.1, 1.2] // 苹果 (未来的词,模型预测时不该看!)
      • x4 = [1.3, 1.4, 1.5] // <EOS> (未来的词,模型预测时不该看!)
    • ​输入张量:​X = [x0, x1, x2, x3, x4],形状 [5, 3]

  2. ​目标:​

    模型需要根据 <SOS> 预测出 。但在并行训练时,x 向量里含有所有位置的信息(包括未来的 苹果<EOS>)。这会导致模型"作弊",直接用未来的信息来预测 ,而不是真正学习到 后面应该接 的规律。​​下三角掩码就是要阻止这种作弊!​


🛡️ 下三角掩码矩阵 (mask) 的作用和计算

1. ​​构造 Look-Ahead Mask 矩阵(尺寸 [5, 5]):​

规则:​​位置 i 可以看位置 j,当且仅当 j <= i ​ (即只能看前面和自身,通常也要掩码自身)。

具体值:​​允许看的位置设为 0 ​ (不影响分数),​​禁止看的位置设为 -∞ ​ (或一个极大的负数如 -1e9),让 Softmax 后概率为 0。

ini 复制代码
//   j=0       j=1       j=2       j=3       j=4     <-- Key 位置 (允许看哪些位置?)
// i=0 (<SOS>) [   0   ,  -∞   ,  -∞   ,  -∞   ,  -∞   ]   // 位置0只能看j=0
// i=1 (我)    [   0   ,    0  ,  -∞   ,  -∞   ,  -∞   ]   // 位置1可以看j=0,1
// i=2 (吃)    [   0   ,    0  ,    0  ,  -∞   ,  -∞   ]   // 位置2可以看j=0,1,2 (目标!)
// i=3 (苹果)  [   0   ,    0  ,    0  ,    0  ,  -∞   ]   // 位置3可以看j=0,1,2,3
// i=4 (<EOS>) [   0   ,    0  ,    0  ,    0  ,    0  ]   // 位置4可以看所有

​重点看 i=2 (吃 所在行):​

  • 允许看 j=0 (<SOS>), j=1 (我), j=2 (吃)。✅
  • 禁止看 j=3 (苹果), j=4 (<EOS>) (设为 -∞)。❌

2. ​​计算 Query (Q), Key (K), Value (V):​

假设我们已计算好 Q, K, V(具体参数不重要,关注数值变化):

  • Q = X * W_q (形状 [5, 3],假设 W_q 是参数矩阵)
  • K = X * W_k (形状 [5, 3])
  • V = X * W_k (形状 [5, 3])
    为简化,我们​只看位置 i=2 (吃) 的向量​
  • q2 = [0.5, 0.6, 0.7] // 位置的 Query 向量
  • K = [ [0.2, 0.3, 0.4], // j=0 (<SOS>) [0.5, 0.6, 0.7], // j=1 (我) [0.8, 0.9, 1.0], // j=2 (吃) [1.1, 1.2, 1.3], // j=3 (苹果) [1.4, 1.5, 1.6] // j=4 (<EOS>) ] // 形状 [5, 3]

3. ​​计算相似度分数 scores (q2K 中每一个 kj 的点积):​

scores = q2 · K^T (点积计算相似度)

具体计算:

less 复制代码
score_j0 = [0.5, 0.6, 0.7] · [0.2, 0.3, 0.4] = 0.5 * 0.2 + 0.6 * 0.3 + 0.7 * 0.4 = 0.1 + 0.18 + 0.28 = 0.56
score_j1 = [0.5, 0.6, 0.7] · [0.5, 0.6, 0.7] = 0.5 * 0.5 + 0.6 * 0.6 + 0.7 * 0.7 = 0.25 + 0.36 + 0.49 = 1.10
score_j2 = [0.5, 0.6, 0.7] · [0.8, 0.9, 1.0] = 0.5 * 0.8 + 0.6 * 0.9 + 0.7 * 1.0 = 0.40 + 0.54 + 0.70 = 1.64
score_j3 = [0.5, 0.6, 0.7] · [1.1, 1.2, 1.3] = 0.5 * 1.1 + 0.6 * 1.2 + 0.7 * 1.3 = 0.55 + 0.72 + 0.91 = 2.18  // 和未来词相似度很高!
score_j4 = [0.5, 0.6, 0.7] · [1.4, 1.5, 1.6] = 0.5 * 1.4 + 0.6 * 1.5 + 0.7 * 1.6 = 0.70 + 0.90 + 1.12 = 2.72  // 和<EOS>相似度也高!

计算得到初始 scores = [0.56, 1.10, 1.64, 2.18, 2.72]

​大问题:​吃 (i=2) 和未来的 苹果 (j=3)<EOS> (j=4) 的分数最高!如果直接用,它会大量参考未来信息,这是严重作弊!

4. ​​应用 Look-Ahead Mask (mask)!​

回想 i=2 (吃) 对应的掩码行:[0, 0, 0, -∞, -∞]

我们将这个掩码 ​​加(+)到 scores 上(通常除以 √d_k 后进行,这里简化略过除法)​​:

ini 复制代码
// 掩码行(对应于 i=2): [0,   0,    0,   -1e9, -1e9]
// 原始 scores:          [0.56, 1.10, 1.64, 2.18, 2.72]
// 相加(masked_scores): [0.56+0, 1.10+0, 1.64+0, 2.18 + (-1e9), 2.72 + (-1e9)]
                       = [0.56,   1.10,   1.64,   ≈ -1000000000, ≈ -1000000000]

​关键效果:​j=3 (苹果) 和 j=4 () 的分数被​​压成了极负值(≈-1e9)​ ​,而允许看的 j=0, 1, 2 的分数保持不变!

5. ​​对 masked_scores 做 Softmax:​

Softmax 对所有位置的值做指数归一化。极大负数的指数 ≈ 0。

ini 复制代码
// masked_scores = [0.56, 1.10, 1.64, -1e9, -1e9]
exp(0.56) ≈ 1.75
exp(1.10) ≈ 3.00
exp(1.64) ≈ 5.16
exp(-1e9) ≈ 0.0
exp(-1e9) ≈ 0.0
// 总和 ≈ 1.75 + 3.00 + 5.16 + 0 + 0 = 9.91
// Softmax 概率:
prob_j0 = 1.75 / 9.91 ≈ 0.18
prob_j1 = 3.00 / 9.91 ≈ 0.30
prob_j2 = 5.16 / 9.91 ≈ 0.52  // 它对自己("吃")关注度最高(在没有未来信息干扰下)
prob_j3 = 0.0
prob_j4 = 0.0

​最终注意力权重:attn_weights = [0.18, 0.30, 0.52, 0.0, 0.0]

6. ​​加权求和得到位置 i=2(吃)的新表示:​

z2 = attn_weights * V = 0.18 * V[j0] + 0.30 * V[j1] + 0.52 * V[j2] + 0.0 * V[j3] + 0.0 * V[j4]

因为 prob_j3 = 0.0, prob_j4 = 0.0,所以 V[j3] (苹果) 和 V[j4] (<EOS>) ​​完全没贡献!​
z2​只融合了 j=0 (<SOS>), j=1 (我), j=2 (吃) 的信息!​


✅ 总结:下三角掩码矩阵到底做了什么?

  1. ​物理位置:​ 在计算位置 i 的 Self-Attention 时,输入包含整个序列所有位置(包括未来的位置)的向量(因为训练是批量的)。
  2. ​作弊风险:​ 位置 i 可以轻易计算出和未来位置 j>i 的高相似度(分数)。
  3. ​掩码介入:​ Look-Ahead Mask(下三角阵)​在计算 Softmax 之前,将位置 i 对应的行中 j>i(未来)的分数加了一个极大的负值(≈-1e9)​
  4. ​Softmax效果:​ 加上掩码后,j>i 位置的分数经过 Softmax 后概率 ​≈0.0​ ,它们对应的 Value(Vj​在加权求和时贡献为0​
  5. ​最终结果:​ 位置 i 的新向量 zi ​仅由位置 0i 的信息(通常也掩码自身,j=i 被屏蔽,使其不关注自己)融合而来,完全屏蔽了未来信息​

📌 一句话核心

​Look-Ahead Mask(下三角掩码矩阵)通过在计算注意力权重时,把未来位置的分数强制设为极负值(≈-1e9),从而保证位置 i 在 Softmax 后,权重只能分配给位置 0i(自身通常也被掩码),无法分配给未来的位置 j>i。​​ 它在训练时防止作弊,并确保推理时模型行为的一致性(只能依赖前文)。

相关推荐
黎燃17 分钟前
基于情感识别的在线教育互动优化:技术实现与未来展望
人工智能
shengyicanmou31 分钟前
2025年物联网新趋势:格行随身WiFi的模块化架构与低延迟优化
大数据·人工智能
Ai财富密码36 分钟前
AI赋能教育:低代码游戏化学习平台
人工智能·低代码·游戏
补三补四44 分钟前
Shapley与SHAP
大数据·人工智能·算法·机器学习·数据分析
qq_314009831 小时前
Dify版本升级实操
人工智能·aigc·开源软件
Hao想睡觉1 小时前
CNN卷积神经网络之VggNet和GoogleNet经典网络模型(四)
网络·人工智能·cnn
我不是小upper1 小时前
anaconda、conda、pip、pytorch、torch、tensorflow到底是什么?它们之间有何联系与区别?
人工智能·pytorch·深度学习·conda·tensorflow·pip
智汇云校乐乐老师1 小时前
产教融合 AI赋能 创新引领 | 第十七届高校教育发展高峰论坛在利川成功举办!
人工智能·高峰论坛·讯方技术
热河暖男1 小时前
Spring Boot AI 极速入门:解锁智能应用开发
java·人工智能·spring boot·ai编程