通常,我们认为NLP = NLU + NLG,NLU-Neural Language Understanding指的自然语言理解,NLG-Neural Language Generation指的自然语言生成。两者是相辅相成的,只有做好NLU才能做好NLG,做好NLG就可以做很多有趣的落地。
NLG包括很多任务,典型的有:
- Machine Translation
- (Abstractive) Summarization
- Dialogue (chit-chat and task-based)
- Creative writing: storytelling, poetry-generation
- Freeform Question Answering (i.e. answer is generated, not extracted from text or knowledge base)
- Image captioning
本篇文章简单介绍一下Summaization和Dialogue基本情况,因为这两个任务最常见,也最实用。像写诗啊,写故事啊,这些task纯属瞎折腾....
NLG任务大部分都是seq2seq的( Image captioning除外),后BERT时代,有条件就上BERT,没条件创造条件也要上。这里附两篇微软用BERT做seq2seq的论文,两篇文章都很好理解,有兴趣自读。
- MASS: Masked Sequence to Sequence Pre-training for Language Generation
- Unified Language Model Pre-training for Natural Language Understanding and Generation(不同的行业,同一个“大一统理论”的梦想)
由于NLG在Decoder阶段都是要一个个“蹦词”的,所以文章最后会介绍一些常用的Decoding algorithms。
1.Summarization
技术上一般将Summarization分为抽取式(Extractive summarization)和生成式(Abstractive summarization)。抽取式摘要指的从一片文档中选择一些重要的句子,作为该文档的摘要,这种方法相对简单,但是不够灵活;生成式摘要指的是NLG的技术生成摘要,这种方法相对困难,需要先做NLU在做NLG,但是也更灵活、上限更高。生成式摘要才是NLG的task。
生成式摘要基本遵循Encoder-Decoder的框架,对文档encode成一个表示,然后使用decoder生成摘要。使用基于attention的Encoder和Decoder是目前的主流。这部分大家耳熟能详,不再赘述。
一个有用的技巧是copy mechanism。copy mechanism指的生成下一个单词的时候,是以p的概率copy source text的单词,(1-p)的概率从词表中生成,拷贝机制详细的参考pointer-generator network ,示意图如下:
拷贝机制带来的问题是:
- 不好控制拷贝内容的多少,经常过多拷贝内容,甚至成句的拷贝。这里的主要原因我觉得可能和数据标注规范有关,Summarization的标注本身没有规范,不同的人会给不同的摘要,但是很明显的是人们总结摘要的时候也经常使用source text中的单词,而很少用同义词替换,除非同义词替换可以带来很大的压缩效率。这就可能导致模型学习的时候过度依赖拷贝机制。
- 在文本很长时,需要做截断处理,导致拷贝的时候“短视“
Bottom-Up Abstractive Summarization给出两阶段任务,第一阶段先做序列标注,找出和Summarization相关单词;第二阶段,使用相关的词汇做Summarization,示意图:
还有一个方向是使用强化学习直接优化相关metrics,给篇代表性论文:A Deep Reinforced Model for Abstractive Summarization
总的来说,现在单纯的end2end的Summarization做的还不是很好,工业级落地场景中会加入很多规则与先验。
2.Dialogue
对话系统包含很多设定:
- 助手类型的,例如智能客服、语音助手等
- 对抗类型的,例如谈判机器人
- 闲聊类型的,闲聊机器人
开放式自由对话(open-ended freeform dialogue)机器人是一个很大的挑战,目前的系统一般存在如下问题:
- 不相关的回复
- 一般性/无意义的回复
- 重复的回复
- 缺乏上下文相关性(Lack of context)
- 缺乏统一的人格(Lack of consistent persona)
在各个方向都有各种方式的优化技巧。
在不相关回复方面可以优化最近的Input和Response的互信息(Maximum Mutual Information, MMI);
在一般性/无意义回复方面可以使用sampling decoding代替beam search
重复的回复可以在beam search的时候限制重复的n-gram,或者在损失函数上做一些考虑。
缺乏上下文上可以想办法将最近的context都喂进去。
总体来说,对话系统是一个很复杂的任务,存在的各种问题都没有彻底解决,工业应用的对话系统一般都会做很多corner case和兜底处理...
3.Decoding algorithms
“蹦词”的时候有一些小算法,我们称之为decoding algorithms. 基本有以下几种:
- greedy decoding
- beam search decoding
- Sampling-based decoding
- Softmax temperature
贪心策略很好理解,每次取logit最大的词就行了。优点就是简单,缺点就是除了简单以外,没有任何优点...
beam search是大家用的最多的,做法是始终保持K条最优序列(平均logits最小),并且在每一步每个序列都再计算最好的K个下一个单词,然后从K*K个结果中选择K个最好的。说的不太清楚,一图顶万言
beach search一个经常比较的对象是维特比算法,两者差别是beam search是局部最优,是工程上的一种trade off,维特比算法是全局最优,搜索树一旦很大(很宽/很深)就非常耗时。
beach search需要选择beam size,越小越接近greedy,beam size=1就等价于greedy. 越大beam size 计算代价就越大,并且有些试验告诉我们太大的beam size可能会有更差的效果。一般来说beam size=3是一个不错的trade off。
Sampling-based decoding和beam search类似,每个decoding step,首先算出最可能的一个token集合,然后以某种概率分布(通常是和神经网络最后的logit值正相关)从中采样n个候选答案。和beam search区别是用softmax代替argmax,通常用于开放式或者需要创造性的生成任务上,比如写故事/写诗之类。
Softmax temperature是在softmax层上加了一个超参数,可以用来平衡diverse的。具体做法是,一般softmax计算过程如下:
加入温度超参数计算过程如下:
tau 越大概率分布就越接近于uniform,概率值在整个词表上做了平滑,可以生成更加diverse的句子;tau 越小概率密度就越集中在某几个token上,可以生成具有更小diverse的句子。
值得一提的Softmax temperature是调节softmax的技巧,它不能单独使用,要配合greedy search或者beam search做decoding.