<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>End2End on bitJoy</title><link>https://bitjoy.net/tags/end2end/</link><description>Recent content in End2End on bitJoy</description><generator>Hugo -- 0.148.2</generator><language>en</language><lastBuildDate>Fri, 02 Aug 2019 11:50:31 +0800</lastBuildDate><atom:link href="https://bitjoy.net/tags/end2end/index.xml" rel="self" type="application/rss+xml"/><item><title>CS224N（1.31）Translation, Seq2Seq, Attention</title><link>https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/</link><pubDate>Fri, 02 Aug 2019 11:50:31 +0800</pubDate><guid>https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/</guid><description>&lt;p>今天介绍另一个NLP任务——机器翻译，以及神经网络机器翻译模型seq2seq和一个改进技巧attention。&lt;/p>
&lt;p>机器翻译最早可追溯至1950s，由于冷战的需要，美国开始研制由俄语到英语的翻译机器。当时的机器翻译很简单，就是自动从词典中把对应的词逐个翻译出来。&lt;/p>
&lt;p>后来在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)\)。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/p7.png">&lt;/p>
&lt;p>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)\)，可能的情况非常多。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/p10.png">&lt;/p>
&lt;p>那么，SMT怎样找到\(\arg max_y\)呢？穷举所有情况是不可能的，启发式搜索是可行的。形象描述就是在搜索过程中，对概率较低的路径进行剪枝，只保留概率较大的翻译情况。如下图的搜索树，对于概率较低的路径就不往下搜索了。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/p18.png">&lt;/p>
&lt;p>总之，统计机器翻译非常复杂，有很多的子模块，需要很多的人工干预和特征工程。&lt;/p>
&lt;hr>
&lt;p>2014年，seq2seq模型横空出世，神经网络机器翻译（Neural Machine Translation, NMT）方兴未艾。seq2seq顾名思义，就是从序列到序列的模型，因为机器翻译的源语言和目标语言都是seq。&lt;/p>
&lt;p>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在预测的时候，需要把上一个神经元的输出作为下一个神经元的输入，不断的预测下一个词，直到预测输出了结束标志符&amp;lt;END&amp;gt;，预测结束。Encoder RNN的输入是源语言的word embeding，Decoder RNN的输入是目标语言的word embeding。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/p24.png">&lt;/p>
&lt;p>seq2seq是一个很强大的模型，不但可以用来做机器翻译，还可以用来做很多NLP任务，比如自动摘要、对话系统等。&lt;/p>
&lt;p>seq2seq作为一个条件语言模型，形式化来说，它直接对\(P(y|x)\)进行建模，在生成\(y\)的过程中，始终有\(x\)作为条件，正如下图的条件概率所示。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/p26.png">&lt;/p>
&lt;p>上面介绍了seq2seq的预测过程，seq2seq的训练过程如下图所示。训练的时候，我们同时需要源语言和翻译好的目标语言，分别作为Encoder RNN和Deocder RNN的输入。对于Encoder RNN没什么好说的。Decoder RNN在训练阶段，每一个时间步的输入是提供的正确翻译词，输出是预测的下一个时间步的词的概率分布，比如在\(t=4\)，预测输出是\(\hat y_4\)，而正确答案是“with”，根据交叉熵损失函数，\(J_4=-\log P(“with”)\)。总的损失函数就是所有时间步的损失均值。&lt;/p>
&lt;p>seq2seq的训练过程是end2end的，即把Encoder RNN和Decoder RNN作为一个整体进行训练，不会像SMT一样有很多的子模块单独训练。当然seq2seq也可以单独对encoder和deconder进行训练优化，再组合，但是这个效果不一定会比整体优化encoder和deconder更好。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/p27.png">&lt;/p>
&lt;p>上上张图介绍的seq2seq的预测过程，实际上是一个贪心的预测过程，即在Decoder RNN的每一步都贪心选择\(\hat y_t\)概率最大的那个词。但是贪心只能保证每一步是最优的，无法保证预测出来的句子整体是最优的。特别是如果在\(t\)时刻贪心选择的词不是全局最优，会导致\(t\)时刻往后的所有预测词都是错误的，没有回头路了。但是如果每个时间步都穷举所有可能的情况的话，时间复杂度\(O(V^T)\)又太高了。&lt;/p>
&lt;p>Beam search搜索策略是贪心策略和穷举策略的一个折中方案，它在预测的每一步，都保留Top-k高概率的词，作为下一个时间步的输入。k称为beam size，k越大，得到更好结果的可能性更大，但计算消耗也越大。请注意，这里的Top-k高概率不仅仅指当前时刻的\(\hat y_t\)的最高概率，而是截止目前这条路径上的累计概率之和，如下图的公式所示。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/p31.png">&lt;/p>
&lt;p>举例如下，假设\(k=2\)，第一个时间步保留Top-2的词为”he”和”I”，他们分别作为下一个时间步的输入。”he”输入预测输出前两名是”hit”和”struck”，则”hit”这条路的累加概率是”he”的概率加上”hit”的概率=-1.7，类似的可以算出其他几个词对应路径的概率打分。最后在这4条路上保留\(k=2\)条路，所以”hit”和”was”对应路径保留，作为下一个时间步的输入；”struck”和”got”对应路径被剪枝。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/p34.png">&lt;/p>
&lt;p>最终的搜索树如下图所示，可以看到在每个时间步都只保留了\(k=2\)个节点往下继续搜索。最后”pie”对应的路径打分最高，通过回溯法得到概率最高的翻译句子。请注意，beam search作为一种剪枝策略，并不能保证得到全局最优解，但它能以较大的概率得到全局最优解，同时相比于穷举搜索极大的提高了搜索效率。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/p44.png">&lt;/p>
&lt;p>在beam search的过程中，不同路径预测输出结束标志符&amp;lt;END&amp;gt;的时间点可能不一样，有些路径可能提前结束了，称为完全路径，暂时把这些完全路径放一边，其他路径接着beam search。beam search的停止条件有很多种，可以设置一个最大的搜索时间步数，也可以设置收集到的最多的完全路径数。&lt;/p>
&lt;p>当beam search结束时，需要从n条完全路径中选一个打分最高的路径作为最终结果。由于不同路径的长度不一样，而beam search打分是累加项，累加越多打分越低，所以需要用长度对打分进行归一化，如下图所示。那么，为什么不在beam search的过程中就直接用下面的归一化打分来比较呢？因为在树搜索的过程中，每一时刻比较的两条路径的长度是一样的，即分母是一样的，所以归一化打分和非归一化打分的大小关系是一样的，即在beam search的过程中就没必要对打分进行归一化了。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://bitjoy.net/posts/2019-08-02-cs224n-0131-translation-seq2seq-attention/p46.png">&lt;/p></description></item></channel></rss>