1. Embedding基础:什么是Embedding、词向量的概念、One-hot编码的局限性、Embedding层的数学本质
好,咱们直接进入正题。Embedding这个词,你肯定在各种深度学习教程里见过。说白了,它就是把「离散的东西」变成「连续的向量」。什么意思?我慢慢讲。
1.1 什么是Embedding?
想象一下,你要让计算机理解「苹果」和「香蕉」的关系。计算机只认数字,不认文字。那怎么办?
Embedding就是干这个的。它把每个词、每个用户、每个商品,都映射到一个低维的、稠密的向量空间里。在这个空间里,语义相近的词,它们的向量距离也近。
核心定义:Embedding = 从离散符号到连续向量的映射函数。
我个人习惯把Embedding理解成「翻译官」。它把人类能理解的符号(比如单词"cat"),翻译成机器能计算的数字列表(比如 [0.23, -0.45, 0.67, ...])。
1.2 词向量的概念
词向量,就是每个词对应的那个向量。比如:
# 假设词表大小是 10000,Embedding维度是 128
# "king" 的向量可能是:
king_vec = [0.12, -0.34, 0.56, ..., 0.89] # 长度128
# "queen" 的向量可能是:
queen_vec = [0.15, -0.30, 0.52, ..., 0.92] # 长度128
你想想看,这两个向量是不是很像?这就是Embedding的精髓——语义相似的词,向量也相似。
我记得在做一个文本分类项目时,发现「开心」和「快乐」的向量余弦相似度高达0.92。嗯,这很合理。但「开心」和「悲伤」的相似度是负的。这就是词向量的力量。
1.3 One-hot编码的局限性
在Embedding出现之前,大家用One-hot编码。那玩意儿长这样:
# 词表:["苹果", "香蕉", "猫", "狗"]
# One-hot编码:
苹果 -> [1, 0, 0, 0]
香蕉 -> [0, 1, 0, 0]
猫 -> [0, 0, 1, 0]
狗 -> [0, 0, 0, 1]
看着挺整齐对吧?但问题大了去了。
One-hot的三大硬伤:
- 维度灾难:词表如果有10万个词,每个向量就是10万维。存起来要命,算起来更要命。
- 语义鸿沟:「苹果」和「香蕉」的距离,跟「苹果」和「猫」的距离一样远。都是√2。这合理吗?不合理。
- 无法表达相似性:所有向量两两正交,没有任何语义关系。
我曾经在一个推荐系统项目里硬用One-hot做用户特征。结果呢?模型训练了三天,准确率还不如随机猜。后来换成Embedding,一天就收敛了。这就是血的教训。
1.4 Embedding层的数学本质
好,现在咱们来点硬核的。Embedding层到底在数学上做了什么?
说白了,Embedding层就是一个查表操作。它维护一个矩阵:
# Embedding矩阵形状:[词表大小, 嵌入维度]
# 假设词表大小=10000,嵌入维度=128
embedding_matrix = torch.randn(10000, 128)
# 输入:词的索引(比如 "cat" 的索引是 42)
input_idx = torch.tensor([42])
# 输出:直接查表
output_vec = embedding_matrix[input_idx] # 形状:[1, 128]
数学上,这就是一个线性变换:
E(x) = W · one_hot(x)
其中W是Embedding矩阵,one_hot(x)是输入x的One-hot向量。但实际实现中,没人真去算矩阵乘法,直接查表效率高得多。
个人经验:Embedding层本质上就是一个可训练的查找表。它的参数(矩阵中的数值)会随着反向传播一起更新。所以,Embedding层不是固定的,它是学出来的。
你可能会问:「那Embedding层和全连接层有什么区别?」
区别大了。全连接层是密集连接,每个输入都跟所有输出相连。Embedding层是稀疏连接,一次只激活一行。所以Embedding层计算量小得多,参数量也少得多。
1.5 实战中的小坑
嗯,这里要注意几个点:
- Embedding维度怎么选? 我一般用经验公式:min(50, 词表大小的1/4次方)。或者直接用50、100、300这些常见值。
- 预训练还是随机初始化? 数据量大就随机初始化,数据量小就用预训练(比如Word2Vec、GloVe)。
- 梯度更新: Embedding层的梯度只更新被查到的行。没被查到的词,它的向量保持不变。
一句话总结:Embedding层就是把离散的符号ID,映射成连续的、可学习的稠密向量。它解决了One-hot的维度灾难和语义鸿沟问题,是深度学习处理离散特征的标配。
下一章,咱们会深入Embedding层的梯度传播细节。你会看到,为什么Embedding层在反向传播时那么高效。准备好了吗?