词元与嵌入:把输入变成数字
入门01 / 从一个完整故事开始
学校社团想用短说明搜索一箱照片。讨论大模型前,小博在卡片上写下“red kite”,思考电脑应保存什么。给每词一个编号便于查表,但编号 7 并不表示意义是编号 1 的七倍。
他再给每个词元分配小型特征列表,将其平均来表示卡片。大家因此能比较一个完整数值例子,也发现丢失了什么:“kite red”得到同样平均值。这个小失败让他们开始理解真实模型为何要保留顺序、学习有用表示。
02 / 理解核心概念
词元是模型处理的单位。文本中可以是词、词的一部分或标点。分词器把文字转换成这种单位的序列,词表为每个单位分配整数 ID。ID 是查表地址,不是有意义的距离。
嵌入是用作表示的一组数。在学习系统里,训练调整这些数,使其有助于任务。向量就是这种有序列表,维度就是元素数。图像词元可表示小图像块而非词。
我们先手写词表,把两个词元向量取平均。这称为池化:将多个向量组合成一个。它容易观察,却丢失顺序。真实分词与学习编码器还做更多工作,包括处理词表中没有整词条目的词。
先认识这些词
- 词元
- 模型输入或输出序列中的一个单位。
- 嵌入
- 表示输入单位或观察的一组数字。
- 维度
- 特征向量中的元素数量。
- 池化
- 将多个特征列表组合成一个。
03 / 如何运用这个概念
使用图文搜索或语言模型前,先区分 ID、特征向量与整个输入的编码。
04 / 官方教程与研究中的应用
用下面的原创计算与 Python 代码观察机制。所链接的一手资料解释完整系统怎样扩展这些机制。故事是虚构的教学情境。
05 / 公式与逐项解析
mean_featureⱼ = (token₁ⱼ + token₂ⱼ + … + tokenₙⱼ) / n
n 是词元向量数。j 选择第一或第二等特征位置。把相同位置的值相加,再除以词元数。所有词元向量必须同维,且 n 为正。
06 / 一步步算出结果
教学表给 red=[1,0]、kite=[0,2]。平均第一项为 (1+0)/2=0.5,第二项为 (0+2)/2=1,池化向量为 [0.5,1]。交换词序不改变两项和,说明这种表示无法区分顺序。
一步步想清楚
为什么不能用词 ID 比较含义?
ID 只标识查表条目。重新编号会改 ID,却不改变词。
平均向量第二项为什么是一?
第二项分别是零与二,(0+2)/2=1。
颠倒词元顺序会改变平均值吗?
不会。加法忽略顺序,这是简单编码器的局限。
运行一个完整示例 · 01
查表并汇总两个词元
小型英文例子只使用列表与字典,其表示原理适用于任何语言。
text = "red kite"
tokens = text.split()
vocabulary = {"red": 0, "kite": 1}
embedding_table = [[1.0, 0.0], [0.0, 2.0]]
ids = [vocabulary[token] for token in tokens]
vectors = [embedding_table[token_id] for token_id in ids]
pooled = [sum(vector[j] for vector in vectors) / len(vectors) for j in range(2)]
print("tokens:", tokens)
print("IDs:", ids)
print("pooled:", pooled)
在本地运行
python tokens-embeddings-toy-token-table.py
预期输出
tokens: ['red', 'kite'] IDs: [0, 1] pooled: [0.5, 1.0]
逐步读懂代码
split 按空白分开。字典把每个词元转为 ID;方括号查询键或列表位置。下一推导式取得每个特征列表。range(2) 遍历特征位置 0、1,sum 累加同位置元素,len 给出两个词元。这是手设查表与均值池化,不是训练文本编码器。
这些知识可以用在哪里
未知词
改为“blue kite”。查表失败,因为缺少 blue。真实分词器需要明确未知词或子词策略。
更长说明
试“red red kite”。平均向量变为 [2/3,2/3]。即使描述同一物体,重复仍会改变均值。
使用图文搜索或语言模型前,先区分 ID、特征向量与整个输入的编码。