Pytorch nn.Embedding的基本使用

本文介绍了在自然语言处理中如何使用PyTorch的nn.Embedding层进行单词编码,包括基本用法、参数设置和可学习性。nn.Embedding通过降维将单词转换为固定维度的向量,解决了one-hot编码的缺点。此外,还讨论了padding_idx参数的使用,以及Embedding参数在训练过程中的更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么情况下使用Embedding

假设我们需要对单词进行编码,首先容易想到的是one-hot,简单复习一下:

  1. 首先要建立一个词典,例如:
单词索引
hello0
i1
am2
  1. 建立好词典后,使用一个与词典一样大小的数组,将要编码的单词对应索引下表改为1即可,例如"am"的编码为[0,0,1,0,0,...],该数组的大小与词典大小一致

one-hot的最大的缺点显而易见:词典有多大,一个单词对应的数组向量的维度就有多大。当然还有其他缺点,例如:词和词之间没有关系,做不到king - queen = man - women

所以需要有一个方法可以降维,可以将单词编码成指定的维度,例如,将"am"(3)编码成5维向量[-0.972,0.371,-0.172,0.581,0.134]

Embedding就是干这个事的

nn.Embedding的基本用法

nn.Embeddding接受两个重要参数:

  1. num_embeddings:字典的大小。对应上面词典的大小,如果你的词典中包含5000个单词,那么这个字段就填5000
  2. embedding_dim:要将单词编码成多少维的向量

例如,我们现在词典大小为20,现在要对hello, i, am,这三个单词进行编码,想将其编码为5维向量,则对应代码为:

import torch
from torch import nn

embedding = nn.Embedding(20, 5)
embedding(torch.LongTensor([0,1,2]))
tensor([[ 0.4471,  0.3875, -1.0195, -1.1125,  1.3481],
        [-1.7230, -0.1964, -0.0420,  0.5782,  0.4514],
        [-0.0310, -1.9674, -1.1344, -1.6752,  1.0801]],
       grad_fn=<EmbeddingBackward0>)

使用nn.Embedding,将0(hello)编码成了[ 0.4471, 0.3875, -1.0195, -1.1125, 1.3481]

使用注意事项

  1. embedding只接受LongTensor类型的数据
  2. embedding的数据不能大于等于词典大小,例如上面指定了词典大小为20,那么要编码的索引大小就不能>=20

nn.Embedding的其他常用参数

padding_idx:填充索引,即,如果是这个所以,一律编码为0。有时我们的字典里会增加一项unknown代表未知的单词,这样我们就可以使用该参数,对所有unknown的单词都编码成0。

embedding = nn.Embedding(20, 5, padding_idx=3) # 加上unknown对应的索引是3
embedding(torch.LongTensor([0,1,2,3,4]))
tensor([[ 0.3824, -0.6734, -2.1156,  1.7065,  1.2072],
        [-0.5977, -1.0876,  0.6169,  1.4566,  0.0325],
        [ 1.1299,  0.5794, -1.5166,  0.1036,  0.3793],
        [ 0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [-1.0468,  1.3305, -2.1740, -0.5534, -0.1062]],
       grad_fn=<EmbeddingBackward0>)

可以看到,3索引的编码全为0

nn.Embedding的可学习性

nn.Embedding中的参数并不是一成不变的,它也是会参与梯度下降的。也就是更新模型参数也会更新nn.Embedding的参数,或者说nn.Embedding的参数本身也是模型参数的一部分。

举个例子:

embedding = nn.Embedding(20, 5, padding_idx=3) # 对3不进行编码
optimizer = torch.optim.SGD(embedding.parameters(), lr=0.1)
criteria = nn.MSELoss()

for i in range(1000):
    outputs = embedding(torch.LongTensor([0,1,2,3,4]))
    loss = criteria(outputs, torch.ones(5, 5))
    loss.backward()
    optimizer.step()
    optimizer.zero_grad()

在上面例子中,我对nn.Embedding不断的计算损失和梯度下降,让其编码往1的方向靠近,训练结束后,我们再次尝试使用embedding进行编码:

embedding(torch.LongTensor([0,1,2,3,4]))

输出为:

tensor([[1.0004, 0.9999, 1.0000, 1.0000, 1.0000],
        [0.9999, 0.9996, 0.9997, 0.9999, 0.9996],
        [0.9999, 0.9996, 0.9994, 0.9993, 0.9991],
        [0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
        [0.9991, 0.9999, 0.9999, 0.9998, 0.9997]],
       grad_fn=<EmbeddingBackward0>)

可以看到,经过训练后,embedding的参数发生了变化,把它们都编码成了1。





参考资料

nn.Embedding官方文档:https://pytorch.org/docs/stable/generated/torch.nn.Embedding.html

### PyTorch `nn.Embedding` 的用法 在自然语言处理 (NLP) 和其他领域中,嵌入层 (`Embedding Layer`) 是非常重要的组件之一。PyTorch 提供了 `torch.nn.Embedding` 类来创建和管理这些嵌入。 #### 创建 Embedding 层 可以通过指定词汇表大小(即词典中的单词数量)以及每个词的维度来初始化一个 embedding 层: ```python import torch from torch import nn embedding = nn.Embedding(num_embeddings=10, embedding_dim=3) ``` 这里 `num_embeddings` 表示词汇量大小,而 `embedding_dim` 则表示每个词语对应的向量长度[^1]。 #### 输入与输出形状 对于输入张量而言,其最后一个维度应当代表 batch 中样本的数量;其余所有前置维度都将被视作单一样本的一部分。因此,在大多数情况下,输入会是一个二维张量 `(batch_size, seq_len)` 或者一维张量 `(seq_len,)` 当批次大小为 1 时。该函数将会返回具有相同前导尺寸的新张量,但在最后增加了一个新的特征轴用于存储 embeddings 结果,形成三维张量 `(batch_size, seq_len, embedding_dim)` 或两维张量 `(seq_len, embedding_dim)` 如果批次大小为 1。 #### 使用预训练权重 如果希望利用已经预先训练好的 word vectors 初始化 embedding 层,则可以这样做: ```python pretrained_weights = ... # 加载预训练权重矩阵 vocab_size, embed_size = pretrained_weights.shape embedding_layer = nn.Embedding(vocab_size, embed_size).from_pretrained(pretrained_weights) ``` 注意这里的 `.from_pretrained()` 方法可以直接接受 numpy 数组或其他形式的数据作为参数,并据此设置初始权重值。 #### 实际应用案例 考虑如下场景:给定一批句子 ID 序列,想要获取它们各自的 embedding 向量以便后续处理。假设我们有一个简单的例子,其中包含三个句子,每句话有两个 token IDs 组成的小序列: ```python input_tensor = torch.LongTensor([[1, 2], [4, 5], [7, 8]]) output_embedding = embedding(input_tensor) print(output_embedding.size()) # 输出应形如: torch.Size([3, 2, 3]) ``` 这段代码片段展示了如何将整数型 tensor 转换成相应的浮点型 embedding vector 形式的操作过程。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iioSnail

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值