在seq2seq任务重,传统的获取decoder输出的结果过程中,在每一个时间步上,我们只选择概率最大的那个词,作为当前时间步的输出,即在每一个时间步上我们取到的都是最大概率的词。等到解码器获取到
我们可以计算全部的输出的概率乘积,选择最大的那一个作为句子的输出,但是我们输出的句子通常都比较长,而且再这样的情况下我们需要计算的数据量会非常大。
beam search是基于上述贪心策略和1.1中提及方法的的兼顾,我们使用 Beam width 表示每次时间步保存最大概率的个数,即例如当 Beam width = 3 的时候,当前时间步保存了三个,在下一个时间步上也是一样保存三个,即我们通过约束搜索空间的大小来实现提高算法效率。
当 Beam width = 1 的时候,就是贪心策略,当 Beam width = 所有候选词的时候,就是1.1中计算全部的概率。
例如上图,我们的 Beam width = 1 时,我们的输出序列会是 ABB ,并不会得到最好的结果(BBB)。当 Beam width = 2 时,我们在第一个时间步上有最大两个概率 [0.6, 0.4] 故保存 [A, B],目前序列为A和B;在第二个时间步上有最大两个概率 [0.36, 0.36] 故保存 [B, B],目前序列为AB和BB;在第三个时间步上有最大两个概率 [0.324, 0.144] 故保存 [B, B],目前序列为ABB和BBB;所以当 Beam width = 2 时可以获得最好的结果。
进一步,我们再看这个例子,输入句子起始 ,输出只会是 [x, y, w, ] 这四个中的一个,我们取 Beam width = 3 :
第一个时间步:选择概率最大的三个词保存 [x, y, w],并把 [x, y, w] 依次作为下一个时间步输入;
第二个时间步:由 [x, y, w] 依次作为输入分别得到九个输出,选择概率最大的三个保存 [x, y, y],并把 [x, y, y] 依次作为下一个时间步输入;
第三个时间步:由 [x, y, y] 依次作为输入分别得到九个输出,选择概率最大的三个保存 [x, y, y],并把 [x, x, x] 依次作为下一个时间步输入;
...
重复上述步骤,直到获得结束符 为当前输出序列为最大概率时候,或者是当前输出序列达到最大句子长度时结束,如果是第二种结束情况的话,输出序列为最大概率的那一个序列。
所以,输出的情况可能是两种:
1. 输出序列没有达到最大长度的时候,搜索空间中最大概率的序列是以结束符 结尾的,并将这个序列作为输出序列;
2. 输出序列达到最大长度的时候,在搜索空间中选择最大概率的序列,并将这个序列加上结束符 作为输出序列;