4.3 其他解码问题和解码技巧
贪心解码和束解码只是最基础的解码方法,其解码结果会出现许多问题。这里主要介绍3种常见问题,并简单介绍解决方案。
4.3.1 重复性问题
有时我们会发现序列到序列模型不断重复的输出同一个词。一个解决方案是解码时在所预测的词的概率分布上添加一个惩罚项,以减少已生成的词的概率。类似的惩罚项也可以添加到训练损失函数中, 即每个时刻的损失函数J₁修改为
另一个解决方案是修改注意力机制。如果当前的注意力分布与之前步骤的注意力分布相近,即关注相同的词, 那么模型往往会生成相同的词。因此可以通过避免注意力集中在相同的词上来减少重复。
4.3.2 多样性问题
在诸如对话这样的任务中,我们往往不希望模型总是刻板地回复同样的句子, 而是希望模型的回复有足够的多样性。但是如果使用贪心解码,对于类似的源序列, 往往最好的目标序列的确是一样的(如“我不知道”“很好”等)。一个解决方案是不再寻求概率最高的目标序列,转而在每一步从所预测的词的概率分布中进行采样。这样一来,即使是完全相同的源序列,也很可能会输出不同的目标序列。
4.3.3 防止“幻觉”
在翻译、文本总结等任务中,模型有时会出现幻觉( hallucination), 也就是说输出的目标文本里包含源文本里没有的元素。产生这个问题有许多原因和对应的解决方案。例如,如果模型的训练文本主要来自新闻领域,那么对于来自美食评论领域的源文本, 模型输出的目标文本很有可能还是带有许多和新闻相关的文字。对于上述问题,增加模型训练文本的领域数量是个比较直接有效的解决方案。当然,“幻觉”的产生还有很多更为复杂和微妙的原因,需要根据具体情况分析和解决, 这里不做更多讨论。
5. 指针网络
在有些场景下, 我们希望模型能将部分源序列中的元素直接复制到目标序列中,例如在机器翻译中,命名实体、数值、日期等短语往往不需要进行翻译, 而是可以直接复制,以如下源句和目标句为例。
源句: John and Mary spent 7 dollar on fried chicken。
目标句: John 和 Mary花了7美元买炸鸡。
源句中的命名实体“ John”和“ Mary”以及数字“7”都直接复制到了目标句中。此外,我们可以回顾一下本章开头给出的基于序列到序列的命名实体识别的例子。
源句: 小红在上海旅游。
目标句:[小红]人名]在[上海|地名]旅游。
目标句中的大部分词都是复制于源句, 仅有一小部分是需要生成的分隔符和实体标签。
在前面所提出的序列到序列模型的基础上, 指针网络( pointer network) ,也称为拷贝机制,可以建模这种复制源句内容的行为。下图展示了指针网络的架构。在解码的每一步, 模型会计算一个生成和复制二选一的伯努利分布,其中:
生成——依照前面介绍的方法, 生成一个词的概率分布;
复制——预测一个源句中词的概率分布(可看作预测一个指向源句中词的“指针”),预测方法和计算注意力分布类似。
最终用于解码的词的概率分布是生成分布和复制分布的加权和, 权重便是伯努利分布的概率。
6. 序列到序列任务的延伸
自然语言处理领域存在不少与序列到序列相近的任务,而前文介绍的序列到序列模型和方法也可以修改和扩展以适用于这些任务。
在一些任务中,输入数据是非序列的其他形式和模态, 而输出数据依然是序列,例如图像文字说明( image captioning) 的输入是单张图像, 视觉/视频问答( visual/ video question answering) 的输入是单张图像或单个视频以及一个问题文本, 结构化数据转文字( structured data to text) 的输入数据是结构化数据(如表格), 语音-文本转换( speech to text) 的输入是一段语音。对于这些任务,需要使用专门针对输入数据形式和模态的编码器,例如图像输入可以使用卷积神经网络或视觉 Transformer编码器,而解码器与序列到序列模型的解码器类似,通过自回归的方式生成文本。此外, 前面介绍的语言模型也可以看成一个无输入的序列到序列问题。
在另一些任务中,输入数据是序列,而输出数据是非序列的其他形式和模态, 例如在序列到集合任务中,输出是一个集合,输出元素之间不存在顺序关系。很多自然语言处理任务可以看作序列到集合任务,例如命名实体识别可以看作预测输入句子所包含的实体集合。序列到集合任务可以使用序列到序列模型求解,即假设输出元素之间存在某种顺序,也可以使用前面描述的使用非自回归解码的 Transformer模型,但其中不使用位置编码, 从而保证预测元素之间不存在顺序。