【NLP笔记】文本生成基础与方案梳理

文本生成是NLP中较难的点,应用场景多且广泛。本篇笔记录一下文本生成的应用场景和主流方案,主要是基础的学习汇总和解决方案的梳理,相关学习资料在文中有链接或者文末有参考文献(我人工筛选的)都是相对经典的。

别问我是谁,请叫我雷锋 。ps. 如有疏漏错误请指正。

文本生成的应用领域

  • 信息抽取:生成式阅读理解
如一篇长篇新闻中根据抽取的事件,生成简短概述
  • 对话系统:闲聊回复|知识型问答回复
用户:我今天失恋了
chatbot: 抱抱,不哭
​
用户:章子怡现在的老公是谁呀?
chatbot: 汪峰现在和她和幸福呢!
  • 创作:写诗词,对联,新闻,小说 | 生成广告文案内容 | 生成吸睛营销标题 等
如《腾讯机器人日均写稿过千篇 你读的新闻可能是AI写的》


基础 && 方案

本文主要从规则和模型两个角度介绍方案,相关基础和资料穿插其中,感兴趣就接着往下看吧。

模板驱动(规则大法)

这种形式的NLG使用模板驱动模式来显示输出,如比赛得分,天气等场景常用,在现在客服系统对话中澄清需求、引导用户、询问、确认、对话结束语等大部分也是模板驱动。早先有很多研究复杂模板的方法,如根据语法树模板生成等,一般模板驱动包括下面几个步骤:



内容确定 :NLG 系统需要决定哪些信息应该包含在正在构建的文本中,哪些不应该包含。通常数据中包含的信息比最终传达的信息要多;

文本结构 :确定需要传达哪些信息后,NLG 系统需要合理的组织文本的顺序。例如在报道一场篮球比赛时,会优先表达「什么时间」「什么地点」「哪2支球队」,然后再表达「比赛的概况」,最后表达「比赛的结局」;

句子聚合 :不是每一条信息都需要一个独立的句子来表达,将多个信息合并到一个句子里表达可能会更加流畅,也更易于阅读;

语法化 :当每一句的内容确定下来后,就可以将这些信息组织成自然语言了。这个步骤会在各种信息之间加一些连接词,看起来更像是一个完整的句子;

参考表达式生成:这个步骤跟语法化很相似,都是选择一些单词和短语来构成一个完整的句子。不过他跟语法化的本质区别在于“REG需要识别出内容的领域,然后使用该领域(而不是其他领域)的词汇”;

语言实现 :最后,当所有相关的单词和短语都已经确定时,需要将它们组合起来形成一个结构良好的完整句子。

模型

文本生成模型方面都跑不脱vae和seq2seq两个思路,seq2seq相对主流,但vae近年来也一直有各种改造,如Nvdia今年出的NVAE,生成图像效果惊人,当然了这里只说NLP领域。

VAE的各种魔改

vae是隐变量自编码器,所谓自编码器系列是研究把数据压缩后,再尽量还原的模型。VAE在文本生成界应用已经开始有点边缘了,不过对于seq2seq的系列文本生成,似然求解偏置问题导致的生成文本单一问题,VAE有天然优势。VAE做文本生成最大的卖点是存在一个隐变量分布,在inference的时候会从分布中采样,而seq2seq在给定输入的时候输出是确定的,无法做到VAE的给定输入,输出仍然会不同的效果。

先了解一下几个概念:

KL散度

  • 考虑某个未知的分布 ​,用一个近似的分布 ​ 对它进行建模。如果我们使用 ​来建立一个编码体系,用来把 ​的值传给模型,那么由于我们使用了​而不是真实分布​,平均编码长度比用真实分布​进行编码增加的信息量(单位是 nat )为:
    • KL 散度看做两个分布​ 和 ​之间不相似程度的度量
    • KL散度也叫相对熵,看上面式子就是信息熵的相减
    • KL>=0, q(x) ​和​ p(x) 相等时和​相等时,等号成立
    • 最小化KL散度等价于最大化似然函数


VAE原理

笔者这里几句话简单描述一下VAE的原理:

  • vae是隐变量自编码器,自编码器系列是研究把数据压缩后,再尽量还原的模型
  • vae在自编码器的基础上,中间加了隐变量,即压缩成隐变量,然后由隐变量生成还原数据,且假设了隐变量的先验分布为标准高斯分布,隐变量的每一个样本后验分布都服从一个高斯分布 p_\theta(x)=\int_zp_\theta(x|z)p(z)dz
  • loss由两部分组成,由于隐变量的积分和后验分布无法求解,因此用另外一个分布来来逼近原来的隐变量的分布,作为原来loss的下界,这个下界叫做ELBO变分下界。
    • loss中用来描述模拟分布与原来隐变量分布的差异项为KL散度
    • loss中另外一项为拟合 p(x|z) ​的loss
  • 编码中,编码器学习隐变量后验分布的近似分布的均值和方差,得到了隐变量后验分布的近似分布的表达式,从而可以计算KL散度。本质上,VAE训练编码器是希望KL散度值达到最小,即令后验近似分布趋近于标准正态分布
  • 解码时基于经验知识使用了一次采样的近似操作,并依靠编码器学习隐变量下样本概率的参数,最后计算了条件概率下样本的似然。VAE希望loss最大,本质上是希望样本的重构误差最小

详细推导推荐大家可以看这篇,或者这篇, 讲的非常详细,足够大家入门。

VAE中KL散度消失问题

从上面原理得知vae loss由两部分组成,vae loss= reconstruction loss - KL loss, 那么最小化loss等价于最小化KL loss并最大化reconstruction loss:

  • 最小化KL: 如果简单的将 x认为和隐变量 z无关并让 q(z|x) = q(z) = p(z) ​,即后验分布退化为和先验分布一样的高斯,KL就可以取得最小值0
  • 最大化reconstruction: 当扮演 p(x|z) ​角色的decoder足够强大,仅凭自己就可以 q(x) ​分布,那么也没有必要去依赖z

在现有encoder-decoder基础上,很多时候decoder足够强大到直接从 p(x|z) ​生成文本,vae退化为无条件语言模型,虽然依然很强,KL散度为0说明编码器输出的是常数向量,而解码器则是一个普通的语言模型。而我们使用VAE通常来说是看中了它无监督构建编码向量的能力,这是vae的固病,有不少魔改vae就是致力于解决这个问题,acl2020有一篇直接加BN层的解法[1],常用几种解法如下:

  • 让KL loss变强
    • 如动态调整KL loss的系数[2]
    • Free Bits[3](KL大于一个阈值时采取调整)
    • Normalizing flow[4] 不断转换得到一个更好的分布
    • Auxiliary Autoencoder [5]多任务,将 VAE 和AE 两部分分开训练,加强编码器信息抽取部分


  • 让decoder 变弱
    • word drop-out[6] 在训练阶段,将decoder 的部分输入词替换为UNK,也就是说 RNN 无法仅依靠前面的生成的词来预测下一个词了,因此需要去多依赖 z
    • Dilated CNN decoder[7], 不用RNN解码而采用CNN,通过调整 CNN 的宽度,从最弱的 Bag-of-words model 到最强的LSTM ,Dilated CNN decoder 都可以无限逼近,做到控制解码的强度
    • Additional Loss[8],引入额外的 loss,例如让 z 额外去预测哪些单词会出现,因此也被称为 bag-of-words loss,他可以看做是增大了 reconstruction 的权重,让 model 更多去关注优化reconstruction 项而不是KL

CVAE

我们在自编码模型中引入隐变量的原因有两点:

  • 重构的恢复的过程是希望没噪声的,而KL loss则希望有高斯噪声的,两者是对立的,因此VAE跟GAN一样,内部其实是包含了一个对抗的过程,只不过它们两者是混合起来,共同进化的
  • 隐变量便于我们控制生成,如隐变量不同的采样有助于我们控制不同的生成内容

因此除了控制采样,可以加入一些其他条件,更进一步的控制生成,那这就是 CVAE (conditional vae ), 如下图,在普通的vae中我们是无监督的从​ p(x|z) 中生成,而在cave中则引入了标签作为条件从​中生成,当然了,condition 可以是多种多样的,这里举个了个是y的例子。

CAVE在非常适用一对多的问题,你可以通过控制条件来控制生成的多样性。如对话中

A:"你有什么兴趣爱好?"
B0:"我喜运动"
B1:"先告诉我你的"
B2:"hmm,我想想"
​

一些魔改方案

Vae-seq2seq[9]

在VAE中直接引入attention时,attention会绕过隐变量空间而使得隐变量无效(如下图中b,c), 因此作者提出了将attention也改造成 variational attention, 即也用隐变量来描述attention,并且应用在VED(variational encoder-decoder)框架中。


笔者在某厂的ppt中看到这种应用的效果不错


多级隐变量vae[10]

该篇主要针对长文本生成中语义不够连贯,和vae固有的KL散度易消失的问题,作者提出了一种多级隐变量的vae, 对于vae中经常解码器太强大而导致KL无效的原因,作者认为应该加强隐变量的学习而不是去减弱解码器的功能,同时作者认为多层特征抽取能捕捉到更细节的语义方便长文本的生成。如下图,作者在编码和解码部分设计了两级的编码-解码结构,作者任务高层的隐变量是来自于底层的推断而不是直接高斯分布,有一定的语义信息,可以看成是一种高斯混合分布,且高层的特征捕捉容易捕捉到长文本里的细节信息 。


phvm[11](Planning-based Hierarchical Variational Model)

这是一篇cvae应用的方案,应用在data to text 如,给出商品属性,生成描述文本,给出风格事件,生成小说等。条件是给定商品的data,即若干个<属性,值>,最后能生成广告文案,模型框架类似与去先想好要说什么重点内容,然后组织语言去说;

  1. 输入模块:从给定的属性值经过Bi-GRU编码后压缩成隐变量​,以及个属性编码后的特征
  2. 计划模块: 从隐变量和属性以及特征中解码出每句话要描述哪些属性
  3. 生成模块:生成模块与上篇论文类似采用多级解码结构


看起来生成效果不错


seq2seq各种魔改

seq2seq在文本生成应用中更加主流,因此各种应用场景和改造也比较多,当然也有其固有的问题, 针对具体场景和问题也有很多解决方案,下面简单介绍原理然后总结几种思路方案

seq2seq原理简述

  • 通过深度神经⽹网络将一个输入的序列列映射为一个作为输出的序列。这 个过程由encoderdecoder节组成。先将输⼊映射到一个序列,然后通过序列解码,解码的时候当前值依赖与隐藏节点和解码出来的上一个节点
  • Seq2Seq优点在于可以处理变长序列, 传统的seq2seq会将输⼊映射成⼀个中间固定序列,并且encoder隐藏节点对decoder贡献一致的问题,可以通过加attention来解决,在 encoder和decoder之间,生成输出词时,会考虑每一个输入词和当前输出词的对齐关系( 重要程度),引用知乎大佬的一张图如下:


seq2seq+attention存在的问题

受模型限制,文本生成质量会受到训练数据集质量和多样性的巨大影响。由于seq2seq的loss采用最大似然求解,必然容易导致偏置问题,生成的内容重复且单一, 如果想要模型生成出更多有趣多样的内容,就需要复杂的数据过滤,采样技术等;

seq2seq魔改方案

针对生成单一问题的一般解是:

  • 从数据角度入手,收集更多的高质量语料,或者做一些数据增强技术,如ACL2020一篇通过回译做增强等,可以参考之前写过的一篇笔记;
  • 给语料添加一些如结构化的情感,知识之类的表达,在任务型QA中常见,非常的费人工;
  • 在从模型的角度入手,改造seq2seq模型的学习目标促使他多样化表达,或在seq2seq解码时加一些特定调价增以便生成更多样的内容;
    • 修改loss:采用了最大互信息(MMI)[12]作为目标损失函数,MMI损失函数可以看成是在极大似然估计的基础上,添加了一项对输出句子概率的惩罚项, 把输出句子的频率考虑进loss中, 或者采用ITF-loss[13]等;
    • Seq2BF[14]: 先预测关键词,然后根据生成的关键词去补全整个句子;
    • 修改Beam Search算法,对每个时间步的条件概率施加多样性惩罚,比如MMI-antiLM、diverseRL[15]、DBS[16]等;

针对生成的流畅性,以及不同场景下的生成要求,介绍一些方案如下:

seq2seq copy机制[17]

copy机制最初是为了解决OOV问题,如当有一些专有名词不在你训练时的词表中时,那在生成时普通的seq2seq是无论如何也无法生成出该词,copyNet的encoder端与普通seq2seq一致,在decode端生成时,copy机制的原理是,让它以一定的概率为生成词,一定的概率为复制该词, 作者将encoder端生成的隐状态向量序列定义为copyNet的短期memory,用M表示, 在解码时M将被多次使用。

decode端的隐藏状态更新时,会拼接进 embeding(y_{t−1}) ​和​在输入序列中对应的隐状态向量(这也是copy的体现)

s_t=f([e(y_{t−1});ζ(y_{t−1})]^T,s_{t−1},c_t)

解码端更新当前时刻的隐状态时,每次动态地将encoder端生成的所有隐状态向量序列(M)表示成(attention机制加权求和,attentive read)该时刻对应的context向量外,还会检查解码器上一时刻的输出​ y_{t−1} 在输入序列X中的位置(同一个词可能会出现多次),然后在M中取出(selective read)相应位置对应的隐状态向量​ ζ(y_{t−1}) ,如果不在的话M中的话,对应隐状态为零向量。

p(y_t|s_t,y_{t−1},c_t,M)=p(y_t,g|s_t,y_{t−1},c_t,M)+p(y_t,c|s_t,y_{t−1},c_t,M)

M的两种读取方式(attentive read与selective read,本质上都是基于注意力进行相关运算的)使得copyNet可以在Generate-Mode与Copy-Mode间进行切换,甚至决定何时开始或者结束copy。Attentive Read就是在编码器端的attention mechanism,Selective Read就是​ ζ(y_{t−1}) 的计算过程。如果​在输入序列X中,那么copyNet接下去的输出就很可能偏向Copy-Mode。

这论文的图太迷惑了我就不放了。

seq2seq Pointer-generator network[18]

与copyNet类似,Pointer-generator network在解码端预测某个词w的概率时,也综合考虑从词表生成(词表分布PvocabPvocab)和从源输入复制(attention分布)两种情况。 不过其表现形式不同,具体如下:

P(w)=p_{gen}P_{vocab(w)}+(1−p_{gen})∑_{i:wi=w}a^t_i

即它直接用词每个词生成w的attention来代表了copy这个词的可能性。

在生成多句文本序列时,很容易出现内容重复现象,为了消除这种现象,作者提出了一种coverage机制,在每一时刻会维持一个coverage向量​,其是解码端在之前的各个时刻的attention分布之和,即

c_t=∑_{t′=0}^{t−1}a^t′

考虑Coverage机制后,在计算解码器端t−1时刻的隐状态向量​与编码器端第i个隐状态向量​的相关性得分(编码和解码之间的attention)时,需要同时考虑上述coverage向量。

e^t_i=v^Ttanh(W_hh_i+W_ss_{t-1}+w_cc_t^i+b_{attn})

其表示到目前t时刻为止,源文本输入序列在attention机制下覆盖密度的分布(未归一化)情况.

这保证了当前的相关性得分参考了之前的权重累积和,从而有效抑制重复内容的出现。同时作者们又定义了一个额外的coverage损失来进一步惩罚在copy时相同位置copy多次的情况。具体损失函数为covloss,并加入最终loss:

covloss_t=∑_imin(a_t^i,c_t^i)


loss_t=−logP(w_t)+λ∑_imin(a^t_i,c^t_i)

seq2seq 控制主题

这种有条件的生成特别像VAE中通过控制隐变量来控制生成,控制生成主题一般通过关键字来约束,两个思路

seq2BF[14]直接用关键词硬约束:

  • (a) 给定用户的query,利用PMI(Pointwise Mutual Information)预测一个keyword作为reply的topic;
  • (b) 将query输入encoder,尔后将上一步中预测的keyword作为decoder端的第一个词输入,然后依次预测得到一个序列backward sequence, 得到keyword和后面的句子;
  • (c) 将query输入encoder,然后将backward sequence进行reverse后,连同keyword一起依次输入decoder端,并开始预测得到剩下的序列forward sequence,得到keyword前面的部分。
  • 拼接行程reply


关键词融合在状态更新中的软约束[19]

  • 关键词不一定直接出现在生成的文本中,可能出现近义词喝着近似意思的表达
  • 设计cue word gru单元,将关键词信息,加入到每一步的状态更新
  • 利用设计的fusion unit结构融合普通gru与 cue word gru 单元


seq2seq属性控制生成

  • 先预测属性信息[20],然后直接当监督模型将属性信息融合进解码的过程中,每次解码由context信息与属性信息共同决定;


  • Seq 与vae 的结合控制属性[21],这与上文vae类似也是一种cvae, 解码步骤分别对功能相关的词(function-related),主题词,普通词分别建模,最终形成一个混合模型

Mem2Seq[22]

现在有不少用知识库来做任务增强的方案,本篇中作者利用MemNet从知识库中动态获得额外知识记录更新并利用了copy机制来决策是生成还是copy知识库中的内容;

Mem2Seq是第一个使用带有指针网络思想的多跳注意力机制的模型,这种方法有效的结合了KB的信息且Mem2Seq学习如何生成动态的查询来控制memory的访问。

前序知识需要了解MemNet大家可以参考这篇, copy和pointer Net前面介绍过。

上图中a部分是encoder的核心, C^K 表示第k跳记忆,query要经过K-hop的更新,类似从历史对话中找到这是真正的query是什么;

b部分描述解码,每一个时刻,将产生两个分布:词表分布 P_{vocab} 和记忆部分分布 P_{ptr} 。记忆部分分布是指对话历史以及KB的信息。 P T R=\left\{p t r_{1}, \ldots, p t r_{m}\right\} , 计算如下:

p t r_{i}=\left\{\begin{array}{ll}{\max (z)} & {\text { if } \exists z \text { s.t. } y_{i}=u_{z}} \\ {n+l+1} & {\text { otherwise }}\end{array}\right. \\

上式表明,当生成的词与记忆存储器中的词相等时,使用记忆存储器的词,即完成复制功能,当生成的词不在记忆存储器中时,ptr_i指向一个特殊字符,模型将使用词表分布P_{vocab}来生成输出。

总结

从发展来看大家越来越希望文本生成是可控的,而不是单纯的黑盒模型,同时希望生成的质量,多样性,长度上能有所突破,因此也是主要针对生成的多样性,语义连贯性和一致性,句式和情感表达控制这几个方向研究。

看都看完了,点个赞再走呀。

参考

  1. ^A Batch Normalized Inference Network Keeps the KL Vanishing Away
  2. ^Generating sentences from a continuous space
  3. ^mproving variationalinference with inverse autoregressive flow
  4. ^Variational lossy autoencoder
  5. ^Improving Variational Encoder-Decoders in Dialogue Generation
  6. ^Generating sentences from a continuous space
  7. ^Improved Variational Autoencoders for Text Modeling using Dilated Convolutions
  8. ^Learning discourse-level diversity for neural dialog models using conditional variational autoencoders
  9. ^Variational Attention for Sequence-to-Sequence Models
  10. ^Towards Generating Long and Coherent Text with Multi-Level Latent Variable Models
  11. ^Long and Diverse Text Generation with Planning-based Hierarchical Variational Model
  12. ^A Diversity-Promoting Objective Function for Neural Conversation Models
  13. ^Another Diversity-Promoting Objective Function for Neural Dialogue Generation
  14. ^abSequence to Backward and Forward Sequences: A Content-Introducing Approach to Generative Short-Text Conversation
  15. ^A Simple, Fast Diverse Decoding Algorithm for Neural Generation
  16. ^Diverse Beam Search: Decoding Diverse Solutions from Neural Sequence Models
  17. ^Incorporating Copying Mechanism in Sequence-to-Sequence Learning
  18. ^Get To The Point: Summarization with Pointer-Generator Networks
  19. ^Towards Implicit Content-Introducing for Generative Short-Text Conversation Systems
  20. ^Towards implicit content-introducing for generative short-text conversation systems
  21. ^Generating Informative Responses with Controlled Sentence Function
  22. ^Mem2Seq: Effectively Incorporating Knowledge Bases into End-to-End Task-Oriented Dialog Systems
编辑于 2020-07-28 17:49