Embbedding的理解

参考:详解深度学习之 Embedding_深度学习embedding_Training.L的博客-CSDN博客

独热编码 one-hot encoding 存在的问题包括如下:

  1. 大量为 0 的稀疏矩阵;
  2. 硬编码,特征没有语义信息;
  3. 特征维度较高,且每个特征都彼此独立,训练所需要的数据量高,容易导致维度灾难;

pytorch中的embedding

在 PyTorch 中,针对词向量有一个专门的层 nn.Embedding ,用来实现词与词向量的映射。nn.Embedding 相当于一个词表,形状为 (num_embedings, embedding_dim) ,其中 num_embedding 表示词表的长度,embedding_dim 表示词向量的维度,如果输入张量中不同词的个数超过词表的长度,就会报数组越界异常

如果 Embedding 层的输入形状为 NxM(N为batch_size,M是序列的长度),则输出的形状是 N x M x embedding_dim.

注意:输入必须是 LongTensor 类型,可以通过 tensor.long() 方法转成 LongTensor。

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
 
word_to_idx = {'girl': 0, 'boy': 1, 'woman': 2, 'man': 3}  # 每个单词用一个数字表示
embeds = nn.Embedding(8, 2) # 单词的个数8,2位embedding的维度

inputs = torch.LongTensor([[word_to_idx[key] for key in word_to_idx.keys()]])
inputs = torch.autograd.Variable(inputs)

# 获取Variable对应的embedding,并打印出来
outputs = embeds(inputs)
print(outputs)
print(embeds.weight)
tensor([[[-0.9663, -0.6391],   # 0
         [-2.2001,  0.7629],   # 1
         [ 0.1813, -1.1935],   # 2
         [-0.3214, -0.9004]]], grad_fn=<EmbeddingBackward>)  # 3
Parameter containing:
tensor([[-0.9663, -0.6391],  # 0
        [-2.2001,  0.7629],  # 1
        [ 0.1813, -1.1935],  # 2
        [-0.3214, -0.9004],  # 3
        [-1.7540,  0.0908],  # 4
        [ 1.1053, -0.8680],  # 5
        [ 0.2549,  0.2402],  # 6
        [ 0.9486, -0.7895]], requires_grad=True)  # 7

注:Embedding的权重也是可以训练的,既可以采用随机初始化,也可以采用预训练好的词向量初始化。

根据上面的结果我们可以看见,最后每个词向量的表示即是embeds.weights。我们训练模型也是训练的这个词向量的表示。(个人理解,欢迎指正)

觉得某大模型解释(觉得不错就粘上来了):

nn.Embedding 是PyTorch中的一个层(layer),通常用于将整数索引映射到密集的词嵌入(dense word embeddings)。在训练过程中,这些词嵌入通常是需要进行训练的参数。

当你创建一个 nn.Embedding 层时,其中的权重矩阵是一个可学习的参数。这个权重矩阵的行数通常等于词汇表的大小,每一行对应一个词。在训练的过程中,这些权重会被模型自动更新,以便更好地表示输入数据

下面是一个简单的例子,演示了如何创建一个包含可训练参数的 nn.Embedding 层:

import torch
import torch.nn as nn

# 假设词汇表大小为10,每个词嵌入的维度为3
vocab_size = 10
embedding_dim = 3

# 创建Embedding层
embedding_layer = nn.Embedding(vocab_size, embedding_dim)

# 随机生成一个输入序列,每个元素是一个词的索引
input_indices = torch.tensor([1, 3, 5, 2, 7])

# 将输入序列映射为词嵌入
embedded_input = embedding_layer(input_indices)

# 输出词嵌入
print("embedded_input",embedded_input)
print("weight",embedding_layer.weight)

在pycharm上实验了以下,输出如下:

embedded_input tensor([[-0.0846, -0.4749, -0.9375],
        [ 0.5553, -0.5761,  0.3212],
        [ 0.6565, -0.9949,  0.0403],
        [ 1.2086, -0.5082,  0.5631],
        [-0.5930,  0.2317,  0.2993]], grad_fn=<EmbeddingBackward0>)
weight Parameter containing:
tensor([[-0.1824, -0.5277,  0.5130],
        [-0.0846, -0.4749, -0.9375],   # 1
        [ 1.2086, -0.5082,  0.5631],   # 2
        [ 0.5553, -0.5761,  0.3212],   # 3
        [ 0.9578,  1.6284,  0.8284],   
        [ 0.6565, -0.9949,  0.0403],   # 5
        [-0.5386, -1.2851, -1.1687],
        [-0.5930,  0.2317,  0.2993],   # 7
        [ 0.9817,  0.6104, -0.6185],
        [ 0.8134,  0.4338, -1.5441]], requires_grad=True)

可以得到:下面的embedding_layer.weight就是上面经过embedding后的词嵌入表示(embedding_layer.weight即是token的表示),这是一个可学习的权重矩阵,我们在训练的时候,学习的就是这个矩阵。

即:nn.Embedding 的权重矩阵将会在训练中被学习,以便更好地适应模型的任务(更好的表示word/token或者input_id)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值