返回课堂

先把“按内容读取”拆成一个小例子

I02/b0 · 三个角色

一个可计算的读取玩具 · query q = (1, 0)
keyvalue与 q 点积
(1, 0)10待比较
(0, 1)20待比较
f(q) = Σᵢ vᵢ (kᵢᵀq)
10×1 + 20×0 = 10

先比较 query 与 key,再把匹配程度作为 value 的权重。这是读取接口的机制示意。

本例 key 正交且 query 恰好命中第一个;下一页去掉这个理想条件。

三个角色

我们借用 Alex Wang 文章里按内容读取的视角,把问题缩成两条记忆。第一条的 key 是横向向量一、零,对应 value 十;第二条的 key 是纵向向量零、一,对应 value 二十。本次 query 也是一、零。key 可以理解成用于识别这条内容的线索,value 是要读出的内容,query 是当前在找什么。这里用两个数画 key、用一个数画 value,只是为了看清动作,不是在宣布真实词义都能压成这么简单的坐标。

教师备课:指图与模拟问答

指图与推进 · 不朗读教师指向当前高亮对象,随后推进。

I02/b1 · 先比较 key

一个可计算的读取玩具 · query q = (1, 0)
keyvalue与 q 点积
(1, 0)101
(0, 1)200
f(q) = Σᵢ vᵢ (kᵢᵀq)
10×1 + 20×0 = 10

先比较 query 与 key,再把匹配程度作为 value 的权重。这是读取接口的机制示意。

本例 key 正交且 query 恰好命中第一个;下一页去掉这个理想条件。

先比较 key

先拿 query 和第一个 key 做点积:一乘一加零乘零,等于一。再和第二个 key 做点积:一乘零加零乘一,等于零。在这组特意挑选的向量里,第一个方向完全匹配,第二个方向没有贡献。为什么要先算这一步?因为我们希望内容的参与程度由当前查询决定,同一批存着的内容,换一个 query 就可能得到不同读取。现在先把匹配度一和零固定在两根连线上。如果把 query 换成零、一,这两根连线的角色就会交换;存着的内容不变,读取结果却能随问题变化。

教师备课:指图与模拟问答

指图与推进 · 不朗读指两组坐标和对应乘积,留出三秒。

I02/b2 · 按匹配度读 value

一个可计算的读取玩具 · query q = (1, 0)
keyvalue与 q 点积
(1, 0)101
(0, 1)200
f(q) = Σᵢ vᵢ (kᵢᵀq)
10×1 + 20×0 = 10

先比较 query 与 key,再把匹配程度作为 value 的权重。这是读取接口的机制示意。

本例 key 正交且 query 恰好命中第一个;下一页去掉这个理想条件。

按匹配度读 value

接着把各 value 乘上自己的匹配度再相加:十乘一,加二十乘零,结果是十。小公式 f(q) 等于所有 value 乘 key 与 query 的点积,再求和,表达的就是这个动作。它叫关联读取,是因为查询通过相似线索调用内容,而不是先给一个固定存储地址。这里用的是线性加权和,权重没有经过 softmax,所以不要把任何情况下的结果都叫概率平均。这个例子看起来很干净,是因为两条 key 刚好互不干扰。现实表示未必有这么漂亮的正交关系,我们现在只改第二个 key 看看。

教师备课:指图与模拟问答

指图与推进 · 不朗读教师指向当前高亮对象,随后推进。

补充推导、边界与来源

用一个二维教学构造解释关联读取:q=(1,0),k₁=(1,0),k₂=(0,1),标量 value 分别为 10 和 20。线性读取 f(q)=Σᵢvᵢ(kᵢᵀq) 先算点积得到匹配度 1 和 0,再得到 10×1+20×0=10。这里的 value 简化为标量,真实模型通常输出向量。

key 是用于匹配的表示,value 是匹配后被加权读出的内容,query 是本次查询。小例子使对象和公式一一对应,但它不是词典查找的完整模型,也没有解释语言理解的全部过程。Alex Wang 的博客使用记忆视角讨论这类读取;MLP 的相关解释可参看 Geva 等。下一步改变第二个 key,观察其他项如何干扰目标读取。

本页证据与条件

B02;P13

进入主题正文