【PyTorch单点知识】torch.nn.Embedding模块介绍:理解词向量与实现 ...

打印 上一主题 下一主题

主题 534|帖子 534|积分 1602

0. 前言

   按照国际惯例,起首声明:本文只是我自己学习的理解,虽然参考了他人的名贵见解及结果,但是内容大概存在不准确的地方。假如发现文中错误,渴望批评指正,共同进步。
  在自然语言处理(NLP)中,torch.nn.Embedding是PyTorch框架中一个至关重要的模块,用于将离散的词汇转换成连续的向量空间表现。这种转换允许模子捕获词汇之间的语义关系,并在诸如情感分析、文本分类和机器翻译等任务中发挥关键作用。
本文将深入探究torch.nn.Embedding的工作原理,并通过示例代码演示其在PyTorch中的利用。
1. 基础介绍

torch.nn.Embedding的本质是一个映射表(Lookup table),它用于储存自然语言词典嵌入向量的映射关系。
1.1 基本参数

torch.nn.Embedding的初始化继承两个基本参数:num_embeddings和embedding_dim。


  • num_embeddings:这个参数直观理解为“要嵌入的自然语言的词汇数量”,表现上面所述的自然语言词典的巨细,即大概的唯一词汇数量。好比英语中的常用单词,从abandon开始一共有3000个,那num_embeddings就可以设定为3000;
  • embedding_dim:表现每个词汇映射的嵌入向量的维度。
1.2 可选参数



  • padding_idx:用于指定词汇表中的填充词汇索引,该位置的向量将被初始化为零。
  • max_norm:用于限定嵌入向量的L2范数。
  • norm_type:用于指定范数范例。
  • scale_grad_by_freq:假如设置为True,则将梯度按词汇频率缩放。
  • sparse:假如设置为True,则将嵌入梯度标志为希罕。
1.3 属性

torch.nn.Embedding 模块只有一个属性 weight。这个属性代表了嵌入层要学习的权重,即存储所有嵌入向量的矩阵。这是嵌入层的学习权重,外形为 (num_embeddings, embedding_dim),也就是上文所说的lookup table映射表。这些权重代表实际的嵌入向量,它们是可学习的参数,而且在练习过程中会被优化算法更新。默认情况下,weight 是从标准正态分布 N(0, 1) 随机初始化的。这意味着每个元素都独立地从均值为 0、标准差为 1 的正态分布中采样。
1.4 PyTorch源码注释

以下是nn.Embedding的源码注释,用于上面说明的参考:
  1. Args:
  2.         num_embeddings (int): size of the dictionary of embeddings
  3.         embedding_dim (int): the size of each embedding vector
  4.         padding_idx (int, optional): If specified, the entries at :attr:`padding_idx` do not contribute to the gradient;
  5.                                      therefore, the embedding vector at :attr:`padding_idx` is not updated during training,
  6.                                      i.e. it remains as a fixed "pad". For a newly constructed Embedding,
  7.                                      the embedding vector at :attr:`padding_idx` will default to all zeros,
  8.                                      but can be updated to another value to be used as the padding vector.
  9.         max_norm (float, optional): If given, each embedding vector with norm larger than :attr:`max_norm`
  10.                                     is renormalized to have norm :attr:`max_norm`.
  11.         norm_type (float, optional): The p of the p-norm to compute for the :attr:`max_norm` option. Default ``2``.
  12.         scale_grad_by_freq (bool, optional): If given, this will scale gradients by the inverse of frequency of
  13.                                                 the words in the mini-batch. Default ``False``.
  14.         sparse (bool, optional): If ``True``, gradient w.r.t. :attr:`weight` matrix will be a sparse tensor.
  15.                                  See Notes for more details regarding sparse gradients.
  16.     Attributes:
  17.         weight (Tensor): the learnable weights of the module of shape (num_embeddings, embedding_dim)
  18.                          initialized from :math:`\mathcal{N}(0, 1)`
  19.     Shape:
  20.         - Input: :math:`(*)`, IntTensor or LongTensor of arbitrary shape containing the indices to extract
  21.         - Output: :math:`(*, H)`, where `*` is the input shape and :math:`H=\text{embedding\_dim}`
复制代码
2. 实例演示

这里我将给出一个简单的例子来说明如何利用 PyTorch 的 torch.nn.Embedding 模块创建一个嵌入层,并获取一些单词的嵌入向量。
假设我们有一个小型的词汇表,包含以下单词:


  • “the”
  • “cat”
  • “dog”
  • “sat”
  • “on”
  • “mat”
我们将这些单词映射到索引上,比方:


  • “the” -> 0
  • “cat” -> 1
  • “dog” -> 2
  • “sat” -> 3
  • “on” -> 4
  • “mat” -> 5
现在我们可以创建一个 torch.nn.Embedding 层,将这些单词映射到嵌入向量中。我们将利用一个 3 维的嵌入向量来表现每个单词。
下面是具体的代码示例:
  1. import torch
  2. import torch.nn as nn
  3. # 创建一个 Embedding 层
  4. # num_embeddings: 词汇表的大小,这里是 6
  5. # embedding_dim: 嵌入向量的维度,这里是 3
  6. embedding = nn.Embedding(num_embeddings=6, embedding_dim=3)
  7. # 定义一些单词的索引
  8. word_indices = torch.LongTensor([0, 1, 2, 3, 4, 5])  # "the", "cat", "dog", "sat", "on", "mat"
  9. # 通过索引获取嵌入向量
  10. word_embeddings = embedding(word_indices)
  11. # 输出嵌入向量
  12. print(word_embeddings)
复制代码
运行上述代码后,word_embeddings 将是一个外形为 (6, 3) 的张量,此中每一行代表一个单词的嵌入向量。
  1. tensor([[ 0.0439,  0.7314, -0.3546],
  2.         [ 0.6975,  1.2725,  1.4042],
  3.         [-1.7532, -2.0642, -0.1434],
  4.         [ 0.2538,  1.1123, -0.8636],
  5.         [-0.7238, -0.0585,  0.5242],
  6.         [ 0.6485,  0.6885, -1.2045]], grad_fn=<EmbeddingBackward0>)
复制代码
比方,word_embeddings[0] 对应于单词 “the” 的嵌入向量,word_embeddings[1] 对应于单词 “cat” 的嵌入向量,以此类推。
这就是一个简单的英语单词嵌入向量的例子。在实际应用中,词汇表会更大,嵌入向量的维度也会更高,而且通常会利用预练习的嵌入向量来初始化这些权重。
3. embedding_dim的合理设定

通过上文说明,我们可以轻松地把握nn.Embedding模块的利用,但是这里有个题目:embedding_dim设定为多少比力符合呢?
这里起首要说明下嵌入向量:它应该是代表单词“语义”的向量,而不是像one-hot那样是简单的字母映射。
举个例子:meet和meat两个词,拼写十分靠近,即它们的one-hot编码十分靠近,但是它们的语义完全不同,也就是说嵌入向量应该相差很远。而huge和enormous情况刚好相反,它们的one-hot编码完全不同,而嵌入向量应该比力靠近。
那回到embedding_dim的设定选择上来,我觉得可以参考以下3个方面来设定比力合理的embedding_dim:

  • 平衡信息量与过拟合风险

    • 信息量: 较高的 embedding_dim 可以捕获更多的信息和细微差异,从而进步模子的表达本事。然而,这也大概会导致过拟合,因为高维空间容易出现希罕性题目。
    • 过拟合风险: 较低的 embedding_dim 可以减少参数数量,降低过拟合的风险,但大概会丢失一些信息。

  • 考虑词汇表的巨细

    • 较小的词汇表: 假如词汇表相对较小(比方几千个词),较低的 embedding_dim(如 50 或 100)大概就足够了。
    • 较大的词汇表: 对于较大的词汇表(比方几十万或更多),可以选择较高的 embedding_dim(如 200 至 500)以更好地捕获语义信息。

  • 实验验证

    • 交叉验证: 终极的选择通常需要通过实验来确定。利用交叉验证来评估不同 embedding_dim 下的模子性能,可以资助找到最佳值。
    • 预练习嵌入: 假如有可用的预练习嵌入(如 Word2Vec、GloVe 或 FastText),可以考虑利用它们的维度作为参考。

   一点点思考:在Embedding方法中,embedding_dim一样平常是要比num_embeddings小(很多)的,这会导致矩阵的秩不满,终极会导致Embedding方法中的单词可以通过线性变换变成另一个单词。好比把abandon的词向量×2得到get的词向量,而one-hot不会有这个题目,这是Embedding小小的范围性。
  4. 结论

torch.nn.Embedding模块在PyTorch中为NLP任务提供了强大的工具,允许模子从词汇索引中学习有意义的向量表现。通过初始化和调用这个模块,我们可以轻松地将文本数据转换为适合深度学习模子的格式,从而挖掘文本数据中的丰富语义信息。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

罪恶克星

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表