Version:0.9 StartHTML:0000000197 EndHTML:0000069599 StartFragment:0000000233 EndFragment:0000069563 SourceURL:https://yuanbao.tencent.com/chat/naQivTmsDa/22ed1bd5-fbe0-48f0-abe0-0b36bade2022 嵌入层本身是固定的(每个token对应一个固定向量),但模型通过其他机制(如位置编码和自注意力)来捕捉语序和上下文语义。以下是具体解释:
1. 问题的根源
- 嵌入层局限性:如果仅靠固定嵌入向量,模型无法区分“猫追狗”和“狗追猫”(词序不同但词相同)。
- 语义差异:语序变化会导致句子含义截然不同(如“人吃鱼” vs “鱼吃人”),必须依赖更复杂的机制。
2. 解决方案:位置编码与自注意力
现代大模型(如Transformer架构)通过以下两种核心机制解决语序问题:
**(1) 位置编码(Positional Encoding)**
- 作用:为每个token的位置赋予唯一编码,明确词序信息。
- 实现方式:
- 绝对位置编码:直接为第i个位置生成向量(如正弦/余弦函数或可学习向量)。
- 相对位置编码:编码词与词之间的相对距离(如“猫”和“追”相隔1个位置)。
- 示例:
- 句子“猫 追 狗”中:
- “猫”的嵌入向量 + 位置1编码
- “追”的嵌入向量 + 位置2编码
- “狗”的嵌入向量 + 位置3编码
- 句子“狗 追 猫”中:
- “狗”的嵌入向量 + 位置1编码
- “追”的嵌入向量 + 位置2编码
- “猫”的嵌入向量 + 位置3编码
- 即使词相同,位置编码不同,输入模型的向量也不同。
- 句子“猫 追 狗”中:
**(2) 自注意力(Self-Attention)**
- 作用:动态分析词与词之间的关系,捕捉上下文依赖。
- 关键特性:
- 上下文感知:每个词的最终表示由其周围词决定(如“苹果”在“吃苹果”中关注“吃”,在“苹果手机”中关注“手机”)。
- 长距离依赖:无论词距离多远,自注意力均可直接关联(如“虽然…但是…”中的逻辑关系)。
- 示例:
- 在“猫追狗”中,自注意力会让“追”关注“猫”和“狗”,建立“猫→追→狗”的动作链。
- 在“狗追猫”中,自注意力会让“追”关注“狗”和“猫”,建立“狗→追→猫”的动作链。
3. 整体流程(以Transformer为例)
python# 伪代码示意 输入句子 = ["猫", "追", "狗"] # 步骤1:嵌入层(固定向量) token_embeddings = embedding_layer(输入句子) # 形状 [3, d_model] # 步骤2:添加位置编码(引入语序信息) position_embeddings = positional_encoding(位置=[1,2,3]) # 形状 [3, d_model] combined_embeddings = token_embeddings + position_embeddings # 形状 [3, d_model] # 步骤3:自注意力层(动态调整语义) output = self_attention(combined_embeddings) # 形状 [3, d_model]
- 最终输出:每个词的向量既包含原始语义(嵌入层),又包含位置和上下文信息。
4. 实验验证
- 可视化注意力权重:若输入“猫追狗”和“狗追猫”,可观察到“追”对“猫”和“狗”的注意力权重分布不同。
- 向量相似度对比:
- “猫”在“猫追狗”中的输出向量 vs “猫”在“狗追猫”中的输出向量 → 相似度较低。
- “追”在两个句子中的输出向量 → 相似度中等(语义相同但方向不同)。
5. 进阶思考
- 为什么不用嵌入层直接编码语序?
- 嵌入层的目标是学习词汇的静态语义(如“猫”是动物,“追”是动作)。
- 语序和上下文属于动态语义,应由更高层网络(如Transformer)处理。
- 位置编码是否足够?
- 单纯的位置编码只能解决显式语序,复杂逻辑关系(如因果、转折)还需依赖自注意力的推理能力。
总结
| 机制 | 作用 | 解决的核心问题 |
|---|---|---|
| 嵌入层 | 编码词汇的静态语义 | 词本身的含义 |
| 位置编码 | 编码词序信息 | 区分“猫追狗”和“狗追猫” |
| 自注意力 | 动态关联上下文 | 理解“苹果”指水果还是公司 |
通过这三者的配合,模型既能理解词义,又能捕捉语序和上下文差异!