本文主要介绍一下 torch.nn.Embedding词嵌入过程。因为使用one-hot矩阵表示,在词汇表很长的情况会有很多0的 稀疏矩阵,所以使用稠密矩阵维度会降低很多,也能利用0的空间。这里讲这个的主要目的是给词嵌入过程一个清晰的变换过程,因为很多书讲这个的时候容易混淆概念,导致理解混乱。token我们一般只的是一个词,看代码或者一些说明的时候容易把句子和词表达混淆。

词向量,一行表示一个句子,每个数字代表在词汇表中的索引 shape 2 x 2
[
   [ 1, 2],
   [ 3, 4]
]

词汇表 shape 4 x 3 每行代表一个词,用三维数据表示
1 [ 1.6890, -0.4711, -0.6101]
2 [ 0.6656,  0.5407,  0.8291]
3 [ 1.3748, -1.1127,  0.0891]
4 [-0.5369, -0.6016, -0.4132]

通过将索引替换后变成 2 x 2 x 3
[
  [
     [ 1.6890, -0.4711, -0.6101],[ 0.6656,  0.5407,  0.8291]
  ],
  [
    [ 1.3748, -1.1127,  0.0891],[-0.5369, -0.6016, -0.4132]
  ]
]

        下面给出一个比较具体的例子

1 样本数据

样本1 我爱你
样本2 你也爱我

2 构建词汇表

    词汇表我们可以按照拼音简单排序(如果是用python 的sorted函数,那么使用的是unicode排序)。

         [  ’  ‘,’爱‘,’你‘,’我‘、’也‘  ]

索引: 0,   1,    2,   3,   4 

        这里我在词汇表里面加了一个空字符。

3 样本转换成词矩阵

样本1 我爱你 [3,1,2]
样本2 你也爱我 [2,4,1,3]


4 标准化

        我们假设允许句子最长为5,那么词矩阵可以在长度不足情况下添加0补齐

样本1 我爱你 [3,1,2,0,0]
样本2 你也爱我 [2,4,1,3,0]

        这里搞成这个样子的原因是pytorch里面神经网络都是基于矩阵运算的。长度不一样估计不好处理,第2步' '对应0的用意是防止0造成意义干扰。如果不加会变成下面这样:

         [  ’爱‘,’你‘,’我‘、’也‘  ]

索引:  0,   1,   2,   3

样本1 我爱你 [2,0,1]
样本2 你也爱我 [1,3,0,2]

         填充0后会造成歧义,当然这里只是我发现的一个问题,想了这么一个处理办法。

样本1 我爱你 [2,0,1,0,0] (我爱你爱爱)
样本2 你也爱我 [1,3,0,2,0]  (你也爱我爱)

5 确定词嵌入形状

       这里词汇表长度是5,词嵌入矩阵input_size=5+1=6,假设我们想输出两个维度的词嵌入向量,我们可以设转换矩阵为(第一列是索引,实际上不需要存储,系数也是随便初始化的,方便演示):

0 0.1 0.9
1 0.2 0.6
2 0.5 0.5
3 0.6 0.3
4 0.8 0.2
5 0.9 0.1

6 查找嵌入表

 这里以样本1 [3,1,2,0,0] 为例子

3 [ 0.6,0.3 ]
1 [ 0.2,0.6 ]
2 [ 0.5,0.5 ]
0 [ 0.1,0.1 ]
0 [ 0.1,0.1 ]

样本1 就变成了[ [ 0.6,0.3 ],[ 0.2,0.6 ],[ 0.5,0.5 ],[ 0.1,0.1 ],[ 0.1,0.1 ]]

样本2也同样的方式处理,输出为 2 x 5 x 2

更多推荐