【NLP 20、Encoding编码 和 Embedding嵌入】

发布于:2025-02-10 ⋅ 阅读:(62) ⋅ 点赞:(0)

目录

一、核心定义与区别

二、常见Encoding编码

(1) 独热编码(One-Hot Encoding)

(2) 位置编码(Positional Encoding)

(3) 标签编码(Label Encoding)

(4) 注意事项 

三、常见Embedding词嵌入

(1) 基础词嵌入(nn.Embedding)

(2) 预训练嵌入(from_pretrained) 

(3) 类别特征嵌入(自定义类)

(4) 注意事项 

四、对比总结

五、编码与嵌入的联合使用

总结


新年快乐,这几天将之前做的笔记整理了一下,补充了一点,正式开始学习! 

                                                                                                                —— 24.2.4

一、核心定义与区别

特性 Encoding(编码) Embedding(嵌入)
目标 将数据转换为特定格式(如数值、二进制、位置信息等),以满足模型输入要求。 将离散符号(如单词、类别)映射到低维连续向量空间,捕捉语义或结构关系。
数学形式 通常为确定性规则或固定函数(如独热编码、位置编码)。 通过可学习的参数矩阵(如神经网络中的嵌入层)生成。
维度 维度可能较高(如独热编码的维度等于类别数量)。 维度固定且较低(如词嵌入常用 100~1000 维)。
可训练性 不可训练(静态规则)。 可训练(通过反向传播优化)。
应用场景 数据预处理、位置信息编码、分类标签处理。 词向量表示、类别特征嵌入、图节点表示。

二、常见Encoding编码

(1) 独热编码(One-Hot Encoding)

  • 定义:将离散类别映射为二进制向量,仅一个位置为1,其余为0。

  • 注意:

    独热编码 使用 torch.nn.functional.one_hot,注意设置 num_classes 参数。
  • 示例:

# 类别:["猫", "狗", "鸟"]
"猫" → [1, 0, 0]
"狗" → [0, 1, 0]
"鸟" → [0, 0, 1]
  • 缺点:维度爆炸(高维稀疏),无法表达类别间关系。

参数 类型 描述 是否必需 默认值
tensor torch.Tensor 输入的整数类别索引张量(如 [0, 2, 1] -
num_classes int 类别总数(决定输出维度) -

(2) 位置编码(Positional Encoding)

  • 定义:为序列数据(如文本、时间序列)添加位置信息,常用正弦/余弦函数生成。

  • 注意:

    位置编码 自定义生成矩阵后叠加到词嵌入上,需与输入张量形状匹配。
  • Transformer 中的公式

参数 类型 描述 是否必需 默认值
max_seq_len int 最大序列长度(决定编码矩阵的行数) -
d_model int 特征维度(决定编码矩阵的列数)

(3) 标签编码(Label Encoding)

  • 定义:将类别映射为整数(如 "红"→0, "蓝"→1, "绿"→2),但可能引入错误的大小关系。

(4) 注意事项 

  1. 独热编码的输入限制

    • 输入张量必须是整数类型(如 torch.long)。

    • 索引值必须小于 num_classes,否则会越界。

  2. 位置编码的叠加方式

    • 需与词嵌入维度一致(d_model),且直接相加前确保形状匹配。

独热编码 num_classes 控制输出维度,避免索引越界
位置编码 max_seq_lend_model 定义编码矩阵的尺寸和特征维度

三、常见Embedding词嵌入

(1) 基础词嵌入(nn.Embedding

nn.Embedding()模块

注意:

词嵌入 使用 nn.Embedding 层,输入为整数索引张量,输出为浮点数向量。
embedding_layer = nn.Embedding(num_embeddings=10000, embedding_dim=300)
参数 类型 描述 是否必需 默认值
num_embeddings int 词汇表大小(唯一符号数量) -
embedding_dim int 嵌入向量的维度 -
padding_idx int 填充符索引(对应向量初始化为零) None
max_norm float 向量最大范数(超过时缩放) None
scale_grad_by_freq bool 根据词频缩放梯度(罕见词更大更新) False
import torch.nn as nn

# 定义嵌入层:词汇表大小=10000,嵌入维度=300
embedding_layer = nn.Embedding(num_embeddings=10000, embedding_dim=300)

# 输入:单词索引(形状 [batch_size, seq_len])
input_ids = torch.LongTensor([[1, 22, 45], [3, 8, 2]])  # 示例输入

# 获取词嵌入向量
embeddings = embedding_layer(input_ids)  # 输出形状 [2, 3, 300]

(2) 预训练嵌入(from_pretrained 

nn.Embedding.from_pretrained()

注意: 

预训练嵌入 通过 from_pretrained 加载,freeze=True 可固定嵌入参数(适用于迁移学习)。
pretrained_emb = nn.Embedding.from_pretrained(glove.vectors, freeze=True)
参数 类型 描述 是否必需 默认值
embeddings torch.Tensor 预训练嵌入矩阵(形状 [num_emb, dim] -
freeze bool 是否冻结参数(不更新) True
padding_idx int 同基础 nn.Embedding None
max_norm float 同基础 nn.Embedding None

如GloVe: 

from torchtext.vocab import GloVe

# 加载预训练的 GloVe 词向量
glove = GloVe(name='6B', dim=100)  # 使用 100 维的 GloVe

# 获取单词 "apple" 的向量
apple_vector = glove['apple']  # 形状 [100]

# 将预训练向量转换为嵌入层
pretrained_emb = nn.Embedding.from_pretrained(glove.vectors, freeze=False)  # freeze=True 表示不更新

(3) 类别特征嵌入(自定义类)

CategoryEmbedding
user_embedding = CategoryEmbedding(num_categories=1000, embedding_dim=64)
参数 类型 描述 是否必需 默认值
num_categories int 类别总数(如用户数、商品数) -
embedding_dim int 嵌入向量的维度 -

注意:

类别嵌入 将高基数类别(如用户ID)映射为低维向量,避免维度爆炸。
import torch.nn as nn

class CategoryEmbedding(nn.Module):
    def __init__(self, num_categories, embedding_dim):
        super().__init__()
        self.embedding = nn.Embedding(num_categories, embedding_dim)
    
    def forward(self, category_ids):
        return self.embedding(category_ids)

# 示例:用户ID嵌入(假设有 1000 个用户)
user_embedding = CategoryEmbedding(num_categories=1000, embedding_dim=64)
user_ids = torch.tensor([5, 12, 8])  # 输入用户ID
embedded_users = user_embedding(user_ids)  # 形状 [3, 64]

(4) 注意事项 

  1. 嵌入层的输入要求

    • nn.Embedding 的输入为整数索引,非浮点数。

  2. 预训练嵌入的兼容性

    • 加载预训练向量时,需确保 num_embeddings 和 embedding_dim 与预训练矩阵一致。

基础词嵌入 num_embeddingsembedding_dim 决定嵌入层的输入输出维度
预训练嵌入 embeddingsfreeze 加载外部知识,控制参数更新
类别嵌入 num_categoriesembedding_dim 处理高基数离散特征,避免维度灾难

四、对比总结

维度 Encoding Embedding
语义保留 无(仅符号化) 高(捕捉语义相似性)
计算开销 低(静态计算) 高(需训练参数)
灵活性 固定规则 可自适应任务优化
典型应用 数据预处理、位置编码 词向量、推荐系统、图表示学习
场景 推荐方法
类别特征且维度低 独热编码(简单高效)
类别特征维度高(如用户ID) 嵌入(避免维度灾难)
序列位置信息 位置编码(如 Transformer)
需要捕捉语义相似性 嵌入(如词向量)
计算资源有限 优先选择静态编码(如哈希编码)

五、编码与嵌入的联合使用

在 Transformer 中,词嵌入位置编码共同构成输入表示:

参数 类型 描述 是否必需 默认值
vocab_size int 词汇表大小(词嵌入参数) -
d_model int 特征维度(词嵌入和位置编码共享) -
max_seq_len int 最大序列长度(位置编码参数) -
import torch
import torch.nn as nn

class TransformerInput(nn.Module):
    def __init__(self, vocab_size, d_model, max_seq_len):
        super().__init__()
        self.token_embedding = nn.Embedding(vocab_size, d_model)
        self.position_encoding = self._generate_position_encoding(max_seq_len, d_model)
        
    def _generate_position_encoding(self, max_len, d_model):
        position = torch.arange(max_len).unsqueeze(1)
        div_term = torch.exp(torch.arange(0, d_model, 2) * (-math.log(10000.0) / d_model))
        pe = torch.zeros(max_len, d_model)
        pe[:, 0::2] = torch.sin(position * div_term)
        pe[:, 1::2] = torch.cos(position * div_term)
        return pe  # 形状: [max_len, d_model]
    
    def forward(self, x):
        # x: [batch_size, seq_len]
        token_emb = self.token_embedding(x)  # [batch_size, seq_len, d_model]
        seq_len = x.size(1)
        positions = self.position_encoding[:seq_len, :]  # [seq_len, d_model]
        return token_emb + positions  # [batch_size, seq_len, d_model]

总结

  • Encoding 是广义的数据转换方式,强调格式兼容性(如独热编码、位置编码)。

  • Embedding 是特殊的编码方法,通过可学习的低维向量捕捉语义信息(如词嵌入)。

  • 两者常结合使用(如 Transformer 中的词嵌入+位置编码),分别处理不同维度的信息。


网站公告

今日签到

点亮在社区的每一天
去签到