引言
Word Embedding(词嵌入)是Dimension Reduction的一个典型应用。
对于单词的表示,可以使用
o
n
e
−
h
o
t
one-hot
one−hot编码来表示。如下图:
对于 o n e − h o t one-hot one−hot编码来说,词义相近的单词之间并没有联系;如我们不能从 c a t cat cat和 d o g dog dog的 o n e − h o t one-hot one−hot编码中学习到猫和狗在词义上是相近的。
Word Class
为了保证将单词编码化后,还能够保留单词之间的关联,将具有相同性质的单词进行聚类,划分多个 c l a s s class class,使用 c l a s s class class的编码去代表 c l a s s class class中的单词;如下图:
但是Word Class还是不能够表达出不同class之间单词的关联。
Word Embedding
可参看吴恩达词嵌入笔记
Word Embedding(词嵌入)将每个单词都投影到高维空间上,这里的高维空间相比于 o n e − h o t one-hot one−hot编码的维度小的很多;
如对于十万个单词进行编码表示, o n e − h o t one-hot one−hot的编码的维度是十万维,而Word Embedding可能仅需要50~100维度即可。这就是为什么说Word Embedding(词嵌入)是Dimension Reduction的一个典型应用。
Word Embedding是无监督学习,在没有标签数据集的情况下通过阅读大量文档来学习单词的含义,而一个单词的含义以通过上下文来理解。即Word Embedding是一种通过上下文学习单词特征向量的无监督学习方法。
能否利用Auto-encoder来进行Word Embedding呢?
答案是不能的,因为对于词嵌入矩阵的学习,我们的输入是one-hot编码,而one-hot编码没有包含文字的信息,auto-encoder学不出东西来。
How to exploit the context?
我们如何挖掘句子的上下文学习出词嵌入矩阵呢?
第一种方式:
Count based:
基本思想:若单词 w i w_i wi和 w j w_j wj之间经常一起出现,那么 w i w_i wi和 w j w_j wj对应的向量 V ( w i ) V(w_i) V(wi)和 V ( w j ) V(w_j) V(wj)就会很接近。
这个思想很类似于之前矩阵分解的思想(宅男和角色之间相似度很大,内积就会很大):若 w i w_i wi和 w j w_j wj同时出现的次数很多,那么 V ( w i ) V(w_i) V(wi)和 V ( w j ) V(w_j) V(wj)的内积就会很大。
Count based的典型例子是Glove Vector。
第二种方式:
Perdition based
基本思想:通过预测的方式去学习词嵌入矩阵。
⋯ w i − 2 w i − 1 w i \cdots \ \ w_{i-2}\ \ w_{i-1} \ \ \color {red} {w_i} ⋯ wi−2 wi−1 wi
即构建一个通过预测 w i \color {red} {w_i} wi的模型,来学习 w i − 1 w_{i-1} wi−1和 w i w_{i} wi之间的联系,从而学习出 w i − 1 w_{i-1} wi−1的词嵌入向量。
如下图,将单词 w i − 1 w_{i-1} wi−1one-hot编码作为输入,最后的输出与one-hot编码相同维度,含义是每个单词作为下一个单词 w i w_{i} wi的概率。
我们将hidden layer的输入
z
1
,
z
2
,
⋯
z_1,z_2,\cdots
z1,z2,⋯拿出来,作为该单词的词嵌入向量。对于不同单词的one-hot输入,最后可以得到不同的词嵌入向量
Z
Z
Z。
为什么通过预测的方式能够有用呢?
例如,现在存在两句话:
1.
李宏毅 是一个很好的老师。
1. ~~李宏毅~~是一个很好的老师。
1. 李宏毅 是一个很好的老师。
2.
吴恩达 是一个很好的老师。
2. ~~吴恩达~~ 是一个很好的老师。
2. 吴恩达 是一个很好的老师。
虽然“李宏毅”、“吴恩达”这两个单词之间看上去并没有联系,但是下文词句是一样的,所以可能会认为这两个单词在含以上可能是类似的,这两个单词都代表了老师的名字。
在上述模型中“李宏毅”、“吴恩达”这两个单词就代表了输入 w i − 1 w_{i-1} wi−1,"是一个很好的老师"就代表 w i w_i wi。
对于下图的神经网络预测模型来说,这两个不同单词的输出是一样的,所以在训练的过程中会通过调整第一层的权重,使这两个单词的输出 Z Z Z经可能的类似,即将这两个单词的one-hot编码投影到位置相近的低维空间上。
所以即使两个单词的one-hot编码不同,但是通过学习调整权重,将这两个不同的编码映射到相近的位置上。(这两个单词被映射到相近的位置上,才能够确保下一个单词的预测是相同的。)
可能觉得通过当前词汇预测下一个词汇这个约束太弱了,因为一个单词可以和很多个单词进行配对。
对于这个问题,可以对当前词汇数量进行扩展,如使用10个以上的词汇数量来预测下一个单词,这样学习到的词嵌入矩阵效果可能会更好。
在这里以2个当前词汇为例子,神经网络结构如下图:
在这里我们将两个词汇
w
i
−
2
w_{i-2}
wi−2和
w
i
−
1
w_{i-1}
wi−1的on-hot编码分别与其对应的权重矩阵
W
1
W_1
W1和
W
2
W_2
W2相乘,将结果相加作为输入,即:
z
=
W
1
⋅
o
n
e
h
o
t
(
w
i
−
1
)
+
W
2
⋅
o
n
e
h
o
t
(
w
i
−
2
)
(1)
z=W_1\cdot onehot(w_{i-1})+W_2\cdot onehot(w_{i-2})\tag1
z=W1⋅onehot(wi−1)+W2⋅onehot(wi−2)(1)
在这里我们希望 W 1 W_1 W1和 W 2 W_2 W2是相同的,因为当 w i − 2 w_{i-2} wi−2和 w i − 1 w_{i-1} wi−1是同一个词的时候,输出的词嵌入向量是一致的,即希望在这个网络结构中词嵌入矩阵是唯一的。
这里的 W 1 W_1 W1和 W 2 W_2 W2就是吴恩达老师里面提到的词嵌入矩阵,将词嵌入矩阵与one-hot编码相乘,得到对应的词嵌入向量
因为 W 1 W_1 W1和 W 2 W_2 W2是相同的, W 1 = W 2 = W W_1=W_2=W W1=W2=W,式子(1)可以简化为:
z = W 1 ⋅ o n e h o t ( w i − 1 ) + W 2 ⋅ o n e h o t ( w i − 2 ) = W ⋅ ( o n e h o t ( w i − 1 ) + o n e h o t ( w i − 2 ) ) z=W_1\cdot onehot(w_{i-1})+W_2\cdot onehot(w_{i-2})=W\cdot (onehot(w_{i-1})+onehot(w_{i-2})) z=W1⋅onehot(wi−1)+W2⋅onehot(wi−2)=W⋅(onehot(wi−1)+onehot(wi−2))
所以 W W W是我们需要学习得到的目标。
如何确保 W 1 W_1 W1和 W 2 W_2 W2是相同的呢?
- 首先对 W 1 W_1 W1和 W 2 W_2 W2赋一样的初始值
- 然后确保更新过程相同,更新式子如下:
w 1 = w 1 − η ∂ L ∂ w 1 − η ∂ L ∂ w 2 w_1=w_1-η\frac{∂L}{∂w_1}-η\frac{∂L}{∂w_2} w1=w1−η∂w1∂L−η∂w2∂L
w 2 = w 2 − η ∂ L ∂ w 2 − η ∂ L ∂ w 1 w_2=w_2-η\frac{∂L}{∂w_2}-η\frac{∂L}{∂w_1} w2=w2−η∂w2∂L−η∂w1∂L
除了通过前两个单词来预测下一个单词,我们也可以通过其他方式来训练词嵌入矩阵,如下图:
- CBOW(Continuous bag of word model):通过前后两个单词来预测中间的单词
- Skip-gram:通过中间单词来预测前后的两个单词
虽然词嵌入是deep learning的一个应用,但是其中的neural network其实并不是deep的;其实这个neural network只有一个linear的hidden layer
.
即我们把one-hot编码输入给神经网络,经过权重 W W W的转换得到词嵌入向量,再通过第一层hidden layer就可以直接得到输出
其实过去有很多人使用过deep model,但这个任务不用deep就可以实现,这样做既可以减少运算量,还可以节省下训练的时间。
因结构简单,就可以训练海量的句子了。
词嵌入向量的特性
在实际应用中,会发现相同联系的单词对之间是平行的关系,如下图:
我们将单词词嵌入向量进行两两相减,投影到二维平面上进行可视化,会发现若两个单词之间包含相同的关系,就会被投影到同一块区域,如下图:
类似的还有:
𝑉 ( 𝑅 𝑜 𝑚 𝑒 ) − 𝑉 ( 𝐼 𝑡 𝑎 𝑙 𝑦 ) ≈ 𝑉 ( 𝐵 𝑒 𝑟 𝑙 𝑖 𝑛 ) − 𝑉 ( 𝐺 𝑒 𝑟 𝑚 𝑎 𝑛 𝑦 ) 𝑉(𝑅𝑜𝑚𝑒) − 𝑉(𝐼𝑡𝑎𝑙𝑦)≈ 𝑉(𝐵𝑒𝑟𝑙𝑖𝑛)− 𝑉(𝐺𝑒𝑟𝑚𝑎𝑛𝑦) V(Rome)−V(Italy)≈V(Berlin)−V(Germany)
若有人发问,罗马之于意大利,相当于柏林至于什么呢?
对于这个问题,我们可以通过计算:
𝑉
(
𝐵
𝑒
𝑟
𝑙
𝑖
𝑛
)
−
𝑉
(
𝑅
𝑜
𝑚
𝑒
)
+
𝑉
(
𝐼
𝑡
𝑎
𝑙
𝑦
)
𝑉(𝐵𝑒𝑟𝑙𝑖𝑛)−𝑉(𝑅𝑜𝑚𝑒)+ 𝑉(𝐼𝑡𝑎𝑙𝑦)
V(Berlin)−V(Rome)+V(Italy)
对这个结果去最近的单词,最后我们会得到 𝐺 𝑒 𝑟 𝑚 𝑎 𝑛 𝑦 𝐺𝑒𝑟𝑚𝑎𝑛𝑦 Germany。
Multi-lingual Embedding
词嵌入可以应用于翻译上。
当分别对中文和英文学习词嵌入矩阵,会发现这两个词嵌入矩阵并不存在什么联系。
但是,如果知道一些中文单词和英文单词之间的对应关系,我们可以获取这些单词的词嵌入向量,去训练一个模型,将具有相同含义的中英文单词投影到新空间上的同一个点上。
接下来遇到新的英语单词词汇,可以使用相同的投影方式投影到新的空间上,在新空间上寻找最近的中文向量,就可以做到翻译的效果。
Multi-domain Embedding
类似做法不仅可以用在文本上,还可以使用在图片上。
例子:
如下图,我们希望输入一张图片能够获取图片的主题。
若我们已经获得了auto、horse、dog等单词的词嵌入矩阵(相当于知晓了这些单词在这个向量空间上的分布情况)。
接下来可以训练一个模型,用于将马、汽车、狗的图片进行重编码,映射到对应词汇相同的空间域上。
对于新的图片,我们就可以通过冲编码映射的方式去找到对应的词嵌入向量,判断出图片所属的主题了。
一般在做图像分类时,我们需要预先确定好具体的分类类别,在对数据集进行训练;当遇到未出现的类别是,会不能进行准确的预测。
而image+word Embedding的方法,即使对于未出现的类别,可以通过阅读大量的文本来获取类别信息。