type
status
date
slug
summary
tags
category
icon
password
线性代数
向量的点积是一种特殊的乘法,它把两个向量"压缩"成一个数字。计算方法是:将两个向量对应位置的数相乘,然后把所有乘积加起来。
例子:
点积的一个重要特性是它可以表示两个向量的"相似度":
- 如果两个向量很相似,它们的点积会较大
- 如果两个向量差异很大,点积会较小
- 如果两个向量互相垂直,点积为0
- 什么是向量? 向量最简单的理解就是一串数字。比如:
这就是一个向量。我们可以把它想象成空间中的一个点或箭头,其中:
- 1 是这个点在x轴上的位置
- 2 是在y轴上的位置
- 3 是在z轴上的位置
在机器学习中,我们经常用向量来表示事物的"特征"。比如一个人的特征可以是:
假设我们在分析一个电商网站的用户行为数据:
假设我们有3位用户的特征向量,每个特征向量包含5个维度的信息:
计算用户之间的相似度(点积):
用户1和用户2的点积:
这个结果告诉我们用户1和用户2的行为模式有多相似
矩阵乘法:
假设我们现在运营一个视频网站,有这样的数据:
- 用户-内容矩阵(用户对不同类型内容的兴趣度):
- 内容-广告矩阵(不同类型内容和广告的相关度):
矩阵乘法可以帮我们计算出:用户对不同广告的可能兴趣度。
计算方法是:用户对某类广告的兴趣 = 该用户对所有内容类型的兴趣 × 这些内容类型与该广告的相关度之和
比如,计算用户A对电子产品广告的兴趣:
完整的矩阵乘法结果是:
这就是矩阵乘法的实际应用 - 它可以把一种关系(用户-内容)通过另一种关系(内容-广告)转换成新的关系(用户-广告)。
假设我们有一句话:"我 喜欢 看 电影",每个词都被编码成了3维的向量(实际中通常是768维,这里简化以便理解):
在self-attention中,我们要回答的核心问题是:每个词需要关注句子中的哪些词?
- 计算相似度(注意力分数) 把每个词和所有词做点积,得到注意力分数矩阵:
这个过程比如:
- "我"和"我"的点积:
- "我"和"喜欢"的点积:
以此类推
- 归一化(softmax) 把这些分数转换成权重,使它们的和为1:
怎么来的:
- Softmax的计算公式是:softmax(x) = exp(x) / sum(exp(x)) 具体步骤:
a) 先计算每个数的指数:
b) 计算所有指数的和:
c) 每个指数除以总和:
这样就得到了第一行的注意力权重:[0.15, 0.20, 0.25, 0.40]
- 加权求和 用这些权重对原始词向量进行加权求和,得到新的表示:
怎么来的:
让我们计算"我"的新表示(第一行):
我们需要的数据是:—》这里用到了矩阵反置—〉
- 转置就像让每个人都有机会去和其他所有人交谈
- 最终得到的是每个人和其他所有人的亲密度评分
- "我"对所有词的注意力权重:[0.15, 0.20, 0.25, 0.40]
- 原始词向量:
计算"我"的新表示(分维度计算):
- 第一个维度:
- 第二个维度:
- 第三个维度:
这样我们就得到了"我"的新表示:[0.31, 0.42, 0.38]
这个新词向量:
但实际上我们是可以在权重那边,看到词和词的关系的。
- 在Transformer中的应用:
- 这些新词向量会被输入到下一个Encoder层
- 每一层都会产生新的词向量,不断精炼表示
- 比如BERT有12层或24层,每层都会产生新的词向量
以机器翻译为例:
所以新词向量是连接注意力机制和实际任务的桥梁 - 它把"谁该关注谁"的信息转换成了可以用来做具体任务的向量表示。
就像一个流水线:
- 注意力权重找出关系
- 新词向量打包这些关系
- 传递给下一层继续处理
- 最后输出任务结果
Position Encoding
比如对于这两个句子:
- "我 喜欢 看 电影"
- "看 电影 我 喜欢"
虽然词是一样的,但意思完全不同。但用我们之前学的self-attention机制,这两个句子可能会得到相似的结果,因为:
- self-attention只关注词与词的关系
- 不知道词在句子中的位置
- 词的顺序信息完全丢失了
所以需要position encoding
为什么要用sin 和 cos:
控制在-1到1;临近位置编码是连续;维度0:变化最慢,适合捕捉长距离关系;维度d_model-1:变化最快,适合捕捉局部特征
所以结合word embedding就直接 embedding+position embedding
- 为什么是加法而不是其他运算?
- 加法保持了原始词向量的语义信息
- 位置编码的值域较小,不会主导最终的表示
- 加法运算简单,计算效率高
- 维度匹配
- 位置编码向量的维度必须和词向量维度相同
- 通常是512维或768维
position Embedding的核心就是:
- 增加位置信息:
- 通过额外的向量注入位置信息
- 让模型知道每个词在序列中的位置
- 使用sin/cos的原因:
- 保证值域在[-1,1],不会喧宾夺主
- 每个位置都有独特编码
- 能表达相对位置关系
- 可以处理任意长度的序列
multi-head
为什么需要?
用之前学的single-head attention时:
- "特效"这个词可能会关注"很棒"
- 但同时它可能也需要关注"电影"(表示是电影的特效)
- 而单个attention只能给出一组权重分布
问题就出现了:
- 单个attention必须在"很棒"和"电影"之间做权重分配
- 无法同时强调这两种不同类型的关系
- 可能会丢失一些重要的关联信息