beam_search
paddle.fluid.layers.
beam_search
(pre_ids, pre_scores, ids, scores, beam_size, end_id, level=0, is_accumulated=True, name=None, return_parent_idx=False)[源代码]
束搜索(Beam search)是在机器翻译等生成任务中选择候选词的一种经典算法
更多细节参考 Beam Search
该OP仅支持LoDTensor,在计算产生得分之后使用,完成单个时间步内的束搜索。具体而言,在计算部分产生 ids
和 scores
后,对于每个源句(样本)该OP从 ids
中根据其对应的 scores
选择当前时间步 top-K (K
是 beam_size
)的候选词id。而 pre_id
和 pre_scores
是上一时间步 beam_search
的输出,加入输入用于特殊处理到达结束的翻译候选。
注意,如果 is_accumulated
为 True,传入的 scores
应该是累积分数。反之,scores
是单步得分,会在该OP内被转化为log值并累积到 pre_scores
作为最终得分。如需使用长度惩罚,应在计算累积分数前使用其他OP完成。
束搜索的完整用法请参阅以下示例:
fluid/tests/book/test_machine_translation.py
- 参数:
- pre_ids (Variable) - LoD level为2的LodTensor,表示前一时间步选择的候选id,是前一时间步
beam_search
的输出。第一步时,其形状应为为 , lod应为 。数据类型为int64。 - pre_scores (Variable) - 维度和LoD均与
pre_ids
相同的LodTensor,表示前一时间步所选id对应的累积得分,是前一时间步beam_search
的输出。数据类型为float32。 - ids (None|Variable) - 包含候选id的LodTensor。LoD应与
pre_ids
相同,形状为 ,其中第一维大小与pre_ids
相同且batch_size
会随样本到达结束而自动减小,K
应该大于beam_size
。数据类型为int64。可为空,为空时使用scores
上的索引作为id。 - scores (Variable) - 表示
ids
对应的累积分数的LodTensor变量, 维度和LoD均与ids
相同。 - beam_size (int) - 指明束搜索中的束宽度。
- end_id (int) - 指明标识序列结束的id。
- level (int,可选) - 可忽略,当前不能更改 。知道LoD level为2即可,两层lod的意义如下: 第一级表示每个源句(样本)包含的beam大小,若满足结束条件(达到
beam_size
个结束)则变为0;第二级是表示每个beam被选择的次数。 - is_accumulated (bool,可选) - 指明输入分数
scores
是否为累积分数,默认为True。 - name (str,可选) – 具体用法请参见 Name ,一般无需设置,默认值为None。
- return_parent_idx (bool,可选) - 指明是否返回一个额外的Tensor,该Tensor保存了选择的id的父节点(beam)在
pre_id
中索引,可用于通过gather OP更新其他Tensor的内容。默认为False。
- pre_ids (Variable) - LoD level为2的LodTensor,表示前一时间步选择的候选id,是前一时间步
返回:Variable的二元组或三元组。二元组中包含了当前时间步选择的id和对应的累积得分两个LodTensor,形状相同且均为
,LoD相同且level均为2,数据类型分别为int64和float32;若 return_parent_idx
为True时为三元组,多返回一个保存了父节点在 pre_id
中索引的Tensor,形状为
,数据类型为int64。
返回类型:tuple
代码示例
- import paddle.fluid as fluid
- # 假设 `probs` 包含计算神经元所得的预测结果
- # `pre_ids` 和 `pre_scores` 为beam_search之前时间步的输出
- beam_size = 4
- end_id = 1
- pre_ids = fluid.layers.data(
- name='pre_id', shape=[1], lod_level=2, dtype='int64')
- pre_scores = fluid.layers.data(
- name='pre_scores', shape=[1], lod_level=2, dtype='float32')
- probs = fluid.layers.data(
- name='probs', shape=[10000], dtype='float32')
- topk_scores, topk_indices = fluid.layers.topk(probs, k=beam_size)
- accu_scores = fluid.layers.elementwise_add(
- x=fluid.layers.log(x=topk_scores),
- y=fluid.layers.reshape(
- pre_scores, shape=[-1]),
- axis=0)
- selected_ids, selected_scores = fluid.layers.beam_search(
- pre_ids=pre_ids,
- pre_scores=pre_scores,
- ids=topk_indices,
- scores=accu_scores,
- beam_size=beam_size,
- end_id=end_id)