通俗讲解pytorch中nn.Embedding原理及使用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通俗讲解pytorch中nn.Embedding原理及使用相关的知识,希望对你有一定的参考价值。
参考技术A其为一个简单的存储固定大小的词典的嵌入向量的查找表,意思就是说,给一个编号,嵌入层就能返回这个编号对应的嵌入向量,嵌入向量反映了各个编号代表的符号之间的语义关系。
输入为一个编号列表,输出为对应的符号嵌入向量列表。
torch.nn包下的Embedding,作为训练的一层,随模型训练得到适合的词向量。
找到对应的词向量放进网络:词向量的输入应该是什么样子
实际上,上面通过随机初始化建立了词向量层后,建立了一个“二维表”,存储了词典中每个词的词向量。每个mini-batch的训练,都要从词向量表找到mini-batch对应的单词的词向量作为RNN的输入放进网络。那么怎么把mini-batch中的每个句子的所有单词的词向量找出来放进网络呢, 输入是什么样子,输出是什么样子?
首先我们知道肯定先要建立一个词典,建立词典的时候都会建立一个dict:word2id:存储单词到词典序号的映射。假设一个mini-batch如下所示:
显然,这个mini-batch有3个句子,即batch_size=3
第一步首先要做的是:将句子标准化,所谓标准化,指的是:大写转小写,标点分离,这部分很简单就略过。经处理后,mini-batch变为:
可见,这个list的元素成了一个个list。还要做一步:将上面的三个list按单词数从多到少排列。标点也算单词。至于为什么,后面会说到。
那就变成了:
可见,每个句子的长度,即每个内层list的元素数为:5,5,4。这个长度也要记录。
之后,为了能够处理,将batch的单词表示转为在词典中的index序号,这就是word2id的作用。转换过程很简单,假设转换之后的结果如下所示,当然这些序号是我编的。
同时,每个句子结尾要加EOS,假设EOS在词典中的index是1。
那么长度要更新:
很显然,这个mini-batch中的句子长度 不一致! 所以为了规整的处理,对长度不足的句子,进行填充。填充PAD假设序号是2,填充之后为:
这样就可以直接取词向量训练了吗?
不能!上面batch有3个样例,RNN的每一步要输入每个样例的一个单词,一次输入batch_size个样例,所以batch要按list外层是时间步数(即序列长度),list内层是batch_size排列。即batch的维度应该是:
重要的问题说3遍!
怎么变换呢?变换方法可以是:使用itertools模块的zip_longest函数。而且,使用这个函数,连填充这一步都可以省略,因为这个函数可以实现填充!
经变换,结果应该是:
记得我们还记录了一个lens:
batch还要转成LongTensor:
这里的batch就是词向量层的输入。
词向量层的输出是什么样的?
好了,现在使用建立了的embedding直接通过batch取词向量了,如:
假设词向量维度是6,结果是:
维度的前两维和前面讲的是一致的。可见多了一个第三维,这就是词向量维度。所以,Embedding层的输出是:
每天讲解一点PyTorch nn.Embedding
今天我们讲解创建词嵌入模型
nn.Embedding(5, 6)
代表5个词(总共有多少个词)6维度(每个词的编码维度),5x6矩阵
>>> import torch
>>> import torch.nn as nn
>>>
>>> embeds = nn.Embedding(5, 6)
>>> embeds
Embedding(5, 6)
>>>
>>> import torch
>>> import torch.nn as nn
>>>
>>> embeds = nn.Embedding(5, 6)
>>> embeds
Embedding(5, 6)
>>> # I like cv
>>> # 1 2 3
>>> word = [[1,2,3],[0,0,3]]
>>> x = torch.LongTensor(word)
>>> x
tensor([[1, 2, 3],
[0, 0, 3]])
>>> embed_ = embeds(torch.LongTensor(word))
>>>
>>> embed_
tensor([[[ 1.1774, 0.0840, 1.2077, 0.3492, -0.1718, -0.2256],
[-1.1595, 0.2247, 0.8931, -0.6904, -0.3020, -0.4171],
[-2.2413, 0.3168, -0.1047, 0.8574, -0.2742, 0.1194]],
[[ 1.7274, 0.9688, -1.2030, 1.0693, -0.5663, 1.8714],
[ 1.7274, 0.9688, -1.2030, 1.0693, -0.5663, 1.8714],
[-2.2413, 0.3168, -0.1047, 0.8574, -0.2742, 0.1194]]],
grad_fn=<EmbeddingBackward>)
>>> embed_.shape
torch.Size([2, 3, 6])
>>>
输入维度:2x3的词
每个词编码:6维度向量
>>> word = [1,2,3]
>>> word
[1, 2, 3]
>>> embed_ = embeds(torch.LongTensor(word))
>>> embed_
tensor([[ 1.1774, 0.0840, 1.2077, 0.3492, -0.1718, -0.2256],
[-1.1595, 0.2247, 0.8931, -0.6904, -0.3020, -0.4171],
[-2.2413, 0.3168, -0.1047, 0.8574, -0.2742, 0.1194]],
grad_fn=<EmbeddingBackward>)
>>>
>>> embed_.shape
torch.Size([3, 6])
>>>
输入维度:3的词
每个词编码:6维度向量
>>> embeds = nn.Embedding(4, 6)
>>> embeds
Embedding(4, 6)
>>> word
[1, 2, 3]
>>> x = torch.LongTensor(word)
>>> x
tensor([1, 2, 3])
>>>
>>> embed_ = embeds(x)
>>> embed_
tensor([[ 1.8449, 0.3119, -0.0317, -0.7793, -0.6710, 0.0316],
[ 0.8638, -1.2257, 0.5386, -0.6412, 1.4129, 0.0926],
[ 0.5742, 1.2701, 0.3415, 0.3161, -1.7954, 0.8924]],
grad_fn=<EmbeddingBackward>)
>>>
>>> embeds = nn.Embedding(len("0123456789"), 6)
>>> embeds
Embedding(10, 6)
>>>
以上是关于通俗讲解pytorch中nn.Embedding原理及使用的主要内容,如果未能解决你的问题,请参考以下文章
PyTorch之 torch.nn.Embedding 词嵌入层的理解