embedding layer 网上个个都将的神乎其神,其本质上就是一个转换。将某一维度的向量转化到另一个维度。看到转换这两个字,很容易想到矩阵相乘。实际上大多数的 embedding layer 就是调用了一下 linear layer。
背景
在 NLP 中,如果用一个数字代表一个汉字,对于某一个待定的汉字,就要用一个非常稀疏的向量来表示它。假设有5000个汉字,那么标识一个汉字要用的向量就是一个5000x1的向量,其中有4999个为0,1个为1。这种方法叫做 one-hot。很明显,这样子效率很低,所以有人想出了这样一个办法,不再用一个数字表示一个汉字,而是使用一组数字来表示这个汉字,这一组数字叫做 latent factors。而 latent factors 究竟由多少个数字组成,则由使用者自己定。
据个例子:
one hot 编码 5 个 字:一(0),二(1),三(2),四(3),五(4)
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
一 | 1 | 0 | 0 | 0 | 0 |
二 | 0 | 1 | 0 | 0 | 0 |
三 | 0 | 0 | 1 | 0 | 0 |
四 | 0 | 0 | 0 | 1 | 0 |
五 | 0 | 0 | 0 | 0 | 1 |
所以一所对应的向量为\((1,0,0,0,0)^T\),二所对应的向量为\((0,1,0,0,0,0)^T\),依次类推。
使用了embedding 后,假设 latent factors 的个数为 3。
一 | 0.11 | 0.23 | 0.97 |
---|---|---|---|
二 | 0.18 | 0.42 | 0.65 |
三 | 0.67 | 0.16 | 0.55 |
四 | 0.12 | 0.27 | 0.21 |
五 | 0.23 | 0.07 | 0.88 |
很明显的节约了不少空间。
为什么需要 embedding layer?
除了上述背景中讲述的能够降低所占空间,提高效率意外,还有一个重要的点。one hot 没有办法表示两个词之间的关系。很容易理解,在语言里面,词与词之间是存在关系的。单纯地使用人造的 0 和 1 来表示词,很难表示这种关系。那么使用 embedding layer 怎么描述这种关系呢?这就只能通过学习来获取这个关系了。所以 embedding layer 是可以学习的,里面的系数描述了词与词之间的关系。
当然了,因为本质就是从一个维度转换到另一个维度,我们也可以单纯将它当作一个映射来用,用来改变向量维度。
embedding layer 的实现
很多情况下,使用一个全相连层就可以了。\(W\) 的 shape 为 (输入的维度,输出的维度)。输入的维度就是原先用多大的 vector 来描述字符,输出的维度就是latent factors 的个数。