自然语言处理任务,比如caption generation(图片描述文本生成)、机器翻译中,都需要进行词或者字符序列的生成。常见于seq2seq模型或者RNNLM模型中。

这篇博文主要介绍文本生成解码过程中用的greedy search 和beam search算法实现。其中,greedy search 比较简单,着重介绍beam search算法的实现。

我们在文本生成解码时,实际上是想找对最有的文本序列,或者说是概率,可能性最大的文本序列。而要在全局搜索这个最有解空间,往往是不可能的(因为词典太大),建设生成序列长度为N,词典大小为V, 则复杂度为 V^N次方。这实际上是一个NP难题。退而求其次,我们使用启发式算法,来找到可能的最优解,或者说足够好的解。

假设序列数据(假设每个位置词的概率都已经给出):

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)

1、greedy search decoder

非常简单,我们用argmax就可以实现

# greedy decoder
def greedy_decoder(data):
# 每一行最大概率词的索引
return [argmax(s) for s in data]

完整代码

from numpy import array
from numpy import argmax # greedy decoder
def greedy_decoder(data):
# 每一行最大概率词的索引
return [argmax(s) for s in data] # 定义一个句子,长度为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)
# 使用greedy search解码
result = greedy_decoder(data)
print(result)

2. beam search

与greedy search不同,beam search返回多个最有可能的解码结果(具体多少个,由参数k执行)。

greedy search每一步都都采用最大概率的词,而beam search每一步都保留k个最有可能的结果,在每一步,基于之前的k个可能最优结果,继续搜索下一步。(参考下面示意图理解)

示例图(设置返回解码结果为2个):

from math import log
from numpy import array
from numpy import argmax # beam search
def beam_search_decoder(data, k):
sequences = [[list(), 1.0]]
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)
# print result
for seq in result:
print(seq)

相关资料:

实现nlp文本生成中的beam search解码器的更多相关文章

  1. 斯坦福NLP课程 | 第15讲 - NLP文本生成任务

    作者:韩信子@ShowMeAI,路遥@ShowMeAI,奇异果@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/36 本文地址:http://www. ...

  2. Beam Search

    Q: 什么是Beam Search? 它在NLP中的什么场景里会⽤到? 传统的广度优先策略能够找到最优的路径,但是在搜索空间非常大的情况下,内存占用是指数级增长,很容易造成内存溢出,因此提出了beam ...

  3. 【NLP】选择目标序列:贪心搜索和Beam search

    构建seq2seq模型,并训练完成后,我们只要将源句子输入进训练好的模型,执行一次前向传播就能得到目标句子,但是值得注意的是: seq2seq模型的decoder部分实际上相当于一个语言模型,相比于R ...

  4. NLP相关问题中文本数据特征表达初探

    1. NLP问题简介 0x1:NLP问题都包括哪些内涵 人们对真实世界的感知被成为感知世界,而人们用语言表达出自己的感知视为文本数据.那么反过来,NLP,或者更精确地表达为文本挖掘,则是从文本数据出发 ...

  5. 关于 Image Caption 中测试时用到的 beam search算法

    关于beam search 之前组会中没讲清楚的 beam search,这里给一个案例来说明这种搜索算法. 在 Image Caption的测试阶段,为了得到输出的语句,一般会选用两种搜索方式,一种 ...

  6. 浅谈NLP 文本分类/情感分析 任务中的文本预处理工作

    目录 浅谈NLP 文本分类/情感分析 任务中的文本预处理工作 前言 NLP相关的文本预处理 浅谈NLP 文本分类/情感分析 任务中的文本预处理工作 前言 之所以心血来潮想写这篇博客,是因为最近在关注N ...

  7. Beam Search快速理解及代码解析(上)

    Beam Search 简单介绍一下在文本生成任务中常用的解码策略Beam Search(集束搜索). 生成式任务相比普通的分类.tagging等NLP任务会复杂不少.在生成的时候,模型的输出是一个时 ...

  8. Beam Search快速理解及代码解析

    目录 Beam Search快速理解及代码解析(上) Beam Search 贪心搜索 Beam Search Beam Search代码解析 准备初始输入 序列扩展 准备输出 总结 Beam Sea ...

  9. 使用 paddle来进行文本生成

    paddle 简单介绍 paddle 是百度在2016年9月份开源的深度学习框架. 就我最近体验的感受来说的它具有几大优点: 1. 本身内嵌了许多和实际业务非常贴近的模型比如个性化推荐,情感分析,词向 ...

随机推荐

  1. JavaScript中的arguments详解

    1. arguments arguments不是真正的数组,它是一个实参对象,每个实参对象都包含以数字为索引的一组元素以及length属性. (function () { console.log(ar ...

  2. PHP数组的遍历

    对于012345...这样的数组可以用for进行遍历 $arr=array('a','b','c','d','e'); for($key=0;$key<count($arr);$key++){ ...

  3. 线程中wait/notify/notifyAll的用法

    前言 多线程时,最关注的就是线程同步,线程间的同步一般用锁来实现,常见的锁就是synchronized和lock.用了synchronized,就不得不提到wait/notify/notifyAll. ...

  4. 关于NaN

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 网上整理的jQuery插件开发教程

    jQuery插件的开发包括两种:一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法.jQuery的全局函数就是属于jQuery命名空间的函数,另一种是对象级别 ...

  6. sklearn_k邻近分类

    # K邻近分类#--------------------------------# coding:utf-8 import pandas as pd from sklearn.neighbors im ...

  7. 支付宝hr终面,忐忑的等待结果

    上周一,内推网投了支付宝上海的 高级java软件开发工程师:阿里效率就是高,不到30分钟电话就过来了!约的上周五14:00面试:上周五技术面了2轮,第一轮是主管面试,貌似给了p6;第二轮部门总监面试, ...

  8. 跨站请求伪造(CSRF)攻击原理解析:比你所想的更危险

    跨站请求伪造(CSRF)攻击原理解析:比你所想的更危险 跨站请求伪造(Cross-Site Request Forgery)或许是最令人难以理解的一种攻击方式了,但也正因如此,它的危险性也被人们所低估 ...

  9. linux nginx大量TIME_WAIT的解决办法--转

    netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' TIME_WAIT 8535 CLOSE_WAIT 5 FIN ...

  10. Linux信息搜集

    ## 1.取证工具 - LiME 内存获取工具 - volatility 内存分析工具 ## 2.机器信息收集 #sysinfo 16 # # 查看当前登录用户 who > who.txt # ...