N2 - Embeddingbag与Embedding



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

上周将文本转换为字典序列、one-hot编码,就是最早期的词嵌入方法

EmbeddingEmbeddingBag是pytorch中用来处理文本数据中词嵌入(word embedding)的工具,它们将离散的词汇映射到低维的连续向量空间中,使得词汇之间的语义关系能够在向量空间中得到体现。

Embedding

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

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

  • 可以用作深度学习模型的一部分,其中嵌入与模型本身一起被学习
  • 可以用于加载训练好的词嵌入模型
    嵌入层往往被定义为网络的第一个隐藏层。

函数原型

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)
  • num_embeddings 词汇表的大小,最大整数index + 1
  • embedding_dim 词向量的维度

示例

import torch
import torch.nn as nn

vocab_szie = 12
embedding_dim = 4

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)

执行结果
通过上面的例子,我们将大小为12的词汇表中的每个词汇映射到一个4维的向量空间中。

EmbeddingBag

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

示例

import torch
import torch.nn as nn

vocab_size =12
embedding_dim = 4

embedding_bag = nn.EmbeddingBag(vocab_size, embedding_dim, mode='mean')

# 造2个假的输入序列
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_bag = embedding_bag(input_sequences, offsets)

print(embedding_bag)

输出
在上面的例子中,我们定义将大小为12的词汇表映射到4维向量的嵌入层,然后输入了两个句子,返回的结果形状为2,4,正好对应于句子的个数和向量的维度。

EmbeddingBag层中的mode参数用于指定如何对每个序列中的嵌入向量进行汇总,常用的模式有三种:summeanmax

  • sum 将每个序列中的嵌入向量相加
  • mean 将每个序列中的嵌入向量求平均值
  • max 将每个序列中的嵌入向量取最大值

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

任务

import jieba
# 文本处理
content = open('task.txt', 'r').read()
lines = content.strip().split('\n')

word_index = {}
index_word = {}
idx = 0

# 制作并获取字典序号
def get(word):
	global idx
	if word not in word_index:
		word_index[word] = idx
		index_word[idx] = word
		idx += 1
	return word_index[word]

vectors = []
for line in lines:
	vec = []
	for word in jieba.cut(line):
		i = get(word)
		vec.append(i)
	vectors.append(vec)

print('vocab_size:', len(word_index))
print('vector:', vectors)

输出结果

使用Embedding完成词嵌入

embedding = nn.Embedding(len(word_index), 32)

for vec in vectors:
	inputs = torch.tensor(vec, dtype=torch.long)
	output = embedding(inputs)
	print(output)

embedding嵌入

使用EmbeddingBag完成词嵌入

embedding_bag = nn.EmbeddingBag(len(word_index), 32, mode='mean')
offsets = torch.tensor([0, len(vectors[0])], dtype=torch.long)

inputs = torch.cat([torch.tensor(vec, dtype=torch.long) for vec in vectors])
outputs = embedding_bag(inputs, offsets)
print(outputs)

lEmbeddingBag输出

总结与心得体会

在没有进行代码实践以前,我一直以为词嵌入是基于输入的,不论是句子还是词汇,输出的都是固定维度的向量。也就是EmbeddingBag,而真正的Embedding是只针对词来做处理的。

还有一个值得注意的点是,EmbeddingBag层计算时要求输入的offsets其实是每个句子的起始索引。这里面包含了两个知识点,一个是,我们使用torch.cat实际将两个句子无缝合并成了一个向量。然后使用offsets来提供每个句子的起始索引。因此登假设offsets中有N个索引,最终的输出结果就是(N,32)维度的向量。

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值