成语大全网 - 汉语词典 - pytorch中nn.Embedding原理及使用

pytorch中nn.Embedding原理及使用

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的维度应该是:

怎么变换呢?

变换方法可以是:使用itertools模块的zip_longest函数。而且,使用这个函数,连填充这一步都可以省略,因为这个函数可以实现填充。

经变换,结果应该是:

batch还要转成LongTensor:

这里的batch就是词向量层的输入。

词向量层的输出是什么样的?

好了,现在使用建立了的embedding直接通过batch取词向量了,如:

假设词向量维度是6,结果是:

维度的前两维和前面讲的是一致的。可见多了一个第三维,这就是词向量维度。所以,Embedding层的输出是: