- 深度序列模型与自然语言处理:基于TensorFlow 2实践
- 阮翀
- 1354字
- 2024-12-27 22:34:49
2.3.1 词向量的分类
词向量学习算法可以分为两大类,一类是基于计数的(Count-based),一类是基于预测的(Prediction-based)。顾名思义,前者统计单词及其上下文单词在语料库中的统计量,例如共现次数、互信息(Mutual Information)等,最后把这些统计量用模型压缩到稠密向量中;后者则试图从上下文中预测当前单词(8),在建模时直接使用稠密的低维词向量。前者的代表算法有潜在语义分析和GloVe[60],后者的代表算法为Word2vec[6][7]。尽管文献[61]声称后一类算法效果更好,但相比于算法本身,更重要的是语料的质量和规模。越是在更大规模的语料上预训练出来的模型,效果往往越好。幸运的是,这两种算法预训练的词向量在互联网上都能找到预训练好的开源版本,可以轻松用于下游任务。
GloVe[60]算法更接近于前面已经讲过的潜在语义分析,本章将不再展开;而Word2vec[6][7]作为引爆自然语言处理深度学习的代表作(9),本章将进行详细讲述。Word2vec火爆的主要原因有二:一是训练速度非常快,在算法提出的那个时代(2013年左右)即可轻松处理包含百亿单词的语料;二是发现词向量可以很好地求解单词类比(Word Analogy)任务,即形如“男人:女人=国王:?”这样的题目,让人耳目一新。对人类来说,以上题目的答案是显而易见的,即“皇后”;但对机器来说做出如此的语义推理并不简单。
Word2vec的原版实现使用的是C语言,现在已经被集成到了Python自然语言处理库Gensim[62]中。由于原版代码中有诸多对模型性能影响至关重要的细节,而且这些细节处理非常不适于在主流深度学习框架中并行实现,因此本章节包含的Word2vec TensorFlow实现仅供读者对照数学原理了解相应模型,而不具备工业级强度。如果希望得到一个效果足够好的词向量,笔者建议使用Gensim库完成训练过程。词向量的质量可以通过t-SNE[63]和主成分分析[64]等算法可视化来直观感受,我们将在下一节里详细讨论。
有些词向量学习算法,例如使用负采样(Negative Sampling)训练的Word2vec(10),会得到两个词向量矩阵。其中一个矩阵用于建模单词本身的含义,往往用在模型的输入端,因此也被称作输入向量(Input Embedding),这也是通常意义的词向量;另一个矩阵用于建模单词和其他单词搭配的能力,因此被称作上下文向量(Context Embedding),由于该参数常常位于模型输出端,有时也被称为输出向量(Output Embedding)(11)。在机器翻译等任务中,让这两个矩阵共享参数是一个常用的技巧,可以使得参数训练更充分。
在绝大多数模型里,单词和向量是一一对应的。也有部分算法[65]会给一个单词学习多个词向量,以期解决一词多义问题。在Word2vec刚刚提出后,有一波多义词词向量的研究热潮。不过今天已经很少有人关心这个问题了,词义消歧通常由模型本身来完成,而不是先进行词义消歧然后再给多义词选择一个对应词义的词向量。尤其是在ELMo[66]发表之后,词向量不再是一个静态的概念(每个词有一个固定的向量来代表它的含义),而是变成了动态的(每个词在文本里的每次出现都有一个实时计算出的、和当前上下文相关的向量来代表它的含义)。词向量不再是一个固定的参数,而是模型在当前输入的句子上进行前向推断的结果。这种词向量融合了句子里各个单词间的依赖关系,被称作语境化的词向量(Contextualized Embedding)。这里注意不要混淆上下文向量和语境化的词向量:前者表示的是一个词在作为别的词的上下文时的含义,仍然是静态的——无论它出现在哪个词的上下文里都取同一个向量;而后者则表达单词本身在某个具体的语境中的含义,是动态的——同一个单词在不同的句子里(甚至是同一句话里的不同出现)对应不同的向量。