beamsearch学习总结以及代码解读

75 篇文章 7 订阅
61 篇文章 2 订阅

一、总结
【理解】seq2seq中的beam search算法过程:https://zhuanlan.zhihu.com/p/28048246
【理解】如何通俗的理解beam search?:https://zhuanlan.zhihu.com/p/82829880
在这里插入图片描述

二、代码
【实现】
How to Implement a Beam Search Decoder for Natural Language Processing:
https://machinelearningmastery.com/beam-search-decoder-natural-language-processing/

from math import log
from numpy import array
from numpy import argmax
# beam search
def beam_search_decoder(data, k):
    sequences = [[list(), 0.0]]
    # walk over each step in sequence
    for row in data:
        all_candidates = list()
        # expand each current candidate
        for i in range(len(sequences)):
            # seq是一个路径列表,score是这个列表对应的分数
            seq, score = sequences[i]
            for j in range(len(row)):
                # row[j]是这个节点的得分,得分小于1,所以是个负数,所以log后用减号?
                # 这里分数的更新感觉没有利用i-1位取值的不同来更新,估计只是做个模拟
                candidate = [seq + [j], score - log(row[j])]
                all_candidates.append(candidate)
        # order all candidates by score
        # 根据分数来排序
        ordered = sorted(all_candidates, key=lambda tup: tup[1])
        # select k best
        sequences = ordered[:k]
    return sequences
# define a sequence of 10 words over a vocab of 5 words
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)
# decode sequence
result = beam_search_decoder(data, 3)
# print result
for seq in result:
    print(seq)
    
# 输出
"""
[[4, 0, 4, 0, 4, 0, 4, 0, 4, 0], 6.931471805599453]
[[4, 0, 4, 0, 4, 0, 4, 0, 4, 1], 7.154615356913663]
[[4, 0, 4, 0, 4, 0, 4, 0, 3, 0], 7.154615356913663]
"""
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` 需要根据具体的应用场景进行实现。此外,这个算法还有一些改进的空间,比如可以使用剪枝等技巧来提高算法的效率和准确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值