seq2seq 中的 beam search 算法过程是怎样的?

seq2seq 中的 beam search 是每一步确定前 k 个概率最大的单词加入列表中么?beam search 是用在 test 的 deco…
关注者
844
被浏览
356,787

25 个回答

谢邀。对于MLE算法训练的模型,beam search只在预测的时候需要。训练的时候因为知道正确答案,并不需要再进行这个搜索。

预测的时候,假设词表大小为3,内容为a,b,c。beam size是2,decoder解码的时候:

1: 生成第1个词的时候,从词表中选择概率分最大的2个词。这里假设a和c的分最高,那么当前的2个序列就是a和c。

2:生成第2个词的时候,我们将当前序列a和c,分别与词表中的所有词进行组合,得到新的6个序列aa ab ac ca cb cc,计算每个序列的得分并选择得分最高2个序列,作为新的当前序列,假如为cb cc。

3:后面会不断重复这个过程,直到遇到结束符或者达到最大长度为止。最终输出得分最高的2个序列。

答案请见

欢迎关注专栏


我们以机器翻译举例,在得到训练模型之后,我们希望能够得到句子序列的条件概率最大的序列,例如

法语句子"Jane visite l'Afrique en septembre."
翻译1-Jane is visiting Africa in September.
翻译2-Jane is going to be visiting Africa in September.

显然翻译2听起来比较笨拙,并不是最好的翻译,也就是

P(y_1|x)>P(y_2|x)\tag{1}

因此我们希望得到一个单词序列表示英文句子使得条件概率最大:

\arg\max_{y} P( y^{<1>},y^{<2>},y^{<3>},...y^{<T_y>}|x^{<1>},x^{<2>},...x^{<T_x>})\tag{2}



1. 为毛不用greedy search

一个很直观的方法是采用贪心搜索(greedy search),在生成第一个词 y^{<1>} 的分布之后,根据条件语言模型挑选出最有可能的第一个词 y^{<1>} ,然后生成第二个词 y^{<2>} 的概率分布挑选第二个词 y^{<2>} ,依此类推。可以看出贪心算法始终是选择每一个最大概率的词,但我们真正需要的是一次性挑选整个单词序列 y^{<1>},y^{<2>},y^{<3>},...y^{<T_y>} 使得整体的条件概率最大,所以贪心算法先挑出最好的第一个词,在这之后再挑最好的第二词,然后再挑第三个,这种方法其实并不管用,我们用上面的例子进行说明。

法语句子"Jane visite l'Afrique en septembre."
翻译1-Jane is visiting Africa in September.
翻译2-Jane is going to be visiting Africa in September.

翻译1显然比翻译2要更好,更加简洁的表达了意思,第二个就很啰嗦并且有很多不重要的词。如果贪心算法挑选了 y^{<1>},y^{<2>}= ('Jane' , 'is'),那么在英语中"is going"更加常见,因此在选择 y^{<3>} 时就会得到 y^{<3>}= 'going',于是对于法语句子来说"Jane is going"相比"Jane is visiting"会有更高的概率作为法语的翻译,所以很有可能如果你仅仅根据前两个词来估计第三个词的可能性,得到的就是going,最终你会得到一个欠佳的句子。


2. Beam Search

在Beam Search中只有一个参数B,叫做beam width(集束宽),用来表示在每一次挑选top B的结果。

我们用下面这个例子来做说明,假设字典大小为10000,B=3

法语句子"Jane visite l'Afrique en septembre."
翻译1-Jane is visiting Africa in September.
翻译2-Jane is going to be visiting Africa in September.

第一步的时候,我们通过模型计算得到 y^{<0>} 的分布概率,选择前B个作为候选结果,比如如下图所示的"in", "jane", "september"

图1 beam search step 1

第二步的时候,我们已经选择出了in、jane、September作为第一个单词的三个最可能选择,beam search针对每个第一个单词考虑第二个单词的概率,例如针对单词“in”,我们将 y^{<1>} ='in',然后将它喂给 x^{<2>} ,输出结果 y^{<2>} 作为第二个单词的概率输出。因为我们关注的是最有可能的 P(y^{<2>},y^{<1>}|x) ,因此我们的选择方法为:

P(y^{<2>},"in"|x)=P(y^{<2>}|"in",x)P("in"|x) \tag{3}

然后同样将“jane”作为将 y^{<1>} ,然后将它喂给 x^{<2>} ,计算得到 P(y^{<2>}|"jane",x) ,然后计算得到:

P(y^{<2>},"jane"|x)=P(y^{<2>}|"jane",x)P("jane"|x) \tag{4}

同样将"september"作为将 y^{<1>} ,然后将它喂给 x^{<2>} ,计算得到 P(y^{<2>}|"september",x) ,然后计算得到:

P(y^{<2>},"september"|x)=P(y^{<2>}|"september",x)P("september"|x) \tag{5}

这样我们就计算得到了 B\times10000=30000 个选择,那么选择前3个,比如得到的结果是:

  • in september
  • jane is
  • jane visits

这样我们就找到了第一个和第二个单词对最可能的三个选择,这也意味着我们去掉了September作为英语翻译结果第一个单词的选择。


第三步的时候,同样我们将我们将 y^{<1>} ='in', y^{<2>} ='september',然后将它喂给 x^{<3>} ,输出结果 y^{<3>} 作为第三个单词的概率输出

图3

这样我们得到前三的结果是:

  • in september jane
  • jane is visiting
  • jane visits africa


第四步的时候同理,增加一个单词作为输入,这样最终会找到“Jane visits africa in september”这个句子,终止在句尾符号。


在集束宽为3时,集束搜索一次只考虑3个可能结果。注意如果集束宽等于1,只考虑1种可能结果,这实际上就变成了贪婪搜索算法,上面里我们已经讨论过了。但是如果同时考虑多个,可能的结果比如3个,10个或者其他的个数,集束搜索通常会找到比贪婪搜索更好的输出结果。


注:以上部分内容和全部图片来自于吴恩达深度学习课程,欢迎大家关注