关于seq2seq中的beam search

参考链接:

https://www.zhihu.com/question/54356960

https://zhuanlan.zhihu.com/p/36029811?group_id=972420376412762112

讲的很详细清晰

作者:习翔宇
链接:https://www.zhihu.com/question/54356960/answer/375588742
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

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

法语句子"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个或者其他的个数,集束搜索通常会找到比贪婪搜索更好的输出结果。

猜你喜欢

转载自blog.csdn.net/weixin_40240670/article/details/86086775