第19周:Embeddingbag与Embedding详解

目录

前言

一、基本概念

1.1 什么是词嵌入?

1.2 Embedding详解

1.3 EembeddingBag详解

二、练习任务

2.1任务要求

2.2 实现代码

总结


前言

说在前面

本周任务:了解Embedding和Embeddingbag,并加载.txt文件完成词嵌入

我的环境:Python3.8、Pycharm2020、torch1.12.1+cu113

数据来源:[K同学啊]


一、基本概念

1.1 什么是词嵌入?

    词嵌入是一种用于自然语言处理(NLP)的技术,用于将单词表示为数字,以便计算机可以处理它们,即一种把文本转化为数值输入到计算机中的方法。

将文本转换为字典序列、one-hot编码就是最早起的词嵌入方法,Embedding和EmbeddingBag是PyTorch中用来处理文本数据中词嵌入(word embedding)的工具,它们将离散的词汇映射到低维的连续向量空间中,使得词汇之间的语义关系能够在向量空间中得到体现。

1.2 Embedding详解

     Embedding是PyTorch中最基本的词嵌入操作,TensorFlow中也有相同的函数,功能是一样的,它将每个离散的词汇映射到一个低维的连续向量空间中,并且保持了词汇之间的语义关系,在PyTorch中,Embedding的输入是一个整数张量,每个整数都代表着一个词汇的索引,输出是一个浮点型的张量,每个浮点数都代表着对应词汇的词嵌入向量。

      嵌入层使用随机权重初始化,并将学习数据集中所有词的嵌入,它是一个灵活的层,可以以各种方式使用,例如

  • 它可以用作深度学习模型的一部分,其中嵌入与模型本身一起被学习
  • 它可以用于加载训练好的词嵌入模型

嵌入层被定义为网络的第一个隐藏层

函数原型:torch.nn.Embedding(num_embeddings, embedding_dim, padding_idx=None, max_norm=None,norm_type=2.0,scale_grad_by_freq=False,sparse=False,_weight=None,

_freeze=False,device=None,dtype=None)

官方API:Embedding — PyTorch 2.4 documentation

常见参数:

num_embeddings:词汇表大小,即最大整数index+1

embedding_dim:词向量的维度

示例(用Embedding将两个句子转换为词嵌入向量)

本例中,定义了一个简单的词嵌入模型,它将大小为12的词汇表中的每个词汇映射到一个4维的向量空间中,然后输入两个句子,分别是[1,5,8]和[2,4],每个数字代表着词汇表中的一个词汇的索引,随后将两个句子通过Embedding转换为词嵌入向量,并输出结果,可以看到,每个句子中的每个词汇都被映射成一个4维的向量。

import torch
import torch.nn as nn

vocab_size = 12      #词汇表大小
embedding_dim = 4    #嵌入向量的维度

#创建一个Embedding层
embedding = nn.Embedding(vocab_size, embedding_dim)

#假设有一个包含两个单词索引的输入序列
input_sequence1 = torch.tensor([1, 5, 8], dtype=torch.long)
input_sequence2 = torch.tensor([2, 4], dtype=torch.long)

#使用Embedding层将输入序列转换为词嵌入
embedded_sequence1 = embedding(input_sequence1)
embedded_sequence2 = embedding(input_sequence2)

print(embedded_sequence1)
print(embedded_sequence2)

输出结果:

tensor([[-7.2832e-01,  1.0047e+00, -8.5490e-02,  1.9378e+00],
        [ 5.0610e-01, -1.8192e-01, -2.0392e+00,  6.3155e-01],
        [ 1.9518e+00,  4.9482e-01, -1.0382e+00, -1.1013e-03]],
       grad_fn=<EmbeddingBackward0>)
tensor([[-0.3932, -0.2167, -0.0483, -0.6653],
        [ 0.2050, -0.4289,  0.7200,  0.1471]], grad_fn=<EmbeddingBackward0>)

进程已结束,退出代码 0

1.3 EmbeddingBag详解

     EmbeddingBag是在Embedding基础上进一步优化的工具,它可以直接处理不定长的句子,并且可以计算句子中所有词汇的词嵌入向量的均值或总和,在Pytorch中,EmbeddingBag的输入是一个整数张量和一个偏移量张量,每个整数都代表着一个词汇的索引,偏移量则表示句子中每个词汇的位置,输出是一个浮点型的张量,每个浮点数都代表着对应句子的词嵌入向量的均值或总和。

示例(在1.2示例的基础上将两个句子转换为词嵌入向量并计算它们的均值)

import torch
import torch.nn as nn

vocab_size = 12      #词汇表大小
embedding_dim = 4    #嵌入向量的维度

#创建一个Embedding层
embedding_bag = nn.EmbeddingBag(vocab_size, embedding_dim)

#假设有一个包含两个单词索引的输入序列
input_sequence1 = torch.tensor([1, 5, 8], dtype=torch.long)
input_sequence2 = torch.tensor([2, 4], dtype=torch.long)

input_sequences = torch.cat([input_sequence1, input_sequence2])

offsets = torch.tensor([0, len(input_sequence1)], dtype=torch.long)
#使用Embedding层将输入序列转换为词嵌入
embedded_bag = embedding_bag(input_sequences,offsets)

print(embedded_bag)

输出结果:

tensor([[ 0.6257, -1.3751, -0.7692, -0.7584],
        [ 0.5431, -0.4553, -0.1833,  0.6991]], grad_fn=<EmbeddingBagBackward0>)

进程已结束,退出代码 0

PS:EmbeddingBag层中的mode参数用于指定如何对每个序列中的嵌入向量进行汇总,常用的模式有三种——‘sum’、‘mean’、‘max’

  • sum模式:将每个序列中的嵌入向量相加,例如,假设有一个序列[2,3,1],每个数字表示一个离散特征的索引,对应的嵌入向量分别为[0.1,0.2,0.3]、[0.2,0.3,0.4]和[0.3,0.4,0.5],则使用'sum’模式汇总后的嵌入向量为[0.6,0.9,1.2];
  • mean模式:将每个序列中的嵌入向量求平均值,例如,使用上述序列和嵌入向量,使用mean模式汇总后的嵌入向量为[0.2,0.3,0.4];
  • max模式:将每个序列中的嵌入向量取最大值,例如,使用上述序列和嵌入向量,使用max模式汇总后的嵌入向量为[0.3,0.4,0.5]

模式的选取通常取决于具体的任务和数据集,例如在文本分类任务中,通常使用mean模型,因为它可以捕捉到每个序列的平均嵌入,反映出序列的整体含义,而在序列标注任务中,通常使用sum模式,因为它可以捕捉到每个序列的所有信息,不会丢失任何关键信息,在实际应用中,可以根据具体情况灵活选择汇总模式,以获得最佳效果。

二、练习任务

2.1任务要求

.txt文件内容如下,加载.txt文件,并使用Embedding和Embeddingbag完成词嵌入

2.2 实现代码

import torch
import jieba

# 确认打开的文本文件路径和文件名
file_name = "任务文件.txt"

# 从文件中读取文本行,并替代预定义的Sentences
with open(file_name, "r", encoding="utf-8") as file:
    context = file.read()
    sentences = context.split()
    print("文本分句: \n", sentences)     # 打印核对结果

# 使用jieba.cut()函数逐句进行分词,结果输出为一个列表
tokenized_texts = [list(jieba.lcut(sentence)) for sentence in sentences]
print("分词结果:\n", tokenized_texts)   # 打印核对结果

# 构建词汇表
word_index = {}
index_word = {}
for i, word in enumerate(set([word for text in tokenized_texts for word in text])):
    word_index[word] = i
    index_word[i]= word

print("词汇表: \n", word_index)          # 打印核对结果

# 将文本转化为整数序列
sequences = [[word_index[word] for word in text] for text in tokenized_texts]
print("文本序列: \n",sequences)          # 打印核对结果

# 获取词汇表大小, 并+1
vocab_size = len(word_index) + 1
# 创建一个EmbeddingBag层
embedding_dim = 100               # 定义嵌入向量的维度
embedding_bag = torch.nn.EmbeddingBag(vocab_size, embedding_dim, mode="mean")

# 将多个输入序列拼接在一起,并创建一个偏移量张量
# 首先需要创建空张量和空列表
input = torch.tensor([], dtype=torch.long)
offset = []
# 逐句处理,进行张量拼接、向列表中添加偏移量数值
for sequence in sequences:
    offset.append(len(input))
    input = torch.cat([input, torch.tensor(sequence, dtype=torch.long)])
# 将列表形式的偏移量转换为张量形式,用于embedding_bag()函数的输入
offset = torch.tensor(offset, dtype=torch.long)
# 检查序列张量拼接和索引生成结果
print("-"*80)
print(offset)
print(input)
print("-"*80)
# 使用Embedding层将输入序列转换为词嵌入
embedded_bag = embedding_bag(input, offset)
# 打印输出结果
print("词嵌入结果: \n", embedded_bag)

输出结果:

文本分句: 
 ['比较直观的编码方式是采用上面提到的字典序列。例如,对于一个有三个类别的问题,可以用1、2和3分别表示这三个类别。但是,这种编码方式存在一个问题,就是模型可能会错误地认为不同类别之间存在一些顺序或距离关系,而实际上这些关系可能是不存在的或者不具有实际意义的。', '为了避免这种问题,引入了one-hot编码(也称独热编码)。one-hot编码的基本思想是将每个类别映射到一个向量,其中只有一个元素的值为1,其余元素的值为0。这样,每个类别之间就是相互独立的,不存在顺序或距离关系。例如,对于三个类别的情况,可以使用如下的one-hot编码:']
Loading model cost 0.342 seconds.
Prefix dict has been built successfully.
分词结果:
 [['比较', '直观', '的', '编码方式', '是', '采用', '上面', '提到', '的', '字典', '序列', '。', '例如', ',', '对于', '一个', '有', '三个', '类别', '的', '问题', ',', '可以', '用', '1', '、', '2', '和', '3', '分别', '表示', '这', '三个', '类别', '。', '但是', ',', '这种', '编码方式', '存在', '一个', '问题', ',', '就是', '模型', '可能', '会', '错误', '地', '认为', '不同', '类别', '之间', '存在', '一些', '顺序', '或', '距离', '关系', ',', '而', '实际上', '这些', '关系', '可能', '是', '不', '存在', '的', '或者', '不', '具有', '实际意义', '的', '。'], ['为了', '避免', '这种', '问题', ',', '引入', '了', 'one', '-', 'hot', '编码', '(', '也', '称', '独热', '编码', ')', '。', 'one', '-', 'hot', '编码', '的', '基本', '思想', '是', '将', '每个', '类别', '映射', '到', '一个', '向量', ',', '其中', '只有', '一个', '元素', '的', '值', '为', '1', ',', '其余', '元素', '的', '值', '为', '0', '。', '这样', ',', '每个', '类别', '之间', '就是', '相互', '独立', '的', ',', '不', '存在', '顺序', '或', '距离', '关系', '。', '例如', ',', '对于', '三个', '类别', '的', '情况', ',', '可以', '使用', '如下', '的', 'one', '-', 'hot', '编码', ':']]
词汇表: 
 {'有': 0, '。': 1, '编码方式': 2, '直观': 3, '顺序': 4, '模型': 5, ',': 6, '的': 7, '称': 8, '关系': 9, '分别': 10, '问题': 11, '或': 12, '或者': 13, '不': 14, '其中': 15, '序列': 16, '相互': 17, '其余': 18, '独立': 19, '三个': 20, '地': 21, '-': 22, '使用': 23, '具有': 24, '存在': 25, '为了': 26, '向量': 27, '情况': 28, '独热': 29, '避免': 30, '可以': 31, '一个': 32, '值': 33, '为': 34, '2': 35, '一些': 36, '、': 37, '编码': 38, '字典': 39, '思想': 40, '错误': 41, '用': 42, '到': 43, '类别': 44, '比较': 45, '这种': 46, '不同': 47, '0': 48, '3': 49, '元素': 50, '例如': 51, '将': 52, '这些': 53, '和': 54, '就是': 55, '距离': 56, '映射': 57, '可能': 58, '表示': 59, '基本': 60, '实际意义': 61, '会': 62, '提到': 63, ')': 64, '(': 65, '实际上': 66, '之间': 67, '采用': 68, '引入': 69, '但是': 70, 'hot': 71, '上面': 72, '认为': 73, '每个': 74, '这样': 75, '只有': 76, '1': 77, 'one': 78, '而': 79, ':': 80, '如下': 81, '对于': 82, '这': 83, '是': 84, '了': 85, '也': 86}
文本序列: 
 [[45, 3, 7, 2, 84, 68, 72, 63, 7, 39, 16, 1, 51, 6, 82, 32, 0, 20, 44, 7, 11, 6, 31, 42, 77, 37, 35, 54, 49, 10, 59, 83, 20, 44, 1, 70, 6, 46, 2, 25, 32, 11, 6, 55, 5, 58, 62, 41, 21, 73, 47, 44, 67, 25, 36, 4, 12, 56, 9, 6, 79, 66, 53, 9, 58, 84, 14, 25, 7, 13, 14, 24, 61, 7, 1], [26, 30, 46, 11, 6, 69, 85, 78, 22, 71, 38, 65, 86, 8, 29, 38, 64, 1, 78, 22, 71, 38, 7, 60, 40, 84, 52, 74, 44, 57, 43, 32, 27, 6, 15, 76, 32, 50, 7, 33, 34, 77, 6, 18, 50, 7, 33, 34, 48, 1, 75, 6, 74, 44, 67, 55, 17, 19, 7, 6, 14, 25, 4, 12, 56, 9, 1, 51, 6, 82, 20, 44, 7, 28, 6, 31, 23, 81, 7, 78, 22, 71, 38, 80]]
--------------------------------------------------------------------------------
tensor([ 0, 75])
tensor([45,  3,  7,  2, 84, 68, 72, 63,  7, 39, 16,  1, 51,  6, 82, 32,  0, 20,
        44,  7, 11,  6, 31, 42, 77, 37, 35, 54, 49, 10, 59, 83, 20, 44,  1, 70,
         6, 46,  2, 25, 32, 11,  6, 55,  5, 58, 62, 41, 21, 73, 47, 44, 67, 25,
        36,  4, 12, 56,  9,  6, 79, 66, 53,  9, 58, 84, 14, 25,  7, 13, 14, 24,
        61,  7,  1, 26, 30, 46, 11,  6, 69, 85, 78, 22, 71, 38, 65, 86,  8, 29,
        38, 64,  1, 78, 22, 71, 38,  7, 60, 40, 84, 52, 74, 44, 57, 43, 32, 27,
         6, 15, 76, 32, 50,  7, 33, 34, 77,  6, 18, 50,  7, 33, 34, 48,  1, 75,
         6, 74, 44, 67, 55, 17, 19,  7,  6, 14, 25,  4, 12, 56,  9,  1, 51,  6,
        82, 20, 44,  7, 28,  6, 31, 23, 81,  7, 78, 22, 71, 38, 80])
--------------------------------------------------------------------------------
词嵌入结果: 
 tensor([[-0.0028,  0.0883, -0.1803, -0.0017, -0.0561, -0.0496,  0.0610,  0.0799,
          0.0215, -0.1439, -0.3511, -0.0244, -0.1269,  0.0621, -0.1917, -0.0330,
         -0.0108, -0.0143,  0.1122,  0.0086, -0.1345, -0.1837,  0.1484,  0.0031,
         -0.0627,  0.0307,  0.1063,  0.1553,  0.3025,  0.2026, -0.2784,  0.0885,
          0.0741,  0.1068,  0.0560, -0.1928, -0.1547,  0.2161,  0.2422,  0.2020,
          0.1286, -0.0543,  0.3036,  0.0410,  0.0630,  0.2551,  0.1188, -0.0403,
         -0.0871,  0.1336,  0.0515, -0.0873, -0.1294, -0.2602,  0.2367, -0.2241,
          0.1964, -0.1551, -0.3029,  0.1840,  0.0770, -0.0770, -0.0226, -0.1519,
          0.3536,  0.1987, -0.0469, -0.3632,  0.0950, -0.0976,  0.0756, -0.1388,
         -0.0878, -0.0055,  0.0851,  0.0243,  0.0860,  0.0094,  0.0794,  0.0887,
          0.0170,  0.0032,  0.0632, -0.0476,  0.0946, -0.1442,  0.1408, -0.0956,
         -0.0719, -0.0244,  0.1289,  0.2144,  0.0929,  0.2216,  0.0381,  0.0060,
         -0.0706,  0.0095,  0.0120,  0.0249],
        [ 0.1284,  0.3078, -0.1073, -0.0893, -0.0442,  0.0480,  0.2314,  0.3570,
          0.1892, -0.0687, -0.3248,  0.1977, -0.0051,  0.0833,  0.0205, -0.0424,
          0.1120,  0.0081, -0.0332,  0.0675, -0.1181, -0.4904, -0.2325,  0.3382,
          0.2005, -0.0265, -0.0373,  0.0288,  0.1449,  0.3063, -0.3906,  0.1438,
          0.0045,  0.0732, -0.1817, -0.0577, -0.0849,  0.0446,  0.0474,  0.2678,
         -0.1891, -0.0364,  0.2461,  0.1305,  0.2117,  0.1139,  0.3798,  0.1735,
          0.0087,  0.1314,  0.0134, -0.0435, -0.1014, -0.1785,  0.2012, -0.0962,
          0.1756, -0.0697, -0.0561,  0.3970,  0.0581, -0.0891,  0.1152, -0.0571,
          0.2871,  0.1138, -0.1827, -0.2865,  0.0237, -0.0835,  0.2664, -0.1628,
         -0.0767,  0.1087, -0.0632,  0.0504, -0.1810,  0.1344,  0.0688, -0.0080,
          0.0405,  0.1930,  0.2549,  0.0585,  0.1745, -0.3068,  0.2549, -0.3024,
         -0.0840,  0.0148,  0.1119,  0.0125, -0.2456, -0.0398,  0.1784,  0.0605,
          0.1001, -0.0087,  0.0550,  0.1379]], grad_fn=<EmbeddingBagBackward0>)


总结

学习了Embedding和EmbeddingBag的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值