《深度学习进阶:自然语言处理》读书笔记

发布于 2022-06-16  314 次阅读


自然语言和单词的分布式表示(word embedding)

自然语言处理

我们平常使用的语言,如日语或英语,称为自然语言(natural language)。所谓自然语言处理(Natural Language Processing,NLP),顾名思义,就是处理自然语言的科学。简单地说,它是一种能够让计算机理解人类语言的技术。

搜索引擎和机器翻译就是两个比较好理解的例子,除此之外,还有问答系统、假名汉字转化(IME)、自动文本摘要和情感分析等,在我们身边已经使用了很多自然语言处理技术。

以下方法将探讨如何是计算机理解单词含义,并且得到单词的计算机表示(离散表示、向量表示、embedding)。

同义词词典

以英文为例,人工构建同义词的词典,使之形成图结构的单词网络。

image-20220616182918218

在自然语言处理领域,最著名的同义词词典是WordNet。使用WordNet,可以获得单词的近义词,或者利用单词网络。使用单词网络,可以计算单词之间的相似度。

这个方法存在很大的局限性:

  • 难以顺应时代变化(更新缓慢)
  • 人力成本高
  • 无法表示单词的微妙差异(没有一个相似度量化指标)

基于计数的方法

语料库

从介绍基于计数的方法开始,我们将使用语料库(corpus)。简而言之,语料库就是大量的文本数据。不过,语料库并不是胡乱收集数据,一般收集的都是用于自然语言处理研究和应用的文本数据。

单词的分布式表示

世界上的颜色可以通过RGB(Red/Green/Blue)三原色分别存在多少来进行表示,将颜色表示为三维向量,且这种基于三原色的表示方式很紧凑,也更容易让人想象到具体是什么颜色。也就是说视觉上相似的颜色,在于rgb这个空间上的距离也是相近的。将这种方式类比到文字上,构建出紧凑合理的准确把握单词含义的向量表示。在自然语言处理领域,这称为分布式表示。

分布式假设

“某个单词的含义由它周围的单词形成”,称为分布式假设(distributional hypothesis)。

共现矩阵

设定一个固定的窗口大小,对一段文字进行统计,将每个单词在其窗口大小内的其他单词进行标注。

例如

image-20220616184025477

image-20220616184034817

得到了每个单词对于其窗口大小内其他出现单词的统计,汇总得到一个矩阵,称为共现矩阵(co-occurence matrix)。

通过共现矩阵其实我们就已经得到了单词的向量表示的雏形,即根据分布式假设,将单词的意思抽象成该单词上下文内的词汇,而这个上下文向量距离较短的两对单词,说明这两个单词上下文中出现的单词是差不多的,因此得到这两个单词的意思是相近的。

向量间的相似度

测量向量间的相似度有很多方法,其中具有代表性的方法有向量内积或欧式距离等。虽然除此之外还有很多方法,但是在测量单词的向量表示的相似度方面,余弦相似度(cosine similarity)是很常用的。设有两个向量,它们之间的余弦相似度的定义如下式所示。

在式(2.1)中,分子是向量内积,分母是各个向量的范数。范数表示向量的大小,这里计算的是L2范数(即向量各个元素的平方和的平方根)。式(2.1)的要点是先对向量进行正规化,再求它们的内积。

余弦相似度直观地表示了“两个向量在多大程度上指向同一方向”。两个向量完全指向相同的方向时,余弦相似度为1;完全指向相反的方向时,余弦相似度为−1。

基于计数的方法的改进

点互信息

上一节的共现矩阵的元素表示两个单词同时出现的次数。但是,这种“原始”的次数并不具备好的性质。在这种方法下一些常用词会和许多词汇产生极强的相关性,这并不是预期的结果,为了解决这种问题需要对常用词进行一些惩罚机制。

为了解决这一问题,可以使用点互信息(Pointwise Mutual Information,PMI)这一指标。对于随机变量x和y,它们的PMI定义如下:

其中,表示发生的概率,表示发生的概率,表示同时发生的概率。PMI的值越高,表明相关性越强。

自然语言的例子中,就是指单词x在语料库中出现的概率。假设某个语料库中有10000个单词,其中单词the出现了100次,则P("the")=。另外,P(x,y)表示单词x和y同时出现的概率。假设the和car一起出现了10次,则P("the","car")=

降维

所谓降维(dimensionality reduction),顾名思义,就是减少向量维度。但是,并不是简单地减少,而是在尽量保留“重要信息”的基础上减少。如图2-8所示,我们要观察数据的分布,并发现重要的“轴”。

image-20220616185742940

向量中的大多数元素为0的矩阵(或向量)称为稀疏矩阵(或稀疏向量)。这里的重点是,从稀疏向量中找出重要的轴,用更少的维度对其进行重新表示。结果,稀疏矩阵就会被转化为大多数元素均不为0的密集矩阵。这个密集矩阵就是我们想要的单词的分布式表示。

降维的方法有很多,这里我们使用奇异值分解(Singular Value Decomposition,SVD)。SVD将任意矩阵分解为3个矩阵的乘积,如下式所示:

SVD将任意的矩阵分解为这3个矩阵的乘积,其中是列向量彼此正交的正交矩阵,是除了对角线元素以外其余元素均为0的对角矩阵。图2-9中直观地表示出了这些矩阵。

image-20220616190046299

是正交矩阵。这个正交矩阵构成了一些空间中的基轴(基向量),我们可以将矩阵作为“单词空间”。是对角矩阵,奇异值在对角线上降序排列。简单地说,我们可以将奇异值视为“对应的基轴”的重要性。这样一来,如图2-10所示,减少非重要元素就成为可能。

word2vec

基于推理的方法和神经网络

用向量表示单词的研究中比较成功的方法大致可以分为两种:一种是基于计数的方法;另一种是基于推理的方法。虽然两者在获得单词含义的方法上差别很大,但是两者的背景都是分布式假设。

基于计数的方法的问题

基于计数的方法根据一个单词周围的单词的出现频数来表示该单词。具体来说,先生成所有单词的共现矩阵,再对这个矩阵进行SVD,以获得密集向量(单词的分布式表示)。但是,基于计数的方法在处理大规模语料库时会出现问题。

在现实世界中,语料库处理的单词数量非常大。比如,据说英文的词汇量超过100万个。如果词汇量超过100万个,那么使用基于计数的方法就需要生成一个100万×100万的庞大矩阵,但对如此庞大的矩阵执行SVD显然是不现实的。

基于计数的方法使用整个语料库的统计数据(共现矩阵和PPMI等 ),通过一次处理(SVD等)获得单词的分布式表示。而基于推理的方法使用神经网络,通常在mini-batch数据上进行学习。这意味着神经网络一次只需要看一部分学习数据(mini-batch),并反复更新权重。这种学习机制上的差异如图3-1所示。

image-20220616190544042

基于计数的方法一次性处理全部学习数据;反之,基于推理的方法使用部分学习数据逐步学习。这意味着,在词汇量很大的语料库中,即使SVD等的计算量太大导致计算机难以处理,神经网络也可以在部分数据上学习。并且,神经网络的学习可以使用多台机器、多个GPU并行执行,从而加速整个学习过程。在这方面,基于推理的方法更有优势。

基于推理的方法的概要

于推理的方法的主要操作是“推理”。如图3-2所示,当给出周围的单词(上下文)时,预测“?”处会出现什么单词,这就是推理。这种方法可以称为是无监督学习,因为所需要输入的数据是大量现存的语料,不需要人为标注,学习目标为预测输入语句下一个会出现的词。

image-20220616190935842

解开图3-2中的推理问题并学习规律,就是基于推理的方法的主要任务。通过反复求解这些推理问题,可以学习到单词的出现模式。从“模型视角”出发,这个推理问题如图3-3所示。

image-20220616191025383

如图3-3所示,基于推理的方法引入了某种模型,我们将神经网络用于此模型。这个模型接收上下文信息作为输入,并输出(可能出现的)各个单词的出现概率。在这样的框架中,使用语料库来学习模型,使之能做出正确的预测。另外,作为模型学习的产物,我们得到了单词的分布式表示。这就是基于推理的方法的全貌。

也就是说在训练完这个模型同时,我们可以从某一层提取到单词的向量表示。

神经网络中单词的处理方法

要用神经网络处理单词,需要先将单词转化为固定长度的向量。对此,一种方式是将单词转换为one-hot表示(one-hot向量)。在one-hot表示中,只有一个元素是1,其他元素都是0。

image-20220616191405294

对于one-hot表示的某个单词,使用全连接层对其进行变换的情况如图3-6所示

image-20220616191600885

CBOW模型的推理

CBOW模型是word2vec的一种,它有两个输入层,经过中间层到达输出层。这里,从输入层到中间层的变换由相同的全连接层(权重为)完成,从中间层到输出层神经元的变换由另一个全连接层(权重为)完成。

image-20220616191834750

中间层的神经元是各个输入层经全连接层变换后得到的值的“平均”。就上面的例子而言,经全连接层变换后,第1个输入层转化为,第2个输入层转化为,那么中间层的神经元是

最后是图3-9中的输出层,这个输出层有7个神经元。这里重要的是,这些神经元对应于各个单词。输出层的神经元是各个单词的得分,它的值越大,说明对应单词的出现概率就越高。得分是指在被解释为概率之前的值,对这些得分应用Softmax函数,就可以得到概率。

如图3-9所示,从输入层到中间层的变换由全连接层(权重是)完成。此时,全连接层的权重是一个7×3的矩阵。提前剧透一下,这个权重就是我们要的单词的分布式表示,如图3-10所示。

image-20220616192424344

中间层的神经元数量比输入层少这一点很重要。中间层需要将预测单词所需的信息压缩保存,从而产生密集的向量表示。这时,中间层被写入了我们人类无法解读的代码,这相当于“编码”工作。而从中间层的信息获得期望结果的过程则称为“解码”。这一过程将被编码的信息复原为我们可以理解的形式。

补充说明

有一个常见的误解,那就是基于推理的方法在准确度方面优于基于计数的方法。实际上,有研究表明,就单词相似性的定量评价而言,基于推理的方法和基于计数的方法难分上下。

使用word2vec获得的单词的分布式表示可以用来查找近似单词,但是单词的分布式表示的好处不仅仅在于此。在自然语言处理领域,单词的分布式表示之所以重要,原因就在于迁移学习(transfer learning)。迁移学习是指在某个领域学到的知识可以被应用于其他领域。

在解决自然语言处理任务时,一般不会使用word2vec从零开始学习单词的分布式表示,而是先在大规模语料库(Wikipedia、Google News等文本数据)上学习,然后将学习好的分布式表示应用于某个单独的任务。比如,在文本分类、文本聚类、词性标注和情感分析等自然语言处理任务中,第一步的单词向量化工作就可以使用学习好的单词的分布式表示。在几乎所有类型的自然语言处理任务中,单词的分布式表示都有很好的效果!

循环神经网络(Recurrent Neural Network,RNN)

概率和语言模型

概率视角下的word2vec

CBOW模型所做的事情就是从上下文()预测目标词()。

image-20220616193931560

用数学式来表示“当给定时目标词是的概率”,如式(5.1)所示:

CBOW模型对这一后验概率进行建模。这个后验概率表示“当给定时目标词是的概率”。这是窗口大小为1时的CBOW模型。顺便提一下,我们之前考虑的窗口都是左右对称的。这里我们将上下文限定为左侧窗口。

image-20220616194119599

在仅将左侧2个单词作为上下文的情况下,CBOW模型输出的概率:

CBOW模型的损失函数可以写成

语言模型(概率分解)

语言模型(language model)给出了单词序列发生的概率。

我们使用数学式来表示语言模型。这里考虑由个单词构成的句子,将单词按的顺序出现的概率记为。因为这个概率是多个事件一起发生的概率,所以称为联合概率。

使用后验概率可以将这个联合概率分解成如下形式:

image-20220616195549649

Simple RNN

Recurrent Neural Network通常译为“循环神经网络”。另外,还有一种被称为Recursive Neural Network(递归神经网络)的网络。这个网络主要用于处理树结构的数据,和循环神经网络不是一个东西。

循环的神经网络

RNN的特征就在于拥有这样一个环路(或回路)。这个环路可以使数据不断循环。通过数据的循环,RNN一边记住过去的数据,一边更新到最新的数据。环路的设计使rnn拥有了记忆性,这与CBOW(bag of word)中的无序性差别很大。

image-20220616200121920

通过该环路,数据可以在层内循环。在图5-6中,时刻的输入是,这暗示着时序数据会被输入到层中。然后,以与输入对应的形式,输出

存储“状态”,时间每前进一步(一个单位),许多文献中将RNN的输出称为隐藏状态(hidden state)或隐藏状态向量(hidden state vector),本书中也是如此。

image-20220616200500964

由图5-8可以看出,各个时刻的RNN层接收传给该层的输入和前一个RNN层的输出,然后据此计算当前时刻的输出,此时进行的计算可以用下式表示:

RNN有两个权重,分别是将输入转化为输出的权重和将前一个RNN层的输出转化为当前时刻的输出的权重。此外,还有偏置。这里,都是行向量。

Backpropagation Through Time

将循环展开后的RNN可以使用(常规的)误差反向传播法。因为这里的误差反向传播法是“按时间顺序展开的神经网络的误差反向传播法”,所以称为Backpropagation Through Time(基于时间的反向传播),简称BPTT。

image-20220616201032783

Truncated BPTT

在处理长时序数据时,通常的做法是将网络连接截成适当的长度。具体来说,就是将时间轴方向上过长的网络在合适的位置进行截断,从而创建多个小型网络,然后对截出来的小型网络执行误差反向传播法,这个方法称为Truncated BPTT(截断的BPTT)。

image-20220616201120459

长短期记忆(Long short-term memory,LSTM)

RNN存在环路,可以记忆过去的信息,其结构非常简单,易于实现。不过,遗憾的是,这个RNN的效果并不好。原因在于,许多情况下它都无法很好地学习到时序数据的长期依赖关系。实际上,当我们说RNN时,更多的是指LSTM层,而不是上一章的RNN。顺便说一句,当需要明确指上一章的RNN时,我们会说“简单RNN”或“Elman”。

RNN的问题

梯度消失和梯度爆炸

RNN层通过向过去传递“有意义的梯度”,能够学习时间方向上的依赖关系。此时梯度(理论上)包含了那些应该学到的有意义的信息,通过将这些信息向过去传递,RNN层学习长期的依赖关系。但是,如果这个梯度在中途变弱(甚至没有包含任何信息),则权重参数将不会被更新。也就是说,RNN层无法学习长期的依赖关系。不幸的是,随着时间的回溯,这个简单RNN未能避免梯度变小(梯度消失)或者梯度变大(梯度爆炸)的命运。

image-20220617063807933

虚线是y=tanh(x)的导数。从图中可以看出,它的值小于1.0,并且随着x远离0,它的值在变小。这意味着,当反向传播的梯度经过tanh节点时,它的值会越来越小。因此,如果经过tanh函数T次,则梯度也会减小T次。

梯度爆炸对策

解决梯度爆炸有既定的方法,称为梯度裁剪(gradients clipping)。

假设可以将神经网络用到的所有参数的梯度整合成一个,并用符号ˆg表示。另外,将阈值设置为threshold。此时,如果梯度的L2范数‖ˆg‖大于或等于阈值,就按上述方法修正梯度,这就是梯度裁剪。如你所见,虽然这个方法很简单,但是在许多情况下效果都不错。

梯度消失和LSTM

LSTM层的结构

image-20220617064507750

LSTM有记忆单元。这个ct存储了时刻时LSTM的记忆,可以认为其中保存了从过去到时刻的所有必要信息(或者以此为目的进行了学习)。然后,基于这个充满必要信息的记忆,向外部的层(和下一时刻的LSTM)输出隐藏状态。如图6-12所示,LSTM输出经函数变换后的记忆单元。

当前的记忆单元是基于3个输入,经过“某种计算”(后述)算出来的。这里的重点是隐藏状态要使用更新后的来计算。另外,这个计算是,表示对的各个元素应用函数。

输出门

image-20220617070042822

针对的各个元素,调整它们作为下一时刻的隐藏状态的重要程度。由于这个门管理下一个隐藏状态的输出,所以称为输出门(output gate)。

输出门的开合程度(流出比例)根据输入xt和上一个状态ht−1求出。这里在使用的权重参数和偏置的上标上添加了output的首字母o。之后,我们也将使用上标表示门。另外,sigmoid函数用σ()表示。

输入有权重,上一时刻的状态有权重是行向量)。将它们的矩阵乘积和偏置之和传给函数,结果就是输出门的输出。最后,将这个的对应元素的乘积作为输出。

将输出门进行的式(6.1)的计算表示为。然后,将它的输出表示为,则ht可由的乘积计算出来。这里说的“乘积”是对应元素的乘积,也称为阿达玛乘积。如果用表示阿达玛乘积,则此处的计算如下所示:

的输出是−1.0 ~ 1.0的实数。我们可以认为这个−1.0 ~ 1.0的数值表示某种被编码的“信息”的强弱(程度)。而函数的输出是0.0~1.0的实数,表示数据流出的比例。因此,在大多数情况下,门使用函数作为激活函数,而包含实质信息的数据则使用函数作为激活函数。

遗忘门

在记忆单元ct−1上添加一个忘记不必要记忆的门,这里称为遗忘门(forget gate)。

image-20220617070456194

将遗忘门进行的一系列计算表示为σ,其中有遗忘门专用的权重参数,此时的计算如下:

由这个和上一个记忆单元的对应元素的乘积求得

新的记忆单元

遗忘门从上一时刻的记忆单元中删除了应该忘记的东西,但是这样一来,记忆单元只会忘记信息。现在我们还想向这个记忆单元添加一些应当记住的新信息,为此我们添加新的tanh节点。

image-20220617071300421

表示向记忆单元添加的新信息。通过将这个加到上一时刻的上,从而形成新的记忆。

输入门

最后,我们给图6-17的添加门,这里将这个新添加的门称为输入门(input gate)。

image-20220617071508319

输入门判断新增信息g的各个元素的价值有多大。输入门不会不经考虑就添加新信息,而是会对要添加的信息进行取舍。输入门会添加加权后的新信息。

用σ表示输入门,用i表示输出,此时进行的计算如下所示:

LSTM的梯度的流动

image-20220617071715415

seq2seq

世界上存在许多输入输出均为时序数据的任务。从现在开始,我们会考察将时序数据转换为其他时序数据的模型。作为它的实现方法,我们将介绍使用两个RNN的seq2seq模型。

seq2seq的原理

seq2seq模型也称为Encoder-Decoder模型。顾名思义,这个模型有两个模块——Encoder(编码器)和Decoder(解码器)。编码器对输入数据进行编码,解码器对被编码的数据进行解码。

image-20220617084745913

吾輩は猫である”这句话进行编码,然后将编码好的信息传递给解码器,由解码器生成目标文本。此时,编码器编码的信息浓缩了翻译所必需的信息,解码器基于这个浓缩的信息生成目标文本。

image-20220617084932999

编码器利用RNN将时序数据转换为隐藏状态h。这里的RNN使用的是LSTM,不过也可以使用“简单RNN”或者GRU等。另外,这里考虑的是将日语句子分割为单词(而不是单个字符)进行输入的情况。

编码器输出的向量h是LSTM层的最后一个隐藏状态,其中编码了翻译输入文本所需的信息。这里的重点是,LSTM的隐藏状态h是一个固定长度的向量。说到底,编码就是将任意长度的文本转换为一个固定长度的向量(分布式表示)。

image-20220617085156767

解码器的结构和上一节的神经网络完全相同。不过它和上一节的模型存在一点差异,就是LSTM层会接收向量h。在上一节的语言模型中,LSTM层不接收任何信息(硬要说的话,也可以说LSTM的隐藏状态接收“0向量”)。这个唯一的、微小的改变使得普通的语言模型进化为可以驾驭翻译的解码器。

这一分隔符(特殊符号)。这个分隔符被用作通知解码器开始生成文本的信号。另外,解码器采样到出现为止,所以它也是结束信号。

image-20220617085656305

seq2seq由两个LSTM层构成,即编码器的LSTM和解码器的LSTM。此时,LSTM层的隐藏状态是编码器和解码器的“桥梁”。在正向传播时,编码器的编码信息通过LSTM层的隐藏状态传递给解码器;在反向传播时,解码器的梯度通过这个“桥梁”传递给编码器。

注意力机制(Attention Mechanism,Attention)

Attention的结构

seq2seq存在的问题

eq2seq中使用编码器对时序数据进行编码,然后将编码信息传递给解码器。此时,编码器的输出是固定长度的向量。实际上,这个“固定长度”存在很大问题。因为固定长度的向量意味着,无论输入语句的长度如何(无论多长),都会被转换为长度相同的向量。实际上在很多问题中输入输出长度并不一定是一对一的关系。

编码器的改进

使用各个时刻(各个单词)的隐藏状态向量,可以获得和输入的单词数相同数量的向量。在图8-2的例子中,输入了5个单词,此时编码器输出5个向量。这样一来,编码器就摆脱了“一个固定长度的向量”的制约。

image-20220617105524235

这一步在Keras中,在初始化RNN层时,可以设置return_sequences为True或者False。

各个时刻的LSTM层的隐藏状态中包含了大量当前时刻的输入单词的信息,编码器输出的hs矩阵就可以视为各个单词对应的向量集合。

image-20220617105839461

解码器的改进

编码器整体输出各个单词对应的LSTM层的隐藏状态向量hs。然后,这个hs被传递给解码器,以进行时间序列的转换。

image-20220617105952791

上一章的解码器只用了编码器的LSTM层的最后的隐藏状态。如果使用hs,则只提取最后一行,再将其传递给解码器。下面我们改进解码器,以便能够使用全部

从现在开始,我们的目标是找出与“翻译目标词”有对应关系的“翻译源词”的信息,然后利用这个信息进行翻译。也就是说,我们的目标是仅关注必要的信息,并根据该信息进行时序转换。这个机制称为Attention,是本章的主题。

我们新增一个进行“某种计算”的层。这个“某种计算”接收(解码器)各个时刻的LSTM层的隐藏状态和编码器的。然后,从中选出必要的信息,并输出到Affine层。与之前一样,编码器的最后的隐藏状态向量传递给解码器最初的LSTM层。

Weight Sum层

image-20220617110315457

网络所做的工作是提取单词对齐信息。具体来说,就是从中选出与各个时刻解码器输出的单词有对应关系的单词向量。比如,当图8-6的解码器输出“I”时,从中选出“吾輩”的对应向量。也就是说,我们希望通过“某种计算”来实现这种选择操作。选择操作使用对各个单词使用不同权重求和来实现(相关单词权重大,不相关单词权重小)。

这里使用了表示各个单词重要度的权重(记为)。 此时,像概率分布一样,各元素是0.0~1.0的标量,总和是1。然后,计算这个表示各个单词重要度的权重和单词向量hs的加权和,可以获得目标向量。

image-20220617113016743

image-20220617113135290

 

Attention Weight层

表示各个单词重要度的权重是网络中机器需要自动学习的参数,下面我们来看一下各个单词的权重的求解方法。

这里通过向量内积算出的各个单词向量之间的相似度,并将其结果表示为。不过,这个是正规化之前的值,也称为得分。接下来,使用老一套的Softmax函数对进行正规化(图8-14)。

计算向量相似度的方法有好几种。除了内积之外,还有使用小型的神经网络输出得分的做法。文献[49]中提出了几种输出得分的方法。

image-20220617113735794

image-20220617113744425

综合分析

image-20220617114258076

我们已经分为Weight Sum层和Attention Weight层进行了实现。重申一下,这里进行的计算是:Attention Weight层关注编码器输出的各个单词向量,并计算各个单词的权重;然后,Weight Sum层计算的加权和,并输出上下文向量。我们将进行这一系列计算的层称为Attention层。

image-20220617114912469

 

 

 

 

 

 

 

 

 


面向ACG编程