李宏毅DLHLP.20.Non-Autoregressive Generation

文章目录

  • 介绍
  • 难点
    • 图片
    • 文字
    • 小结
  • Vanilla NAT (Non-Autoregressive Translation)
    • Fertility
    • Sequence-level knowledge distillation
    • Noisy Parallel Decoding (NPD)
  • Evolution of NAT
    • NAT with Iterative Refinement
    • Mask-Predict
    • Insertion Transformer
    • KERMIT
    • Levenshtein Transformer
    • CTC
    • Imputer
    • Knowledge Distillation in NAT

介绍

本门课程是2020年李宏毅老师新课:Deep Learning for Human Language Processing(深度学习与人类语言处理)
课程网站
B站视频
公式输入请参考:在线Latex公式
这节课是莊永松主讲,关于Non-Autoregressive这个在BERT and its family.2/2中有提到过这个名词,与之对应的是Autoregressive。所谓的Autoregressive Sequence Generation就是从左到右的一个个的生成token。Non-Autoregressive Sequence Generation则是同时生成,下面来看一下典型的Autoregressive Sequence Generation模型(inference stage):
RNN,逐个的吃token,然后生成token的时候是生成下一个token的时候要参考当前时间步的token,因此,无论是输入和输出都比较花费时间。
李宏毅DLHLP.20.Non-Autoregressive Generation_第1张图片
后来有了BERT,这个时候就可以用BERT替换输入模块,这个时候可以直接一次把所有的输入都吃进来,不用一个个的吃,输入的速度是解决了,但是输出还是和RNN一样,一个个的往外吐:
李宏毅DLHLP.20.Non-Autoregressive Generation_第2张图片
因此,就想能不能把输出也改成直接吐所有的token的模式,这个就是Non-autoregressive model的目标:
李宏毅DLHLP.20.Non-Autoregressive Generation_第3张图片

难点

图片

要实现上面提出的目标,有难度,借用之前ML课程中讲过的一个例子来说:
有一个Text-to-lmage的任务,就是给一段文字,然后模型为文字配一个图片,传统使用有监督的方式进行训练,例如下图中给出的文字是奔跑的狗子,那么模型生成的图片要和ground truth要越接近越好
李宏毅DLHLP.20.Non-Autoregressive Generation_第4张图片
假如我们给出的文字是【train】,然后由于数据库中的ground truth有很多火车的图片,那模型就犯傻了,要想和所有有火车的图片都as close as possible怎么办?只能把所有火车图片都拿过来求平均,然后计算一个相似的结果:
李宏毅DLHLP.20.Non-Autoregressive Generation_第5张图片
最后的的结果就是模糊不清的,模型又想像这张图片,又想像那张图片。
李宏毅DLHLP.20.Non-Autoregressive Generation_第6张图片
究其原因就是在模型的输出层上,各个神经元之间没有相互联系(No dependency on output structure),例如下图的第二神经元在输出ink的时候,它并不知道邻居神经元产生什么东西
李宏毅DLHLP.20.Non-Autoregressive Generation_第7张图片
解决这个问题可以用Autoregressive model,ex: PixelRNN;另外还可以用GAN,使用GAN的discriminator来判别生成的图片是否真实,使得Generator学会生成清晰,真实的图片。
另外一个原因就是没有隐变量来控制生成结果的,例如上面已经知道,ground truth有70%几率来做白灯火车,30%几率来自黑灯火车,但是在生成结果的时候输出层并没有根据这个比例来进行生成数据。
对于整个问题,Autoregressive model也是有解决方法的,因为每个时间步中,Autoregressive model都是pick当前时间步输出分布中几率最大那个;李宏毅DLHLP.20.Non-Autoregressive Generation_第8张图片
而GAN也在输入的时候要吃一个正态分布,就是要使得输出有一个确定的方向。
李宏毅DLHLP.20.Non-Autoregressive Generation_第9张图片

文字

了解了图片的例子,再来看文字的是什么情况,假如我们使用Non-Autoregressive Sequence Generation的方式来进行translation。输入是【Hello!】,输出可以看到有好几种合理的翻译。
李宏毅DLHLP.20.Non-Autoregressive Generation_第10张图片
我们假定在groud truth中的几率分布如下:
李宏毅DLHLP.20.Non-Autoregressive Generation_第11张图片
那么对应的输出的分布就如下图所示:
李宏毅DLHLP.20.Non-Autoregressive Generation_第12张图片
可以看到输出第一个token中【哈】【你】几率都相等,都为50%,第二个token同理。那么在输出整个sequence的时候就有可能是:
李宏毅DLHLP.20.Non-Autoregressive Generation_第13张图片
明显这两个都是错误的翻译,但是都是有可能被模型sample出来的结果。
我们将这个问题称为:multi-modality problem,同一个输入,可能对应多个输出,那么Non-Autoregressive模型就会把各种可能的输出进行叠加,导致错误。

小结

generate target /methods Image Text
naive approach Deconvolution layer + L2 loss,求均值,效果差 non-autoregressive decoder,multi-modality problem本文重点要解决的问题
autoregressive PixelRNN, VQVAE-2,效果好 autoregressive decoder,成熟,缺点是一个个输出效率低
Generative Adversarial Networks/ non-auto model 效果好 文字应用还不成熟,待研究

Vanilla NAT (Non-Autoregressive Translation)

这个是第一篇用在翻译上的论文这个文章提出了几个trick,来改进Non-Autoregressive模型,第一个就是:

Fertility

·Predict fertility as latent variable & Copy input words.
·Represents sentence-level “plan” before writing Y.
这个trick就是在encoder部分加入输入单词对应的翻译结果的长度,例如,下图中的2121表示【Hello】翻译后对应2个token,【,】对应一个token,以此类推:
李宏毅DLHLP.20.Non-Autoregressive Generation_第14张图片
这个做法可以使得在句子层面对翻译这个任务进行提前布局,例如:
2121和1121分别对应的结果是:
李宏毅DLHLP.20.Non-Autoregressive Generation_第15张图片
李宏毅DLHLP.20.Non-Autoregressive Generation_第16张图片
这个Fertility的训练有两种方法:
1.Labels comes from external aligner.使用外部的aligner工具,这个工具会自动给出翻译结果对应原文的哪些字
李宏毅DLHLP.20.Non-Autoregressive Generation_第17张图片
2.Observing attention weights in auto-regressive models.直接训练一个seq2seq的auto-regressive model,然后看其attention权重如何分布,就可以看出输出结果对应输入的哪个字。这个方法用在翻译上比较多。
由于Fertility模型目标和NAT模型目标不一样的,因此,需要在NAT模型训练好之后,用REINFORCE的方式对fertility classifier进行Fine-tune。
第二个trick是:

Sequence-level knowledge distillation

knowledge distillation在之前的ML课程里面有讲,就是有一个比较小的模型(绿色),这个模型训练是以另外一个大的模型(蓝色)为老师,两个模型吃相同的输入,然后大的模型已经训练好了,这个时候有一个输出,小模型的目标是输出和大模型的输出交叉熵最小化。
李宏毅DLHLP.20.Non-Autoregressive Generation_第18张图片
对于翻译任务而言:
Teacher: Autoregressive model, Student: Non-autoregressive model
Construct new corpus by autoregressive teacher model
Teacher’s greedy decode output as student’s training target
如果用autoregressive 模型做老师,那么在输出的时候,如果第一个token选择【你】,那么autoregressive 模型就会给第二个token为【好】字几率变高,那么也就是说,整个模型的输出不在有两种可能,而是只有一种,【你好】
李宏毅DLHLP.20.Non-Autoregressive Generation_第19张图片
然后Non-autoregressive model在以autoregressive model的输出做为训练集的话,就不会存在多种正确答案的情况。
李宏毅DLHLP.20.Non-Autoregressive Generation_第20张图片
第三个trick:

Noisy Parallel Decoding (NPD)

1.Sample several fertility sequences
2.Generate sequences
3.Score by a autoregressive model
首先给出不同的fertility的组合,那么这些不同的组合会使得生成的结果也不一样,然后把生成出来的不同结果丢进Autoregressive Decoder中,让Autoregressive Decoder判断哪个结果最好:
李宏毅DLHLP.20.Non-Autoregressive Generation_第21张图片
这里注意,Autoregressive Decoder判断的过程不需要一个个的token进行,全部只需要一个时间步就可以搞定。
李宏毅DLHLP.20.Non-Autoregressive Generation_第22张图片
计算出每一个token对应的几率,然后把这些几率乘起来,就得到整句话的几率。

Evolution of NAT

  1. Vanilla NAT
    a. Gu et al., ICLR′18
    李宏毅DLHLP.20.Non-Autoregressive Generation_第23张图片

在原始的NAT的算法后,基本每年都有对其进行改进的方法:
2. Iterative Refinement
a. iNAT, Lee et al, EMNLP18
b. Mask-Predict, Ghazvininejad et al., EMNLP′19
这个算法的思想是在一次性输出某句话后,再把输入拿过来,重新迭代的对输出进行修正(下图中的红箭头),但是注意,这个方法在第一次的输出之后,对其进行修正时输出的长度是不变的,而是把对应的输入进行copy,例如下图中的你好对应两个hello。
李宏毅DLHLP.20.Non-Autoregressive Generation_第24张图片

  1. Insertion-based
    a. Insertion Transformer, Stern et al., ICML’19
    b. KERMIT, Chan et al, arXiv19
    李宏毅DLHLP.20.Non-Autoregressive Generation_第25张图片
    这个算法针对算法2中输出长度不能变化的缺点,设定了可以对输出进行插入的设定,使得输出的长度可以变化。例如一句话是[A,B,C,D,E,F,G],这里先生成子序列[D],再插入[D]周围词,以此类推。
    0→[D]→[B,D,F]→[A,B,C,D,E,F,G]
  2. Insert+Delete
    Levenshtein Transformer, Gu et al., NeurIPS’19
    算法3中只对输出进行插入,如果插入了错字就没有办法进行处理,因此这个算法加入了删除功能。
  3. CTC-based
    a. E2E NAT w/ CTC, Jindrich Libovick et al., EMNLP’20
    b. NAT w/ Latent Alignments, Saharia et al., arXiv’20

NAT with Iterative Refinement

这个迭代的思想就是吃一个句子X,一步一步的调节输出 Y L Y_L YL,直到最后得到结果Y:
在这里插入图片描述
具体模型结构如下图所示:
可以看到,第一个Encoder先预测target length,然后按照长度进行copy,经过第一个decoder_1,得到第一个输出 Y 0 Y_0 Y0,然后将 Y 0 Y_0 Y0作为输入,经过decoder_2得到第二个输出,不断重复好几次这个过程。
李宏毅DLHLP.20.Non-Autoregressive Generation_第26张图片
训练decoder_2可以将groud truth加入一些noise(将字进行重复,或者替换为随机字,或者交换顺序等),让decoder_2学习如何去噪。
Corruption Process(加入一些noise)
(1) replace y t + 1 y_{t+1} yt+1 with y t y_t yt
(2) replace y t y_t yt with a random token
(3) swap y t y_t yt and y t + 1 y_{t+1} yt+1.
这个算法效果提升不是很明显。

Mask-Predict

Conditional Masked Language Models (CMLM):这个算法是在BERT之后提出来的,借用了BERT中mask的思想,结构如下:
李宏毅DLHLP.20.Non-Autoregressive Generation_第27张图片
具体做法如下,在t=0时间步,先根据输入预测输出的长度,这里是6,那么就在Decoder(是BERT)中设置6个mask,然后BERT会得到第一版的翻译结果。
李宏毅DLHLP.20.Non-Autoregressive Generation_第28张图片
然后在t=1时间步,将第一版输出得到结果中几率比较低的字符替换为mask,再次丢入模型得到第二次输出。以此类推
李宏毅DLHLP.20.Non-Autoregressive Generation_第29张图片
每次mask的字符数量为n,计算方式如上图左下角的公式,随着时间慢慢减少。
Example: (target length is fixed)

李宏毅DLHLP.20.Non-Autoregressive Generation_第30张图片

Insertion Transformer

Partially Autoregressive Model,不是纯正的NAT,该模型会在每两个字之间做预测,是否需要插入新字。
李宏毅DLHLP.20.Non-Autoregressive Generation_第31张图片
具体做法如下,如图所示,假设的输入有6个,因此其输出(粉色)也是6个,然后将这六个输出vector两两进行concat操作(紫色)
李宏毅DLHLP.20.Non-Autoregressive Generation_第32张图片
然后把concat的结果用来预测插入词。如果不需要插入则获得【end】(end of slot),如果得到字,就把字插入到原句子中。
模型训练过程如下图所示,先将原句子打乱,然后随机给定一个数字,例如下图中是5,取前5个字,然后将前5个字还原回原句子的位置,其他去掉的字就形成了slots,然后就得到一个训练样本。
李宏毅DLHLP.20.Non-Autoregressive Generation_第33张图片
将这个训练样本丢到模型:这里两个字中间的slot对应多个字的,那么就是两个loss的allset?(这里没听清)
李宏毅DLHLP.20.Non-Autoregressive Generation_第34张图片
生成一个slot对应多个字符的情况有一个trick,这里不是为每个字符都给与相同的概率(下图中的红色),而是更加偏向生成中间的字符(下图中的蓝框),因为每次都生成中间的字符,这样整个生成过程就会按Binary tree那样效率高。
李宏毅DLHLP.20.Non-Autoregressive Generation_第35张图片
具体体现在公式中的红圈部分,中间的字权重比较大:
李宏毅DLHLP.20.Non-Autoregressive Generation_第36张图片
看一个具体例子:
Input: But on the other side of the state, that is not the impression many people have of their former governor.
Output: Aber auf der anderen Seite des Staates ist das nicht der Eindruck, den viele von ihrem ehemaligen Gouverneur haben.
用Binary tree loss(这里的计算是并行的)每次都最先Decoder的是中间的字。
在这里插入图片描述
Input: They want to create a post on the college’s equal opportunities committee to ensure that their opinions can be aired freely.
Output: Sie wollen einen Posten im Ausschuss fir Chancengleichheit des Kollegiums einrichten, um sicherzustellen, dass ihre Meinungen frei zur Sprache gebracht werden konnen.
使用uniform loss(这里的计算是并行的):
在这里插入图片描述

KERMIT

Kontextuell Encoder Representations Made by Insertion Transformations(第一个单词是上下文的德文)
李宏毅DLHLP.20.Non-Autoregressive Generation_第37张图片
这个算法对于 Insertion Transformer而言是将encoder和Decoder都合并在一起了:
李宏毅DLHLP.20.Non-Autoregressive Generation_第38张图片
这样做的好处:
做中翻英 P ( y ∣ x ) P(y|x) P(yx),就是放完整的英文,在中文那边做插入:
李宏毅DLHLP.20.Non-Autoregressive Generation_第39张图片
做英翻中 P ( x ∣ y ) P(x|y) P(xy),就是放完整的中文,在英文那边做插入:
李宏毅DLHLP.20.Non-Autoregressive Generation_第40张图片
中英文一起drop一些词,模型做预测 P ( x , y ) P(x,y) P(x,y)(求联合概率):
李宏毅DLHLP.20.Non-Autoregressive Generation_第41张图片
当然可以只做中文或者英文:
李宏毅DLHLP.20.Non-Autoregressive Generation_第42张图片
李宏毅DLHLP.20.Non-Autoregressive Generation_第43张图片
也就是一个模型可以同时做5个任务结果表明任务越多,效果越差,但是最后加上finetune可以超越单个任务。
李宏毅DLHLP.20.Non-Autoregressive Generation_第44张图片
这个模型在做问答完形填空任务比较强:Zero-shot ClozeQA
李宏毅DLHLP.20.Non-Autoregressive Generation_第45张图片
李宏毅DLHLP.20.Non-Autoregressive Generation_第46张图片
这个模型还有一个改进版本:Multilingual KERMIT,专门针对多语言进行处理。

Levenshtein Transformer

这个模型是在插入的基础上加入了删除功能,模型如下图所示:
李宏毅DLHLP.20.Non-Autoregressive Generation_第47张图片
可以看到输入经过encoder之后得到初始的输出要经过三个Decoder:
第一个Decoder是一个删除分类器,判断是否需要删除当前单词;
第二个Decoder是一个插入分类器,判断是否要在当前单词与单词之间插入单词,如果插入则生成一个占位符【PLH】place holder;
第三个Decoder是token分类器,根据【PLH】的位置预测对应的单词。
这个模型训练就是采用上面提到的从另外一个模型学习的方法(knowledge distillation)。具体算法称为:Levenshtein Distance Algorithm
例子:

>>> import Levenshtein
>>> Levenshtein.distance("ABCEFGHJJ", "ABCDEFGHI")
3
>>> Levenshtein.editops("ABCEFGHJJ", "ABCDEFGHI")
[('insert', 3, 3), ('delete', 7, 8), ('replace', 8, 8)]

这个文章的算法中把最后的replace分解为删除和插入操作。
训练过程如下:
先生成一系列需要删除单词的句子 y d e l y_{del} ydel,这个只要将正常句子中单词替换一些就可以;
再生成一系列需要插入单词的句子 y i n s y_{ins} yins,这个只要将正常句子中单词删除一些就可以。
有了上面的数据集后,就可以按下面的模型进行训练:
李宏毅DLHLP.20.Non-Autoregressive Generation_第48张图片
例如第一个句子输入模型,根据Levenshtein Distance Algorithm看的正确答案,第三个单词要删除,其他单词保持不变;第二个句子输入模型,根据Levenshtein Distance Algorithm看的正确答案,要在第二空位插入2个单词(第一个空位是和This这两个单词中间);最后一个句子就不用说了。
下面是两个例子:
针对a)这个例子,可以看到第一个iteration中刚开始啥都没有,所以不需要进行delete操作,然后插入一堆,然后在第二个iteration进行删除和插入,直到没有东西可以插入和删除结束。
李宏毅DLHLP.20.Non-Autoregressive Generation_第49张图片
下面是算法的结果比较:
李宏毅DLHLP.20.Non-Autoregressive Generation_第50张图片
当采用transformer作为teacher效果最好,然后在速度上比原来的Autoregressive Generation要明显快很多。

CTC

这个模型之前有讲过,这里只是拿过来比较一下,因为:
1.CTC也是Non-Autoregressive模型,只不过用在语音识别上;
2.语音识别没有multi-modality问题,就是一段语音对应多个结果。(特殊情况当然也有,不过加入LM可以解决,例如有人说:城市/程式还不错!)
李宏毅DLHLP.20.Non-Autoregressive Generation_第51张图片
但是这个模型有两个缺点:
1.虽然效果还不错,但是比不过seq2seq模型LAS;
2.语音经过Encoder之后得到的文字数据,不能再次经过refine操作进行修改,只能Encoder一次。例如下面红色明显是输出错误了,但是模型也无力回天。
李宏毅DLHLP.20.Non-Autoregressive Generation_第52张图片

Imputer

为了解决CTC的缺点,2020年研究人员提出了一个叫Imputer 的模型,这个模型结合了:CTC+Mask-Predict几种技术。
这个模型在t=0时刻会将一个与语音信号等长的Mask序列与语音信号丢入encoder中,得到一个初始化的输出,这个输出中可以还有Mask和确定结果(文字或者下划线)。
李宏毅DLHLP.20.Non-Autoregressive Generation_第53张图片
在t=1时刻,把上一个时间步得到序列结果在和语音信息重新进入Encoder,进行refine:
李宏毅DLHLP.20.Non-Autoregressive Generation_第54张图片
不断迭代直到输出没有变化为止。这个模型还有一个trick,叫:Block Decoding,将输入序列划分成一个个的block,并规定每个block在迭代过程,必须至少确定一个结果,下面是一个block size=3的例子:
李宏毅DLHLP.20.Non-Autoregressive Generation_第55张图片
可以看到,加入这个限制之后,迭代的次数最多为blocksize。
下面是一个blocksize=8的具体例子:
李宏毅DLHLP.20.Non-Autoregressive Generation_第56张图片
可以看到在第八个时间步结果已经出来了。
还有人把CTC和Inputer用在了翻译上,原理就是把语音信号替换为文字,然后把文字先做一个upsampling操作,然后其他操作一样。
CTC
李宏毅DLHLP.20.Non-Autoregressive Generation_第57张图片
Inputer
李宏毅DLHLP.20.Non-Autoregressive Generation_第58张图片

Knowledge Distillation in NAT

最后给出来NAT对Autoregressive模型进行Knowledge Distillation后效果提升的研究,语料中原文为英文,译文有de德文,es西班牙文,fr法文,然后Autoregressive模型翻译结果非常清楚,一句话翻译出来是三种目标文字中的一种,不会混乱(下图中第一个图每一个点代表一个句子。),但是NAT模型就不行,最后以Autoregressive模型为例进行学习后
NAT可以获得很好的效果。
李宏毅DLHLP.20.Non-Autoregressive Generation_第59张图片

你可能感兴趣的:(李宏毅.DLHLP2020)