BeamSearch计算过程和代码实现

本文深入探讨了束搜索算法,一种用于序列生成任务的关键技术,如机器翻译,通过束宽度控制搜索效率,平衡多样性和计算成本。
摘要由CSDN通过智能技术生成

Beam search(束搜索)是一种用于生成序列的搜索算法,常用于序列生成任务,例如机器翻译、语音识别和文本生成。它是一种启发式算法,旨在在生成序列时平衡搜索空间的广度和深度。

Beam search使用一个参数称为"beam width"(束宽度)来控制搜索的宽度,即在每个时间步骤选择保留的最有希望的候选项数量。在每个时间步骤,Beam search保留最有希望的K个候选项,其中K是束宽度。

下面是Beam search算法的详细步骤:

  1. 初始化:将初始输入作为序列的起始点,并将其放入候选项列表中。

  2. 生成候选项:对于每个候选项,使用模型(例如神经网络)生成下一个可能的元素或单词。

  3. 扩展候选项:对于每个候选项,将生成的元素添加到当前序列中,并计算相应的分数或概率。这些分数用于评估候选项的好坏。

  4. 剪枝:根据分数或概率对候选项进行排序,并选择当前分数最高的K个候选项,将其保留为下一步的候选项。

  5. 终止条件:如果生成的序列达到了预定的长度,或者满足特定的终止条件(例如遇到了终止标记),则停止搜索。

  6. 重复步骤2至5,直到到达终止条件。

  7. 返回结果:从最终的K个候选项中选择得分最高的序列作为最终的输出。

Beam search的优点是可以在生成序列时保持一定的多样性,因为它保留了多个候选项,并在每个时间步骤维护了一个较小的搜索空间。这有助于避免过于确定性的结果,并提供更多选择的可能性。

然而,Beam search也存在一些限制。它可能会陷入局部最优解,因为它只考虑了当前时间步骤的最有希望的候选项,并没有全局优化。此外,束宽度的选择也会影响结果,较小的束宽度可能会导致搜索空间不足,而较大的束宽度会增加计算成本。

算法关键点:在解码过程中,每次都挑选当前解码字的前k个最大概率的字符,第一轮可以得到k个结果,第二轮可以k2个结果,然后在这k2个结果中选择前k个最大概率的结果。依次类推...

具体步骤:

1.初始化Result列表用来存储每次得到的最大k个概率结果,初始化为[[list(),1]] 1为当前初始化的成绩

2.遍历解码长度S(解码出来S个字),

3.编历Result,用来为每个当前为止的最大k个结果解码出候选集

4.每个解码出的k个结果统一存储在Condidate列表中

5.按照成绩选取前k个作为Result,继续遍历,直到解码出S长度或者<eos>

from math import log
from numpy import array
from numpy import argmax

# 集束搜索
def beam_search_decoder(data, k):
	sequences = [[list(), 1.0]]#初始化存储最后结果的列表,存储k个
	# 遍历序列中的每一步
	for row in data:#序列的最大长度
		all_candidates = list()
		# 扩展每个候选项,即解码当前所得序列的下一个字
		for i in range(len(sequences)):
			seq, score = sequences[i]
			for j in range(len(row)):#计算每个词表中的字的成绩
				candidate = [seq + [j], score * -log(row[j])]
				all_candidates.append(candidate)
		# 根据分数排列所有候选项
		ordered = sorted(all_candidates, key=lambda tup:tup[1])
		# 选择k个最有可能的
		sequences = ordered[:k]
	return sequences

# 定义一个由10个单词组成的序列,单词来自于大小为5的词汇表
data = [[0.1, 0.2, 0.3, 0.4, 0.5],
		[0.5, 0.4, 0.3, 0.2, 0.1],
		[0.1, 0.2, 0.3, 0.4, 0.5],
		[0.5, 0.4, 0.3, 0.2, 0.1],
		[0.1, 0.2, 0.3, 0.4, 0.5],
		[0.5, 0.4, 0.3, 0.2, 0.1],
		[0.1, 0.2, 0.3, 0.4, 0.5],
		[0.5, 0.4, 0.3, 0.2, 0.1],
		[0.1, 0.2, 0.3, 0.4, 0.5],
		[0.5, 0.4, 0.3, 0.2, 0.1]]
data = array(data)
# 解码输出序列
result = beam_search_decoder(data, 3)
# 打印结果

for seq in result:
	print(seq)
  • 24
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Beam search(束搜索)是一种常用的序列生成算法,它在生成一个序列时,每一步都会保留 $k$ 个最有可能的候选项,然后选择得分最高的其中一个作为下一步的输入,并重复此过程直到生成完整个序列。 以下是一个 Python 实现的简单的 beam search 算法代码示例: ```python import math def beam_search(start_sequence, model, beam_size, max_len): """ 使用 beam search 算法生成序列。 参数: start_sequence:起始序列,一般为特殊起始符号。 model:生成模型。 beam_size:束宽,即保留的最有可能的候选项数量。 max_len:生成序列的最大长度。 返回: 生成的序列。 """ # 将起始序列作为第一步的输入。 candidates = [{'tokens': [start_sequence], 'score': 0}] # 不断扩展序列,直到最大长度。 for _ in range(max_len): # 生成下一步的所有可能的候选项。 next_candidates = [] for candidate in candidates: # 获取当前序列的最后一个标记。 last_token = candidate['tokens'][-1] # 使用模型预测下一个标记和对应的得分。 scores = model(last_token) # 选择得分最高的前 beam_size 个候选项。 top_scores, top_tokens = torch.topk(scores, beam_size) for score, token in zip(top_scores, top_tokens): # 计算候选项的总得分。 total_score = candidate['score'] + score.item() # 将新的候选项加入到候选项列表中。 next_candidates.append({'tokens': candidate['tokens'] + [token], 'score': total_score}) # 保留得分最高的前 beam_size 个候选项。 sorted_candidates = sorted(next_candidates, key=lambda x: -x['score'])[:beam_size] candidates = sorted_candidates # 返回得分最高的序列。 best_sequence = candidates[0]['tokens'] return best_sequence ``` 这个代码示例中,输入参数包括起始标记、生成模型、束宽和最大序列长度。在算法的主循环中,首先将起始标记作为第一步的输入,然后不断扩展序列直到达到最大长度为止。在每一步中,使用模型预测下一个标记的概率分布,并选择得分最高的前 $k$ 个候选项作为下一步的输入。然后计算每个候选项的总得分,并保留得分最高的前 $k$ 个候选项。最后返回得分最高的序列。 需要注意的是,这个示例代码中的模型预测函数 `model` 需要根据具体的应用场景进行实现。此外,这个算法还有一些改进的空间,比如可以使用剪枝等技巧来提高算法的效率和准确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅白Coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值