本文参考黄海广主编针对吴恩达深度学习课程DeepLearning.ai 《深度学习课程 笔记 (V5.7 )》
第二周 自然语言处理与词嵌入( Natural Language Processing and Word Embeddings )
2.1 词汇表征(Word Representation )
上周我们学习了 RNN、GRU 单元和 LSTM 单元。本周你会看到我们如何把这些知识用到NLP 上,用于自然语言处理 。
其中一个很关键的概念就是词嵌入(word embeddings),这是语言表示的一种方式,可以让算法自动的理解一些类似的词,比如男人对女人,比如国王对王后,还有其他很多的例子。通过词嵌入的概念你就可以构建 NLP 应用了,即使你的模型标记的训练集相对较小。
现在我们先开始讨论词汇表示,目前为止我们一直都是用词汇表来表示词,上周提到的词汇表,可能是 10000 个单词,我们一直用 one-hot 向量来表示词。比如如果 man(上图编号 1 所示)在词典里是第 5391 个,那么就可以表示成一个向量,只在第 5391 处为 1(上图编号 2 所示),我们用O 5391 代表这个量,这里的O代表 one-hot。
这种表示方法的一大缺点就是它把每个词孤立起来,这样使得算法对相关词的泛化能力不强。
算法很难从已经知道的 orange juice 是一个常见的东西,而明白 apple juice 也是很常见的东西或者说常见的句子。
这是因为任何两个 one-hot 向量的内积都是 0,如果你取两个向量,比如 king和 queen,然后计算它们的内积,结果就是 0。如果用 apple 和 orange 来计算它们的内积,结果也是 0。很难区分它们之间的差别,因为这些向量内积都是一样的,所以无法知道 apple和 orange 要比 king 和 orange,或者 queen 和 orange 相似地多。
换一种表示方式会更好,如果我们不用 one-hot 表示,而是用特征化的表示来表示每个词,man,woman,king,queen,apple,orange 或者词典里的任何一个单词,我们学习这些词的特征或者数值。
1. 举个例子,对于这些词,比如我们想知道这些词与 Gender( 性别)的关系。假定男性的性别为-1,女性的性别为+1,那么 man 的性别值可能就是-1,而 woman 就是-1。最终根据经验 king 就是-0.95,queen 是+0.97,apple 和 orange 没有性别可言。
2. 另一个特征可以是这些词有多 Royal( 高贵),所以这些词,man,woman 和高贵没太关系,所以它们的特征值接近 0。而 king 和 queen 很高贵,apple 和 orange 跟高贵也没太大关系。
3. 那么 Age( 年龄)呢?man 和 woman 一般没有年龄的意思,也许 man 和 woman 隐含着成年人的意思,但也可能是介于 young 和 old 之间,所以它们(man 和 woman)的值也接近 0。而通常 king 和 queen 都是成年人,apple 和 orange 跟年龄更没什么关系了。
4. 还有一个特征,这个词是否是 Food( 食物),man 不是食物,woman 不是食物,king和 queen 也不是,但 apple 和 orange 是食物。
5. 当然还可以有很多的其他特征,从 Size( 尺寸大小),Cost( 花费多少),这个东西是不是 alive( 活的),是不是一个 Action( 动作),或者是不是 Noun( 名词)或者是不是 Verb( 动词),还是其他的等等。
接下来要学的特征表示方法却能使算法高效地发现 apple 和 orange 会比 king 和 orange,queen 和 orange 更加相似。
如果我们能够学习到一个 300 维的特征向量,或者说 300 维的词嵌入,通常我们可以做一件事,把这 300 维的数据嵌入到一个二维空间里,这样就可以可视化了。常用的可视化算法是 t-SNE 算法,来自于 Laurens van der Maaten 和 Geoff Hinton 的论文。如果观察这种词嵌入的表示方法,你会发现 man 和 woman 这些词聚集在一块(上图编号 1 所示),king 和queen 聚集在一块(上图编号 2 所示),这些都是人,也都聚集在一起(上图编号 3 所示)。动物都聚集在一起(上图编号 4 所示),水果也都聚集在一起(上图编号 5 所示),像 1、2、3、4 这些数字也聚集在一起(上图编号 6 所示)。如果把这些生物看成一个整体,他们也聚集在一起(上图编号 7 所示)。
小小结:
1. 词嵌入(word embeddings),这是语言表示的一种方式,可以让算法自动的理解一些类似的词,比如男人对女人,比如国王对王后,还有其他很多的例子。
2. 换一种表示方式会更好,如果我们不用 one-hot 表示,而是用特征化的表示来表示每个词,man,woman,king,queen,apple,orange 或者词典里的任何一个单词,我们学习这些词的特征或者数值。
3. 如果我们能够学习到一个 300 维的特征向量,或者说 300 维的词嵌入,通常我们可以做一件事,把这 300 维的数据嵌入到一个二维空间里,这样就可以可视化了。常用的可视化算法是 t-SNE 算法。
2.2 使用词嵌入(Using Word Embeddings )
已经了解不同单词的特征化表示了。这节你会看到我们如何把这种表示方法应用到 NLP 应用中。
学习词嵌入的算法会考察非常大的文本集,也许是从网上找到的,这样你可以考察很大的数据集可以是 1 亿个单词,甚至达到 100 亿也都是合理的,大量的无标签的文本的训练集。
通过考察大量的无标签文本,你可以发现 orange( 橙子)和 durian( 榴莲)相近,farmer( 农民)和 cultivator( 培育家)相近。因此学习这种嵌入表达,把它们都聚集在一块,通过读取大量的互联网文本发现了 orange( 橙子)和 durian( 榴莲)都是水果。
总结一下,这是如何用词嵌入做迁移学习的步骤。
第一步,先从大量的文本集中学习词嵌入。一个非常大的文本集,或者可以下载网上预训练好的词嵌入模型,网上你可以找到不少,词嵌入模型并且都有许可。
第二步,你可以用这些词嵌入模型把它迁移到你的新的只有少量标注训练集的任务中,比如说用这个 300 维的词嵌入来表示你的单词。这样做的一个好处就是你可以用更低维度的特征向量代替原来的 10000 维的 one-hot 向量,现在你可以用一个 300 维更加紧凑的向量。尽管 one-hot 向量很快计算,而学到的用于词嵌入的 300 维的向量会更加紧凑。
第三步,当你在你新的任务上训练模型时,在你的命名实体识别任务上,只有少量的标记数据集上,你可以自己选择要不要继续微调,用新的数据调整词嵌入。实际中,只有这个第二步中有很大的数据集你才会这样做,如果你标记的数据集不是很大,通常我不会在微调词嵌入上费力气。
词嵌入在语言模型、机器翻译领域用的少一些,尤其是你做语言模型或者机器翻译任务时,这些任务你有大量的数据。在其他的迁移学习情形中也一样,如果你从某一任务 A 迁移到某个任务 B,只有 A 中有大量数据,而 B 中数据少时,迁移的过程才有用。所以对于很多NLP 任务这些都是对的,而对于一些语言模型和机器翻译则不然。
2.3 词嵌入的特性(Properties of Word Embeddings)
这是一系列你希望词嵌入可以捕捉的单词的特征表示,假如我提出一个问题,man 如果对应 woman,那么 king 应该对应什么?你们应该都能猜到 king 应该对应 queen。能否有一种算法来自动推导出这种关系,下面就是实现的方法。
正式地探讨一下应该如何把这种思想写成算法。在图中,词嵌入向量在一个可能有 300 维的空间里,于是单词 man 代表的就是空间中的一个点,另一个单词 woman 代表空间另一个点,单词 king 也代表一个点,还有单词 queen 也在另一点上(上图编号 1 方框内所示的点)。事实上,我们在上个幻灯片所展示的就是向量 man 和 woman 的差值非常接近于向量 king 和 queen 之间的差值,我所画的这个箭头(上图编号 2 所示)代表的就是向量在 gender( 性别)这一维的差,不过不要忘了这些点是在 300 维的空间里。为了得出这样的类比推理,计算当 man 对于 woman,那么 king 对于什么,你能做的就是找到单词 w 来使得
在继续下一步之前,我想再说明一下左边的这幅图(上图编号 1 所示),在之前我们谈到过用 t-SNE 算法来将单词可视化。t-SNE 算法所做的就是把这些 300 维的数据用一种非线性的方式映射到 2 维平面上,可以得知 t-SNE 中这种映射很复杂而且很非线性。在进行 t-SNE映射之后,你不能总是期望使等式成立的关系,会像左边那样成一个平行四边形,尽管在这
个例子最初的 300 维的空间内你可以依赖这种平行四边形的关系来找到使等式成立的一对类比,通过 t-SNE 算法映射出的图像可能是正确的。但在大多数情况下,由于 t-SNE 的非线性映射,你就没法再指望这种平行四边形了,很多这种平行四边形的类比关系在 t-SNE 映射中都会失去原貌。
再快速地列举一个最常用的相似度函数,这个最常用的相似度函数叫做余弦相似度。这是我们上个幻灯片所得到的等式(下图编号 1 所示),在余弦相似度中,假如在向量u和v之间定义相似度:
2.4 嵌入矩阵(Embedding Matrix )
当你应用算法来学习词嵌入时,实际上是学习一个嵌入矩阵 。
假设我们的词汇表含有 10,000 个单词,词汇表里有 a,aaron,orange,zulu,可能还有一个未知词标记<UNK>。我们要做的就是学习一个嵌入矩阵E,它将是一个300×10,000 的矩阵,如果你的词汇表里有 10,000 个,或者加上未知词就是 10,001 维。这个矩阵的各列代表的是词汇表中 10,000 个不同的单词所代表的不同向量。假设 orange 的单词编号是 6257(下图编号 1 所示),代表词汇表中第 6257 个单词,我们用符号O 6527 来表示这个 one-hot 向量,这个向量除了第 6527 个位置上是 1(下图编号 2 所示),其余各处都为0,显然它是一个 10,000 维的列向量,它只在一个位置上有 1,它不像图上画的那么短,它的高度应该和左边的嵌入矩阵的宽度相等。
假设这个嵌入矩阵叫做矩阵E,注意如果用O去乘以右边的 one-hot 向量(上图编号 3 所示),也就是O6527 ,那么就会得到一个 300 维的向量,E是 300×10,000 的,O 6527 是 10,000×1的,所以它们的积是 300×1 的,即 300 维的向量。要计算这个向量的第一个元素,你需要做的是把O的第一行(上图编号 4 所示)和O 6527 的整列相乘,不过O 6527 的所有元素都是 0,只有 6257 位置上是 1,最后你得到的这个向量的第一个元素(上图编号 5 所示)就是 orange这一列下的数字(上图编号 6 所示)。然后我们要计算这个向量的第二个元素,就是把E的第二行(上图编号 7 所示)和这个O 6527 相乘,和之前一样,然后得到第二个元素(上图编号 8 所示),以此类推,直到你得到这个向量剩下的所有元素(上图编号 9 所示)。
在实践中你会使用一个专门的函数来单独查找矩阵E的某列,而不是用通常的矩阵乘法来做,但是在画示意图时(上图所示,即矩阵𝐹乘以 one-hot 向量示意图),这样写比较方便。但是例如在 Keras 中就有一个嵌入层,然后我们用这个嵌入
层更有效地从嵌入矩阵中提取出你需要的列,而不是对矩阵进行很慢很复杂的乘法运算。
2.5 学习词嵌入(Learning Word Embeddings )
假如你在构建一个语言模型,并且用神经网络来实现这个模型。于是在训练过程中,你可能想要你的神经网络能够做到比如输入:“I want a glass of orange ___.”,然后预测这句话的下一个词。
介绍如何建立神经网络来预测序列中的下一个单词,让我为这些词列一个表格,“I want a glass of orange”,我们从第一个词 I 开始,建立一个 one-hot 向量表示这个单词 I。这是一个 one-hot 向量(上图编号 1 所示),在第 4343 个位置是 1,它是一个 10,000 维的向量。然后要做的就是生成一个参数矩阵E,然后用E乘以O 4343 ,得到嵌入向量e 4343 ,这一步意味着e 4343 是由矩阵E乘以 one-hot 向量得到的(上图编号 2 所示)。然后我们对其他的词也做相同的操作。
于是现在你有许多 300 维的嵌入向量。我们能做的就是把它们全部放进神经网络中(上图编号 3 所示),经过神经网络以后再通过 softmax 层(上图编号 4 所示),这个 softmax也有自己的参数,然后这个 softmax 分类器会在 10,000 个可能的输出中预测结尾这个单词。假如说在训练集中有 juice 这个词,训练过程中 softmax 的目标就是预测出单词 juice,就是结尾的这个单词。这个隐藏层(上图编号 3 所示)有自己的参数,我这里用w [1] 和b [1] 来表示,这个 softmax 层(上图编号 4 所示)也有自己的参数W [2] 和b [2] 。如果它们用的是 300维大小的嵌入向量,而这里有 6 个词,所以用 6×300,所以这个输入会是一个 1800 维的向量,这是通过将这 6 个嵌入向量堆在一起得到的。
但如果你的目标不是学习语言模型本身的话,那么你可以选择其他的上下文。
比如说,你可以提出这样一个学习问题,它的上下文是左边和右边的四个词,你可以把目标词左右各 4 个词作为上下文(上图编号 3 所示)。提出这样一个问题,这个问题需要将左边的还有右边这 4 个词的嵌入向量提供给神经网络,就像我们之前做的那样来预测中间的单词是什么,来预测中间的目标词,这也可以用来学习词嵌入。
还有一个效果非常好的做法就是上下文是附近一个单词,它可能会告诉你单词 glass (上图编号 7 所示)是一个邻近的单词。或者说我看见了单词 glass,然后附近有一个词和 glass位置相近,那么这个词会是什么(上图编号 8 所示)?这就是用附近的一个单词作为上下文。我们将在下节视频中把它公式化,这用的是一种 Skip-Gram 模型的思想。这是一个简单
算法的例子,因为上下文相当的简单,比起之前 4 个词,现在只有 1 个,但是这种算法依然能工作得很好。
如果你真想建立一个语言模型,用目标词的前几个单词作为上下文是常见做法(上图编号 9 所示)。但如果你的目标是学习词嵌入,那么你就可以用这些其他类型的上下文(上图编号 10 所示),它们也能得到很好的词嵌入。我会在下节视频详细介绍这些,我们会谈到 Word2Vec 模型。