--- created: 2025-08-03 21:19:11 tags: - "Research" - "基础" - "Transformer" - "词嵌入" - "Embedding" --- ### 引入 在用语料作为数据集训练语言模型时, 我们无法直接将文字作为计算的数据, 就和我们在[[YOLO-v5]]中输入一张图片一样, 我们需要先将其展平成一个向量(toTensor), 将其数据 **向量化** , 才能输入到我们的网络中进行计算. 将单词(word)映射成我们所需要的向量, 从而能够用于模型的训练与计算, 这个过程就是所谓的 **词嵌入 (Word Embedding)**. 在以往我们也有接触过非常简单的词嵌入, 那就是[[One-Hot编码]], 但是现在我们要训练的数据集通常非常庞大(例如[[Transformer]]的各种应用的训练, 使用一个非常非常长的One-Hot是不现实的, 所以我们就需要新的词嵌入的方法.) ### Embedding的本质 Embedding 就是==用一个低维稠密的向量表示一个对象==,这里的对象可以是一个词(Word2vec),也可以是一个物品(Item2vec),亦或是网络关系中的节点(Graph Embedding)。==Embedding 向量能够表达对象的某些特征,两个向量之间的距离反映了对象之间的**相似性**==。简单的说,Embedding 就是把一个东西映射到一个向量 X。如果这个东西很像,那么得到的向量 x1 和 x2 的**欧式距离很小**。 (有没有发现[[位置编码 (Positional Encoding)]]其实和Embedding还挺像的? 因为它也用一个低维稠密的向量来表示了单词在句子中的位置, 位置相近两个向量之间的欧式距离也很小, 所以有些地方也把位置编码叫做PositionalEmbedding) **举例说明**: - `Word Embedding`,把单词 w 映射到向量 x。如果两个单词的意思相近,比如 bike 和 bicycle,那么它们映射后得到的两个词向量 x1 和 x2 的欧式距离很小。 - `User Embedding`,把用户 ID 映射到向量 x。推荐系统中,需要用一个向量表示一个用户,如果两个用户的行为习惯接近,那么他们对应的向量 x1 和 x2 的欧式距离很小。 - `Graph Embedding`,把图中的每个节点映射成一个向量 x。如果图中两个节点接近,比如它们的最短路很小,那么它们 embed 得到的向量 x1 和 x2 的欧式距离很小。 - `多模态里的embedding`,就是直接把两个向量通过全连接变成一个。 ### Embedding的用途 #### 降维 假设,一个 2x6 的矩阵,乘上一个 6x3 的矩阵,变成一个 2x3 的矩阵。 $$(\begin{array}{cccc}1&0&0&0&0&0\\0&1&0&0&0&0\end{array})\begin{bmatrix}w_{11}&w_{12}&w_{13}\\w_{21}&w_{22}&w_{23}\\w_{31}&w_{32}&w_{33}\\w_{41}&w_{42}&w_{43}\\w_{51}&w_{52}&w_{53}\\w_{61}&w_{52}&w_{53}\\w_{61}&w_{52}&w_{53}\end{bmatrix}=(\begin{array}{ccccc}a_{11}&a_{12}&a_{13}\\a_{21}&a_{22}&a_{23}\end{array})$$ $$A*B=C$$ 在上述公式中,一个 12 个元素的 A 矩阵变成 C 中 6 个元素的矩阵,直观上大小缩小了一半。 假设一个 100Wx10W 的矩阵,乘上一个 10Wx20 的矩阵,可以把它降到 100Wx20 的矩阵,降低 10w/20=5000 倍。 总结:在某种程度上,==Embedding 层实现了降维的作用==,降维的原理是根据==矩阵乘法==。 #### 升维 如果在 10 米开外找出 3 处不同,是很困难的事情,目测也可能完成。但是让你在一米外,发现水壶的背景不同。然后再走近半米,又发现小姑娘头上的小花夹子不一致。再走近 20 厘米,又发现花盆中黄色小花不同。 无限靠近并不代表认知度就高。比如,在距离屏幕 1 厘米远的地方找茬,这是不可能的。低维的数据可能包含的特征信息是非常笼统的,需要不停地拉近拉远来改变我们的感受,让我们对这幅图有不同的观察点,找出图中的 “找茬”。由此可见,距离的远近会影响我们的观察效果。 Embedding 的另一个作用体现了:==对低维数据进行升维时,可以把一些其他特征放大,或者把笼统的特征给分开==。 Embedding 是一直在学习优化的,使得整个拉近拉远的过程慢慢形成一个良好的观察点。比如,来回靠近和远离屏幕,发现 45 厘米是最佳观测点,这个距离能 5s 内把 3 个不同点找出来。 ### Word Embedding的方法 One-Hot 的形式看上去很简洁,也挺美,但劣势在于它很**稀疏**,而且还可能很**长**。比如词汇表如果有 10k 个词,那么一个词向量的长度就需要达到 10k,而其中却仅有一个位置是 1,其余全是 0,太浪费空间 更重要的是,这种方式无法体现出**词与词之间的关系。** 比如 “爱” 和 “喜欢” 这两个词,它们的意思是相近的,但基于 one-hot 编码后的结果取决于它们在词汇表中的位置,无法体现出它们之间的关系。 因此,我们需要另一种词的表示方法,能够体现词与词之间的关系,使得**意思相近的词有相近的表示结果**,这种方法即 **Word Embedding。** 那么应该如何设计这种方法呢?最方便的途径是设计一个**可学习的权重矩阵 W,** 将*词向量与这个矩阵进行点乘*,即得到新的表示结果。 假设 “爱” 和 “喜欢” 这两个词经过 one-hot 后分别表示为 10000 和 00001,权重矩阵设计如下: \[ w00, w01, w02 w10, w11, w12 w20, w21, w22 w30, w31, w32 w40, w41, w42 ] 那么两个词点乘后的结果分别是 \[w00, w01, w02] 和 \[w40, w41, w42],在网络学习过程中(这两个词后面通常都是接主语,如 “你”,“他” 等,或者在翻译场景,它们被翻译的目标意思也相近,它们要学习的目标一致或相近),权重矩阵的参数会不断进行更新,从而使得 \[w00, w01, w02] 和 \[w40, w41, w42] 的值越来越接近。 另一方面,对于以上这个例子,我们还把向量的维度从 5 维压缩到了 3 维。因此,word embedding 还可以起到**降维**的效果。 其实,可以将这种方式看作是一个 **lookup table**:对于每个 word,进行 word embedding 就相当于一个 lookup 操作,在表中查出一个对应结果。 在 `Pytorch` 框架下,可以使用 _`torch.nn.Embedding`_ 来实现 word embedding: ```python class Embeddings(nn.Module): def __init__(self, d_model, vocab): super(Embeddings, self).__init__() self.lut = nn.Embedding(vocab, d_model) self.d_model = d_model def forward(self, x): return self.lut(x) * math.sqrt(self.d_model) ``` 其中,_`vocab`_ 代表词汇表中的单词量,one-hot 编码后词向量的长度就是这个值;_`d_model`_ 代表权重矩阵的列数,通常为 512,就是要将词向量的维度从 _`vocab` 编码_到 _`d_model`_。 ### 参考资料 [A word to understand word embedding (2 mainstream algorithms + comparison with other text representations)](https://easyai.tech/en/ai-definition/word-embedding/) [Transformer输入嵌入:Input Embedding-CSDN博客](https://blog.csdn.net/m0_61899108/article/details/121534347#t1) [【Transformer系列】深入浅出理解Embedding(词嵌入)\_transformer embedding-CSDN博客](https://blog.csdn.net/m0_37605642/article/details/132866531)