CS224N(3.14)Future of NLP + Deep Learning

今天是该课程的最后一节课,介绍了使用未标注数据集进行NLP学习的方法,以及谈了谈NLP未来的发展方向。下面主要介绍使用未标注数据集进行NLP学习的方法。 我们知道,在机器翻译领域,特别缺少标注好的语料集。目前世界上有上千种语言,但用得最多的只有十几种。对于那些使用人数很少的语言,它们和其他语言之间标注好的翻译句子就更少了。如何使用少量标注集,甚至不用标注集,就能实现机器翻译功能,是NLP领域一个很有前景的发展方向。 之前的很多工作使用pre-training来提高机器翻译模型的性能。具体方法是,先在源语言和目标语言的语料集上分别训练一个语言模型,这是无监督的,这个语言模型可以学到不同词的含义。然后在翻译模型中,用源语言的语言模型初始化Encoder权重,用目标语言的语言模型初始化Decoder权重。使用pre-training的模型相比于不使用pre-training的模型的BLEU大概有2分的提高。 Pre-training的问题是,由于预训练是在两种语言上独立进行的,两种语言在预训练期间没有交互过程。 下面的Back-Translation比较有意思。比如我们要训练一个英语到法语的翻译器,初始化的时候让模型随便从英语翻译成法语。同时,训练一个法语到英语的翻译器,把上一个翻译器输出的法语翻译成英语。有点像练功的时候左右互搏,也有点像AlphaGo自己教自己下棋,随着训练的进行,两个模型的翻译能力都得到了提升。 当然这有一些问题,如果两个模型一开始都一无所知,则可能前一个模型的输出是随机的,后一个模型的输入是随机的,模型根本学不到任何知识,无法收敛。所以更好的做法是,有少量的标注数据,两个模型先在标注数据上学到一个比较差的模型;然后用这个比较差的模型左右互搏,相当于可以粗略的标注一部分新数据;然后又在标注数据上训练;如此循环往复。实验结果表明,使用Back-Translation和大量无标注数据集之后,翻译模型的性能有大幅提升。 Back-Translation要求我们还是需要少量的标注数据,用来启动左右互搏的过程。那么如果有两种语言X和Y,我们没有X和Y的任何翻译好的句子pair,但依然想翻译它们,怎么办。这时候,可以先从简单的单词翻译做起。在训练X和Y各自的词向量时,可以把它们的词向量映射到同一个空间,则空间中相近的词的含义也相近。对于X中的一个词x,只需要在词向量空间中选与x最接近的Y中的词y,则y可以作为x的翻译。这种把多种语言的词向量统一对齐到一个空间之后的词向量称为跨语言的词向量,也就是说从这个空间中取一个词向量,虽然它的含义是固定的,但可以转换成任意一种语言的具体的词。 那么,关键问题就是怎样把X和Y的词向量对齐。我们知道word2vec有一个很好的特点就是,它训练出来的词向量能够保持比较好的空间结构。举例来说,对于X中的词x和Y中的词y,即使它们的含义很接近,但如果直接把x和y放到同一个空间中,它们的距离可能还是比较大,因为X和Y的词向量坐标系可能就不一样。但是,对于X中的两个词x1和x2,如果它们分别对应Y中的两个词y1和y2,则在X空间中,x1和x2的距离应该与Y空间中y1和y2的距离相近,也就是说两个空间的整体结构是一样的。如下图所示,X和Y对齐的过程就是找出它们的变换矩阵W。由于我们只希望将它们的坐标系进行变换对齐,并不想改变里面的数据分布,所以变换矩阵W最好是正交的。 学习矩阵W的过程也很有意思,这里介绍了一种对抗学习的方式。有一个生成器,用来生成矩阵W。有一个判别器,它想要区分一个词向量是Y中的词向量,还是X中的词向量经过W变换得到的。起初,由于X和Y的空间分布不同,W也是随机的,判别器可以很容易地区分Y和WX。但是随着对抗的进行,W越来越准,最后WX和Y重合了,此时判别器傻傻分不清楚,它只能随机猜,有50%的几率猜对。所以学习矩阵W的过程就是让判别器懵圈的过程。 上述是非监督的词与词的翻译,怎样由此得到非监督的句子与句子的翻译呢? 我们首先使用上述的跨语言的词向量,然后使用相同的encoder-decoder来编码和解码两种语言。解码的时候,设置一个标志位,告诉decoder要把目标含义用哪种语言表达出来,就是下图的<Fr>标签。 然后有两个训练目标,第一个目标是对源句子进行微小的打乱,然后让encoder恢复原来的句子。第二个目标是使用上文提到的back translation进行左右互搏(所以好像还是需要少量标注集?)。 这种方法有效是因为输入的词向量是跨语言词向量,输入一个英文句子就相当于输入了一个法文句子。又因为使用的encoder是相同的,所以英文句子在进行第一个目标训练时,隐含学到了将法语翻译为英语的能力。 上述的非监督词与词、句子与句子的翻译,只有在源语言和目标语言比较像的情况下才能取得比较好的效果,比如英语、法语、德语比较像,可以用。但英语和土耳其语差别比较大,这种非监督方法的效果就比较差。语言像不像涉及到很多方面,比如语法结构、句子结构、用词顺序等等。

March 26, 2020 · 1 min

CS224N(2.26)Natural Language Generation

今天要介绍的内容比较多,但都是概述性的内容,主要了解自然语言生成领域的进展。 Section 1: Recap LMs and decoding algorithms 之前已经讲过什么是语言模型,语言模型就是给定句子中的一部分词,要求预测下一个词是什么。形式化表述就是预测\(P(y_t|y_1,…,y_{t-1})\),其中的\(y_1,…,y_{t-1}\)就是目前已知的词,\(y_t\)就是要预测的下一个词。 条件语言模型是指除了已知\(y_1,…,y_{t-1}\),还给定了\(x\),这个\(x\)就是提供给语言模型的额外的信息。比如机器翻译的\(x\)就是源语言的句子信息;自动摘要的\(x\)就是输入的长文;对话系统的\(x\)就是历史对话内容等。 需要提醒的是,语言模型在训练阶段,输入Decoder的是正确的词,这种方法被称为Teacher Forcing,即不论上一步的输出是什么,都强制给这一步输入正确的词。而如果在测试阶段,Decoder的输入是上一步的输出。 在机器翻译那期的博客中(CS224N(1.31)Translation, Seq2Seq, Attention),我们曾提到过在测试阶段,语言模型的Decoder有两种策略,一种是Greedy search,另一种是Beam search。Greedy search是指当前步的输入是上一步输出中概率最大的词。而Beam searh是指不但保留概率最大的词,还要保留概率在Top-k的词,那么在每一个时间步,都会有k条路径,最后选一条概率最大的路径。 那么,Beam search中保留的Top-k到底取多少合适呢?当k=1时,Beam search退化为Greedy search,产生的句子可能会不够自然,甚至难以理解。增大k会使得产生的句子的全局概率更大,读起来会更通顺一些。但是k的增大也会带来一些问题,比如:计算量增大;对于NMT任务,k的增大会导致翻译出来的句子更短,BLEU得分更低;对于对话系统,k的增大会导致产生的句子过于“安全”和“通用”,也就是和当前对话没有太大关系但又比较通顺的句子。 比如下面右图的例子,k=1时,回答和对话有点关系,但句子语法有问题;k=6时,句子很同时,但感觉答非所问。 事实上,除了Greedy search和Beam search,还有其他的decoding方法。下面是两种基于采样的decoding方法。 Pure sampling:每个时间步t,根据softmax输出的概率分布进行采样,来决定t时刻最终输出的词。Top-n sampling:只在概率top-n的词中采样,相当于对Pure sampling的概率分布进行truncate。两种方法都是单路径的,不像Beam search那样保留多条路径。由于两种方法都是通过采样决定输出,属于随机算法,所以每次运行算法输出都不一样,可增加句子的多样性,比较适合于对话系统。 还有一种可以改变语言模型输出概率的方法,就是Softmax temperature,带温度的Softmax,如下图所示。当t越大,分布变得越扁平,削弱了大和小的差别;t越小,则分布变得越尖,大的越大,小的越小。配合不同的decoding算法,可以控制产生句子的流畅度、平庸度、或者新奇度等。 以下是语言模型的decoding算法小结。 Section 2: NLG tasks and neural approaches to them 自然语言生成是一类生成新文本的任务,包括机器翻译、自动摘要、对话系统(聊天机器人)、写作机器人、看图写作等。下面对其中几个任务进行简单的介绍。 自动摘要的定义是,给定长文本x,要求生成短文本y,y能概括x的主要内容。自动摘要又分为x是单文档或多文档两类。 (左图)自动摘要的一些数据集。Summarization:根据长文本写一个短句子作为长文本的摘要,就是常规意义的自动摘要。Sentence simplification:把复杂的句子转换为简单的句子,通常转换后的句子比源句子短,主要是换成更简单易懂的词,用简单的句子结构替代复杂的句子结构等,比如把新闻转换为儿童容易读懂的新闻。 (右图)两种自动摘要的策略对比。Extractive summarization是指摘要的句子从原文中提取;Abstractive summarization是指使用语言模型生成新的句子作为摘要。前者类似于从原文中高亮某些关键句子,后者相当于用笔创作出新的句子作为摘要。 前神经网络时代的自动摘要大多数是Extractive summarization,是一个pipeline,很复杂,可能会用到各种不同的算法。 自动摘要的评价指标ROUGE。ROUGE和BLEU类似,都是基于模型输出和标准答案之间的n-gram的overlap,但是ROUGE不会对太短的摘要进行惩罚,而且ROUGE对不同的n-gram打分是分开的,而BLEU综合了n=1,2,3,4的n-gram结果。BLEU更关注precision,所以对太短(可能没有包含源句子的意思)的翻译有惩罚。ROUGE更关注recall,从其名称就可以看出来,在某个长度限制下,尽量包含长文的信息。) 2015年开始,基于神经网络的自动摘要方法蓬勃发展。基本思路是把自动摘要看成从长句子到短句子的翻译任务,使用seq2seq+attention的方法解决,效果还不错。下图是一些技巧,感兴趣的可以搜索原文阅读。 对话系统的分类:assistive:个人助手型;co-operative:协作型;adversarial:对抗型,辩论?chit-chat:聊天机器人;therapy:心理咨询师? 神经网络之前的做法是,事先设计一些问答模板,根据场景,给模板填充不同的内容。或者使用信息检索的方式,从问答库中检索问答。 2015年后,很多人开始用seq2seq+attention的方法做问答系统,但存在一些问题,如下。 ...

March 6, 2020 · 1 min

CS224N(2.21)Transformers and Self-Attention For Generative Models

今天介绍大名鼎鼎的Transformer,它于2017年出自谷歌的论文《Attention Is All You Need》(https://arxiv.org/pdf/1706.03762.pdf),用Attention实现机器翻译模型,并取得了新的SOTA性能。 传统的机器翻译模型一般是结合RNN和Attention,可以看我之前的博客介绍:CS224N(1.31)Translation, Seq2Seq, Attention。虽然RNN+Attention的组合取得了不错的效果,但依然存在一些问题。由于RNN是序列依赖的模型,难以并行化,训练时间较长;且当句子很长时由于梯度消失难以捕捉长距离依赖关系。虽然相继推出的LSTM和GRU能一定程度上缓解梯度消失的问题,但这个问题依然存在。而且LSTM和GRU难以解释,我们根本不知道当前timestep依赖远的词多一点还是近的词多一点。 Transformer的思想很激进,它完全抛弃了RNN,只保留Attention,从其论文标题可见一斑。RNN无法并行化的根本原因是它的正向和反向传播是沿着句子方向(即水平方向),要想实现并行化,肯定不能再走水平方向了。于是,Transformer完全抛弃水平方向的RNN,而是在垂直方向上不断叠加Attention。由于每一层的Attention计算只和其前一层的Attention输出有关,所以当前层的所有词的Attention可以并行计算,互不干扰,这就使得Transformer可以利用GPU进行并行训练。 具体来说,Transformer的结构如下图所示。我们知道end2end的机器翻译模型一般都是Encoder+Decoder的组合,Encoder对源句子进行编码,将编码信息传给Decoder,Decoder翻译出目标句子。Transformer也不例外,下图左边即为Encoder,右边即为Decoder。 Encoder的每一层有两个子层组成,包括Self-Attention和Feed-forward neural network (FFNN)。FFNN就是常规的全连接网络,没什么可说的,下面重点介绍Self-Attention。 Encoder Self-Attention的结构如下图所示,由于此时是Encoder阶段,对于每个词,都能看到句子中所有其他的词(对应到RNN里面就是可以用双向的RNN)。假设我们想要抽取第二个词”represent”的特征表示。首先,对第二个词的词向量\(e_2\)进行线性变换,即乘以矩阵\(matmul_Q\),得到Query,这就是标准Attention中的Query。其次,对周围所有的其他词,比如\(e_1\),也进行线性变换,变换矩阵为\(matmul_K\),得到很多的Key。然后,Query和所有Key做点积,并用softmax归一化,得到了Query在周围词上的Attention score distribution。接着,周围词乘以另一个线性变换矩阵\(matmul_V\),变换为Value。最后,Value和Attention score distribution进行加权求和,并加上\(e_2\)自己,送给FFNN。图中右下角的公式中的分母只是个缩放因子。 回顾一下,一个标准的Attention包括三个向量:Q、K、V,其中Q为用来查询的Query,K表示被查询的Key,V表示被查询的Value。其中的K和V来源相同,只是经过了不同的变换。形象描述就是:计算Q在K上分配的注意力\(QK^T\),然后从V中取出这部分注意力的值\(softmax(\frac{QK^T}{\sqrt{d_k}})V\)。 Self-Attention的优点。因为每个词都和周围所有词做attention,所以任意两个位置都相当于有直连线路,可捕获长距离依赖。而且Attention的可解释性更好,根据Attention score可以知道一个词和哪些词的关系比较大。易于并行化,当前层的Attention计算只和前一层的值有关,所以一层的所有节点可并行执行self-attention操作。计算效率高,一次Self-Attention只需要两次矩阵运算,速度很快。 Transformer的Decoder部分每一层有三个子层组成,包括Self-Attention、Encoder-Decoder Attention和FFNN。Decoder的Self-Attention如下图所示,和Encoder的Self-Attentoin非常像,只不过当要Decoder第二个词时,用黑框蒙住了第三、四个词的运算(设置值为-1e9)。因为对于机器翻译来说,Encoder时能看到源句子所有的词,但是翻译成目标句子的过程中,Decoder只能看到当前要翻译的词之前的所有词,看不到之后的所有词,所以要把之后的所有词都遮住。所以这个Attention也叫Masked Self-Attention。这也说明Transformer只是在Encoder阶段可以并行化,Decoder阶段依然要一个个词顺序翻译,依然是串行的。 不要忘了我们的任务是机器翻译,Decoder Self-Attention只用到了翻译出来的目标句子的前缀信息,还没用到源句子的信息,这部分就在Encoder-Decoder Attention中。前面说了对于源句子,通过Encoder的Self-Attention+FFNN,源句子的每个词都有一个输出向量,这些输出向量作为Encoder-Decoder Attention的Keys和Values,而从目标句子当前要翻译的词的Decoder Self-Attention出来的向量就是Encoder-Decoder Attention的Query。从下图可以看到,Encoder上面出来指向右边Multi-Head Attention的两个箭头就是Keys和Values,而从下面出来指向Multi-Head Attention的一个箭头就是Query。Encoder-Decoder Attention的作用就是看看当前要翻译的词在源句子中各个词上的注意力情况。 我们知道Attention机制是位置无关的,因为对于每个词,它都和句子中的所有词直连求Attention score,跟词在句子中的位置没有关系。但是句子作为一种线性结构,词在句子中的顺序对句子的含义至关重要。为了考虑词的位置信息,词在输入Attention前,把词向量和词在句子中的位置Positional Encoding加起来,得到一个新的向量,输入到Attention中,如上图所示。这个Positional Encoding可通过公式计算得到,这里不展开。 上图的Attention前面都有一个修饰词Multi-Head,也就是下图的Parallel attention heads。前面提到一个标准的Attention包括三个向量Q、K、V,它们分别由原始的查询向量和特征向量乘以矩阵\(matmul_Q\)、\(matmul_K\)、\(matmul_V\)得到。如果一个词在计算Attention时,选用多个不同的\(matmul_Q\)、\(matmul_K\)、\(matmul_V\),得到的Attention输出向量也就不同了,这正好可以用来表示一个词在句子中的不同作用。比如句子“华为是一家中国的公司”中的“华为”,它的语义是一家公司,它在句子中的成分是主语,也就是说一个词至少有其语义信息和句法信息,如果只用一套\(matmul_Q\)、\(matmul_K\)、\(matmul_V\),则只能得到一种含义,如果设置多套\(matmul_Q\)、\(matmul_K\)、\(matmul_V\),则能提取到这个词更多的信息。于是,在对每个词进行Attention时,都会设置多套\(matmul_Q\)、\(matmul_K\)、\(matmul_V\),提取多个Attention输出向量,然后拼接起来,这就是Multi-Head Attention,或者说Parallel attention heads。我个人理解多套\(matmul_Q\)、\(matmul_K\)、\(matmul_V\)相当于CNN中不同的kernal,相当于不同的特征提取器。 课上还介绍了利用Transformer生成图片和音乐的应用,感兴趣的同学可以搜索相关论文看一看。 有关Transformer的介绍,还可参考如下三个链接: http://jalammar.github.io/illustrated-transformer/ https://zhuanlan.zhihu.com/p/48508221 https://zhuanlan.zhihu.com/p/44121378

March 4, 2020 · 1 min

CS224N(2.14)Subword Models

今天介绍一下subword(子词)模型。之前介绍的NLP模型都是基于word的,对于英文来说是一个个单词,对于中文来说是一个个词语(需要分词)。不过,最近几年,subword模型多起来了,这就是我们今天要介绍的内容。 对于英文来说,文字的粒度从细到粗依次是character, subword, word,character和word都很好理解,subword相当于英文中的词根、前缀、后缀等,如unfortunately中的un、ly、fortun(e)等就是subword,它们都是有含义的。对于中文来说,只有两层,character和subword是同一层,表示单个的字,而word表示词语。 之前介绍的基于word的模型,存在out of vocabulary(OOV,未登录词)的问题。以英文为例,现存的英文单词数量太多了,随便加个前缀、后缀,变个时态什么的都变成新的单词了,所以英文单词的词典数量特别大,而且有很多低频稀疏词。很多模型在训练时都会去掉低频词,只保留高频词。那么这就存在一个问题,如果预测时遇到未登录词,则模型不认识,出现OOV的问题。 为了解决这个问题,一开始想到的是采用character级别的模型,即对26个字母训练word2vec,每个词由其字母的embedding拼接或者求平均得到。但是character级别的模型效果相比于word级别的模型效果差不多,并没有显著优势。而且如果用RNN来训练character级别的模型也有它的问题,就是训练起来非常慢。特别是对英文来说,原来的一个word,现在变成了七八个character,时间步长增加了很多,训练和预测都更久了,而且梯度消失(爆炸)的问题也会更严重。 后来,人们就想用subword模型作为character和word的折中模型。subword模型主要有两种,它们都能解决未登录词(OOV)的问题,如下图所示。第一种是模型结构和word模型完全一样,只不过把word换成了subword。第二种则是word和character模型的杂交模型。 对于第一种模型,关键问题是怎样得到subword。前面提到character的粒度太细,虽然能解决OOV问题,但效果并不是太好;word模型的word数量太多,存在大量稀疏word,删掉它们又会导致OOV问题,所以打算用subword模型。那么,怎样提取一个单词的subword呢?前面提到,unfortunately中的un、ly、fortun(e)等就是subword,但是对每个词都这样提取subword的话,费时费力不说,也不够智能。 有人就想出了用BPE算法来提取高频subword。BPE,全称是byte pair encoder,是上世纪提出的一种压缩算法,其核心思想是不断用字母表中不存在的char来代替最高频的char pair。举个例子,对于字符串aaabdaaabac,其字符串中最开始只出现了a/b/c/d这四个char;统计所有char pair,最高频的是aa,用不在字母表中的另一个字符Z代替aa,则原字符串变成了ZabdZabac,字母表变成了a/b/c/d/Z;如此不断进行下去,直到字母表大小达到一定的阈值,或者所有连续的char pair的频数都等于1了。关于BPE算法的进一步介绍请看这里:https://zhuanlan.zhihu.com/p/38130825。 第一种模型就是用BPE算法来得到高频subword的。比如下图的例子,语料集D中出现了5个low,2个lower等等。最开始,字母表V中是语料集中出现的所有单个字母的集合{l,o,…,d}。然后,发现e s这个char pair出现次数最多,将其作为一个subword加入到V中,同时将D中的es合并看作一个新的char。接着统计发现es t这个char pair(此时es已经是一个char了)出现次数最多,将其作为一个subword加入到V中,如此进行下去。发现没有,我们自动从D中提取了est这个subword,而est就是最高级的后缀。也就是说BPE算法自动提取到了英文的前缀、后缀等subword信息,完全避免了之前费时费力地从unfortunately中手工提取un、ly、fortun(e)的过程。这种方法也能解决未登录词问题,但是粒度又不至于太细。一方面是因为最开始的时候D中原始出现的单个字母都在V中,另一方面,由V中字母组成的未出现词也能由subword构成,比如下图中虽然less没有出现在D中,但可以由l es s这3个subword组成,而这3个subword是在最终的V中的。 得到高频subword作为V之后,后续在进行NLP任务时,encoder的时候查一下V,把char pair替换为新字符;decoder的时候查一下V,把新字符替换回原来的char pair。 最近比较流行的BERT,字典中既有相对比较常见的词,对于不太常见的词则用subwords/wordpieces来表示。 第二种被称为杂交模型的方法就相对简单了。这种方法是Manning老师提出来的,它就是在D中有这个word时就用word embedding,没有的时候就用char embedding来学习word embedding,非常简单。 fasttext就是skipgram+n-gram,一个词的embedding=组成这个词的n-gram的embedding的加权求和,所以fasttext也能解决OOV问题。

February 17, 2020 · 1 min

CS224N(1.31)Translation, Seq2Seq, Attention

今天介绍另一个NLP任务——机器翻译,以及神经网络机器翻译模型seq2seq和一个改进技巧attention。 机器翻译最早可追溯至1950s,由于冷战的需要,美国开始研制由俄语到英语的翻译机器。当时的机器翻译很简单,就是自动从词典中把对应的词逐个翻译出来。 后来在1990s~2010s,统计机器翻译(Statistical Machine Translation, SMT)大行其道。假设源语言是法语\(x\),目标语言是英语\(y\),机器翻译的目标就是寻找\(y\),使得\(P(y|x)\)最大,也就是下图的公式。进一步,通过贝叶斯公式可拆分成两个概率的乘积:其中\(P(y)\)就是之前介绍过的语言模型,最简单的可以用n-gram的方法;\(P(x|y)\)是由目标语言到源语言的翻译模型。为什么要把\(P(y|x)\)的求解变成\(P(x|y)*P(y)\)?逐个击破的意思,\(P(x|y)\)专注于翻译模型,翻译好局部的短语或者单词;而\(P(y)\)就是之前学习的语言模型,用来学习整个句子\(y\)的概率,专注于翻译出来的句子从整体上看起来更加通顺、符合语法与逻辑。所以问题就转化为怎样求解\(P(x|y)\)。 SMT进一步把\(P(x|y)\)分解成\(P(x,a|y)\),其中\(a\)表示一个对齐alignment,可以认为是两种语言之间单词和单词或短语和短语的一个对齐关系。如下图所示是一个英语和法语的alignment。对齐本身就很复杂,存在1对1,1对多,多对1,多对多等情况,所以\(P(x,a|y)\)的求解在给定\(y\)的情况下,不但要考虑对齐方案\(a\)的情况\(P(a|y)\),还需要考虑对齐之后词与词的翻译情况\(P(x|a,y)\),可能的情况非常多。 那么,SMT怎样找到\(\arg max_y\)呢?穷举所有情况是不可能的,启发式搜索是可行的。形象描述就是在搜索过程中,对概率较低的路径进行剪枝,只保留概率较大的翻译情况。如下图的搜索树,对于概率较低的路径就不往下搜索了。 总之,统计机器翻译非常复杂,有很多的子模块,需要很多的人工干预和特征工程。 2014年,seq2seq模型横空出世,神经网络机器翻译(Neural Machine Translation, NMT)方兴未艾。seq2seq顾名思义,就是从序列到序列的模型,因为机器翻译的源语言和目标语言都是seq。 seq2seq的NMT如下图所示,它由两个RNN组成,左边的红色部分称为Encoder RNN,它负责对源语言进行编码(Encode);右边的绿色部分称为Decoder RNN,它负责对目标语言进行解码(Decode)。首先,Encoder RNN可以是任意一个RNN,比如朴素RNN、LSTM或者GRU。Encoder RNN负责对源语言进行编码,学习源语言的隐含特征。Encoder RNN的最后一个神经元的隐状态作为Decoder RNN的初始隐状态。Decoder RNN是一个条件语言模型,一方面它是一个语言模型,即用来生成目标语言的;另一方面,它的初始隐状态是基于Encoder RNN的输出,所以称Decoder RNN是条件语言模型。Decoder RNN在预测的时候,需要把上一个神经元的输出作为下一个神经元的输入,不断的预测下一个词,直到预测输出了结束标志符<END>,预测结束。Encoder RNN的输入是源语言的word embeding,Decoder RNN的输入是目标语言的word embeding。 seq2seq是一个很强大的模型,不但可以用来做机器翻译,还可以用来做很多NLP任务,比如自动摘要、对话系统等。 seq2seq作为一个条件语言模型,形式化来说,它直接对\(P(y|x)\)进行建模,在生成\(y\)的过程中,始终有\(x\)作为条件,正如下图的条件概率所示。 上面介绍了seq2seq的预测过程,seq2seq的训练过程如下图所示。训练的时候,我们同时需要源语言和翻译好的目标语言,分别作为Encoder RNN和Deocder RNN的输入。对于Encoder RNN没什么好说的。Decoder RNN在训练阶段,每一个时间步的输入是提供的正确翻译词,输出是预测的下一个时间步的词的概率分布,比如在\(t=4\),预测输出是\(\hat y_4\),而正确答案是“with”,根据交叉熵损失函数,\(J_4=-\log P(“with”)\)。总的损失函数就是所有时间步的损失均值。 seq2seq的训练过程是end2end的,即把Encoder RNN和Decoder RNN作为一个整体进行训练,不会像SMT一样有很多的子模块单独训练。当然seq2seq也可以单独对encoder和deconder进行训练优化,再组合,但是这个效果不一定会比整体优化encoder和deconder更好。 上上张图介绍的seq2seq的预测过程,实际上是一个贪心的预测过程,即在Decoder RNN的每一步都贪心选择\(\hat y_t\)概率最大的那个词。但是贪心只能保证每一步是最优的,无法保证预测出来的句子整体是最优的。特别是如果在\(t\)时刻贪心选择的词不是全局最优,会导致\(t\)时刻往后的所有预测词都是错误的,没有回头路了。但是如果每个时间步都穷举所有可能的情况的话,时间复杂度\(O(V^T)\)又太高了。 Beam search搜索策略是贪心策略和穷举策略的一个折中方案,它在预测的每一步,都保留Top-k高概率的词,作为下一个时间步的输入。k称为beam size,k越大,得到更好结果的可能性更大,但计算消耗也越大。请注意,这里的Top-k高概率不仅仅指当前时刻的\(\hat y_t\)的最高概率,而是截止目前这条路径上的累计概率之和,如下图的公式所示。 举例如下,假设\(k=2\),第一个时间步保留Top-2的词为”he”和”I”,他们分别作为下一个时间步的输入。”he”输入预测输出前两名是”hit”和”struck”,则”hit”这条路的累加概率是”he”的概率加上”hit”的概率=-1.7,类似的可以算出其他几个词对应路径的概率打分。最后在这4条路上保留\(k=2\)条路,所以”hit”和”was”对应路径保留,作为下一个时间步的输入;”struck”和”got”对应路径被剪枝。 最终的搜索树如下图所示,可以看到在每个时间步都只保留了\(k=2\)个节点往下继续搜索。最后”pie”对应的路径打分最高,通过回溯法得到概率最高的翻译句子。请注意,beam search作为一种剪枝策略,并不能保证得到全局最优解,但它能以较大的概率得到全局最优解,同时相比于穷举搜索极大的提高了搜索效率。 在beam search的过程中,不同路径预测输出结束标志符<END>的时间点可能不一样,有些路径可能提前结束了,称为完全路径,暂时把这些完全路径放一边,其他路径接着beam search。beam search的停止条件有很多种,可以设置一个最大的搜索时间步数,也可以设置收集到的最多的完全路径数。 当beam search结束时,需要从n条完全路径中选一个打分最高的路径作为最终结果。由于不同路径的长度不一样,而beam search打分是累加项,累加越多打分越低,所以需要用长度对打分进行归一化,如下图所示。那么,为什么不在beam search的过程中就直接用下面的归一化打分来比较呢?因为在树搜索的过程中,每一时刻比较的两条路径的长度是一样的,即分母是一样的,所以归一化打分和非归一化打分的大小关系是一样的,即在beam search的过程中就没必要对打分进行归一化了。 ...

August 2, 2019 · 1 min