贪心搜索(greedy search)、集束搜索(beam search)、随机采样(random sample)
当我们训练完成一个自然语言生成模型后,需要使用这个模型生成新的语言(句子),如何生成这些句子,使用如下的方法:贪心搜索,集束搜索,随机搜索。
贪心搜索(greedy search)/采样(Sampling)
贪心搜索最为简单,直接选择每个输出的最大概率,直到出现终结符或最大句子长度。
在每个阶段都选择分值最高的项。此方法经常奏效,但显然不是最优的。
集束搜索(beam search)
集束搜索是一种启发式图搜索算法,在图的解空间比较大的情况下,为了减少搜索所占用的空间和时间,在每一步深度扩展的时候,剪掉一些质量比较差的结点,保留下一些质量较高的结点。
在sequence2sequence模型[中,beam search的方法只用在测试的情况(decoder解码的时候),因为在训练过程中,每一个decoder的输出是有正确答案的,也就不需要beam search去加大输出的准确率。
具体过程为:使用广度优先策略在树的每一层建立搜索树,按照启发代价对节点进行排序,然后仅留下预先确定的个数(Beam Width-集束宽度)的节点,仅这些节点在下一层次继续扩展,其他节点就被剪掉了。(注意:如果集束宽度无穷大,那该搜索就是宽度优先搜索)
好处:减少了空间消耗,并提高了时间效率。
假设字典为[a,b,c],beam size选择2,则如下图有:
- 在生成第1个词的时候,选择概率最大的2个词,那么当前序列就是a或b。
- 在生成第2个词的时候,我们将当前序列a或b,分别与字典中的所有词进行组合,得到新的6个序列aa ab ac ba bb bc,然后从其中选择2个概率最高的,作为当前序列,即ab或bb。
- 不断重复这个过程,直到遇到结束符为止。最终输出2个概率最高的序列。
一个正确且高效的算法需要处理的问题大概有两个:
充分利用硬件,可以处理批量数据,且尽量使用并行计算少用循环
处理好长短不同的生成结果
序列扩展的每一步迭代过程如图所示, 使用束搜索找出下一步分数最大的beam个
基础代码实现如下:
十分钟读懂Beam Search(1/2)
随机采样(random sample)
论文: The Curious Case of Neural Text Degeneration
随机采样是一种对Beam search进行改进的尝试。
解码过程用随机采样(sampling)代替取概率最大的词。采样的依据就是解码器输出的词典中每个词的概率分布。相比于按概率“掐尖”,这样会增大所选词的范围,引入更多的随机性。这个方法是谷歌开放式聊天机器人Meena[DialoGPT、Meena]采用的方式。当时那篇论文的结论就是这种随机采样的方法远好于Beam Search。但这其实也是有条件的,随机采样容易产生前后不一致的问题。而在开放闲聊领域,生成文本的长度都比较短,这种问题就被自然的淡化了。
采样的时候有一个可以控制的超参数,称为温度(temperature, T)。解码器的输出层后面通常会跟一个softmax函数来将输出概率归一化,通过改变T可以控制概率的形貌。softmax的公式如下,当T大的时候,概率分布趋向平均,随机性增大;当T小的时候,概率密度趋向于集中,即强者愈强,随机性降低,会更多地采样出“放之四海而皆准”的词汇。
top-k采样
这个方法就是在采样前将输出的概率分布截断,取出概率最大的k个词构成一个集合,然后将这个子集词的概率再归一化,最后从新的概率分布中采样词汇。这个办法据说可以获得比Beam Search好很多的效果,但也有一个问题,就是这个k不太好选。因为这个概率分布变化比较大,有时候可能很均匀(flat),有的时候比较集中(peaked)。对于集中的情况还好说,当分布均匀时,一个较小的k容易丢掉很多优质候选词。但如果k定的太大,这个方法又会退化回普通采样。
top-p采样
top-p相比前面那些都更好的采样方式,他不再取一个固定的k,而是固定候选集合的概率密度和在整个概率分布中的比例。也就是构造一个最小候选集,使得
选出来这个集合之后也和top-k采样一样,重新归一化集合内词的概率,并把集合外词的概率设为0。
惩罚重复
为了解决重复问题,还可以通过惩罚因子将出现过词的概率变小或者强制不使用重复词来解决。惩罚因子来自于同样广为流传的《CTRL: A Conditional Transformer Language Model for Controllable Generation》。
Top_k, Top_p代码实现
import torchdef top_k_top_p_filtering(logits: torch.FloatTensor, top_k: int = 0, top_p: float = 1.0, filter_value: float = -float("Inf"), min_tokens_to_keep: int = 1) -> torch.FloatTensor:'''logits: logit分布的shape (batch_size, vocabulary size)'''scores = logitsif top_k > 0:top_k = min(max(top_k, min_tokens_to_keep), logits.size(-1))indices_to_remove = scores < torch.topk(scores, top_k)[0][:, -1, None] #None方便扩展维度而不该改变数据排列顺序#结果为Bool类型表示是否大于第k个值scores = scores.masked_fill(indices_to_remove, filter_value)if top_p < 1.0:sorted_logits, sorted_indices = torch.sort(scores, descending = True) #降序排列cumulative_probs = sorted_logits.softmax(dim=-1).cumsum(dim=-1) #softmax操作后,累计计算概率分布sorted_indices_to_remove = cumulative_probs > top_pif min_tokens_to_keep > 1:#保持至少有min_tokens_to_keep个单词可选sorted_indices_to_remove[:, :min_tokens_to_keep - 1] = 0sorted_indices_to_remove[:, 1:] = sorted_indices_to_remove[:, :-1].clone()sorted_indices_to_remove[:, 0] = 0indices_to_remove = sorted_indices_to_remove.scatter(1, sorted_indices, sorted_indices_to_remove)scores = scores.masked_fill(indices_to_remove, filter_value)return scoresx = torch.randn(4, 8)
print(x)
print(top_k_top_p_filtering(x, top_p = 0.6, min_tokens_to_keep = 2))
Module | Complexity | # Parameters |
Self-Attention | ||
FFN |
参考:
集束搜索(beam search)和贪心搜索(greedy search)
自然语言生成-集束搜索beam search和随机搜索random search
十分钟读懂Beam Search(1/2)
十分钟读懂Beam Search 2
贪心搜索(greedy search)、集束搜索(beam search)、随机采样(random sample)相关推荐
- Beam Search集束搜索
在Seq2Seq解码部分中,常用到Beam Search.每个时刻它会保存b(beam size)个概率最大的选择作为当前的最佳选择,然后解码下一时刻时,继续选择和之前保存的b个选择组合起来后的概率最 ...
- 算法工程师面试之集束算法(beam search)
1.前言 文章来源: LawsonAbs@CSDN 2.动机 束搜索常用在生成模型中?为什么? 这和束搜索的使用有关.生成模型中,我们需要根据之前的字符串预测接下来的词,这个预测是根据词表大小预测.如 ...
- Beam Search与Prefix Beam Search的理解与python实现
引言 Beam search是一种动态规划算法,能够极大的减少搜索空间,增加搜索效率,并且其误差在可接受范围内,常被用于Sequence to Sequence模型,CTC解码等应用中 时间复杂度 对 ...
- 集束搜索算法 beam search
类似于贪心算法,局部最优解,只不过有三个带宽增加概率 https://blog.csdn.net/pipisorry/article/details/78404964 https://blog.csd ...
- 集束搜索(beam search)和贪心搜索(greedy search)
最近读论文的时候看到文中经常用到集束搜索(beam search),可能很多人不懂这到底是个什么算法,其实很简单,顺便把贪心搜索(greedy search)也介绍一下. 贪心搜索(greedy se ...
- 集束搜索(Beam Search Algorithm )
看计算机科学中最重要的32个算法,其中有个是集束搜索(又名定向搜索,Beam Search)--最佳优先搜索算法的优化.使用启发式函数评估它检查的每个节点的能力.不过,集束搜索只能在每个深度中发现前m ...
- java实现beamsearch_Beam Search(集束搜索/束搜索)
1.简介 Beam Search(集束搜索)是一种启发式图搜索算法,通常用在图的解空间比较大的情况下,为了减少搜索所占用的空间和时间,在每一步深度扩展的时候,剪掉一些质量比较差的结点,保留下一些质量较 ...
- Greedy search与beam search
最近在看End-to-end Relation Extraction using LSTMs on Sequences and Tree Structures这篇文章时,看到此文在Entity det ...
- Teacher Forcing机制及Beam search详解
RNN在训练过程中的问题 训练迭代过程早期的RNN预测能力非常弱,几乎不能给出好的生成结果.如果某一个unit产生了垃圾结果,必然会影响后面一片unit的学习.teacher forcing最初的mo ...
最新文章
- 让Web开发者事半功倍的8个网站
- stm32 Bootloader设计(YModem协议)
- Linux 下升级 python2 到python3
- 前端学习(627):数据类型
- 腾讯-地图:腾讯位置服务
- “鸿蒙”系统的产生并不是为了手机?任正非透露实情...
- Echarts数据grid直角坐标系(xAxis、yAxis)详解
- 【Spring 持久层】Spring 与 Mybatis 整合
- BOMTool更新到1.3.0.8
- HTML实现学习网站首页
- Java继承中的构造方法使用的理解,白话文,简单易理解
- 中信行业分类判断标准
- scrcpy之将Android手机投屏到Linux电脑实践
- github、npm、Stack Overflow...... 一键加速 【支持多平台】
- 机器人设计之一简单机械设计
- Java学习-面向对象进阶
- 计算机CQ,什么是Cq(Ct)值?
- DELL笔记本硬件 ACPI\SMO8800找不到合适驱动问题解决
- playwright使用心得
- 防火墙配置(CiscoPTGNS3)