Transformer架构

Transformer 是一个基于自注意力的序列到序列模型,与基于循环神经网络的序列到序列模型不同,其可以能够并行计算。

序列到序列模型

序列到序列模型输入和输出都是一个序列,输入与输出序列长度之间的关系有两种情况。第一种情况下,输入跟输出的长度一样;第二种情况下,机器决定输出的长度。

image.png|525

  • 语音识别:输入是声音信号,输出是语音识别的结果,即输入的这段声音信号所对应的文字。我们用圆圈来代表文字,比如每个圆圈代表中文里面的一个方块字。输入跟输出的长度有一些关系,但没有绝对的关系,输入的声音信号的长度是 T,并无法根据 T 得到输出的长度 N。其实可以由机器自己决定输出的长度,由机器去听这段声音信号的内容,决定输出的语音识别结果。
  • 机器翻译:机器输入一个语言的句子,输出另外一个语言的句子。输入句子的长度是N,输出句子的长度是 N′。输入“机器学习”四个字,输出是两个英语的词汇:“machine learning”,N 跟 N′之间的关系由机器决定。
  • 语音翻译:我们对机器说一句话,比如“machine learning”,机器直接把听到的英语的声音信号翻译成中文

[!question] Q: 既然把语音识别系统跟机器翻译系统接起来就能达到语音翻译的效果,那么为什么要做语音翻译?
世界上很多语言是没有文字的,无法做语音识别。因此需要对这些语言做语音翻译,直接把它翻译成文字。

语音合成

输入文字,输出声音信号

以闽南语的语音合成为例,其使用的模型还是分成两阶,首先模型会先把白话文的文字转成闽南语的拼音,再把闽南语的拼音转成声音信号。

聊天机器人

image.png|600

问答任务

很多自然语言处理的任务都可以想成是问答(Question Answering,QA)的任务

  • 翻译。机器读的文章是一个英语句子,问题是这个句子的德文翻译是什么?输出的答案就是德文。
  • 自动做摘要:给机器读一篇长的文章,让它把长的文章的重点找出来,即给机器一段文字,问题是这段文字的摘要是什么。
  • 情感分析:机器要自动判断一个句子是正面的还是负面的。如果把情感分析看成是问答的问题,问题是给定句子是正面还是负面的,希望机器给出答案

因此各式各样的自然语言处理的问题往往都可以看作是问答的问题,而问答的问题可以用序列到序列模型来解。序列到序列模型的输入是一篇文章和一个问题,输出就是问题的答案。问题加文章合起来是一段很长的文字,答案是一段文字。只要是输入一个序列,输出是一个序列,序列到序列模型就可以解

句法分析

很多问题都可以用序列到序列模型来解,以句法分析(syntactic parsing)为例,如图所示,给机器一段文字:比如“deep learning is very powerful”,机器要产生一个句法的分析树,即句法树(syntactic tree)。

image.png|500

在句法分析的任务中,输入是一段文字,输出是一个树状的结构,而一个树状的结构可以看成一个序列,该序列代表了这个树的结构

image.png|325

多标签分类

多标签分类(multi-label classification)任务也可以用序列到序列模型。多类的分类跟多标签的分类是不一样的。多分类问题(multi-class classification)是指分类的类别数大于 2。而多标签分类是指同一个东西可以属于多个类。

多标签分类问题不能直接把它当作一个多分类问题的问题来解。比如把这些文章丢到一个分类器里面,本来分类器只会输出分数最高的答案,如果直接取一个阈值(threshold),只输出分数最高的前三名。这种方法是不可行的,因为每篇文章对应的类别的数量根本不一样。因此需要用序列到序列模型来做

image.png|500

Transformer结构

一般的序列到序列模型会分成编码器和解码器,如图所示。编码器负责处理输入的序列,再把处理好的结果“丢”给解码器,由解码器决定要输出的序列。

image.png|350

Transformer编码器

编码器输入一排向量,输出另外一排向量
Transformer的编码器使用的是自注意力,输入一排向量,输出另外一个同样长度的向量。

image.png|250

image.png|500

编码器里面会分成很多的块(block),每一个块都是输入一排向量,输出一排向量。输入一排向量到第一个块,第一个块输出另外一排向量,以此类推,最后一个块会输出最终的向量序列。

编码器的每个块并不是神经网络的一层,每个块的结构如图所示,在每个块里面,输入一排向量后做自注意力,考虑整个序列的信息,输出另外一排向量。接下来这排向量会“丢”到全连接网络网络里面,输出另外一排向量,这一排向量就是块的输出

image.png|400

Transformer 的编码器的每个块并不是神经网络的一层,每个块的结构如图 7.11 所示,在每个块里面,输入一排向量后做自注意力,考虑整个序列的信息,输出另外一排向量。接下来这排向量会“丢”到全连接网络网络里面,输出另外一排向量,这一排向量就是块的输出

Transformer 里面加入了残差连接(residual connection)的设计,如图所示,最左边的向量 b 输入到自注意力层后得到向量 a,输出向量 a 加上其输入向量 b 得到新的输出。得到残差的结果以后,再做层归一化(layer normalization)。归一化后再输入全连接网络,残差连接后再得到新的输出。最后再进行一次层归一化,得到编码块里面一个块的输出。

image.png|300

[!info] 层归一化和批量归一化

  • 层归一化不需要考虑批量的信息,输入一个向量,输出一个向量
    • 它是对同一个特征、同一个样本里面的不同维度计算均值和标准差,接着做归一化
    • $x_{i}’=\frac{x_{i}-m}{\sigma}$
    • 就是对一个句子进行归一化
  • 批量标准化是对不同样本、不同特征同一个维度计算均值和标准差
    • 就是对一个batch句子的同一个位置做归一化

下图给出了 Transformer 的编码器结构,其中 N× 表示重复 N 次。首先,在输入的地方需要加上位置编码。如果只用自注意力,没有位置的信息,所以需要加上位置信息。多头自注意力就是自注意力的块。经过自注意力后,还要加上残差连接和层归一化。接下来还要经过全连接的前馈神经网络(这一块的目的是为了提高模型的非线性,通常维度为隐藏层维度的4倍),接着再做一次残差连接和层归一化,这才是一个块的输出,这个块会重复 N 次。

[!question] 为什么有位置编码?
Transformer不采用RNN的结构,而是使用全局信息,不能利用单词的顺序信息,而这部分信息对于NLP来说非常重要。所以 Transformer 中使用位置 Embedding 保存单词在序列中的相对或绝对位置。
计算方式:
$$
PE_{(pos,2i)}=\sin\left( \frac{pos}{10000^{2i/d}} \right)
$$

$$
PE_{(pos,2i+1)}=\cos\left( \frac{pos}{10000^{2i/d}} \right)
$$

这样计算的好处是不需要训练,只需要计算,而且容易计算相对位置,对于固定长度的间距k,PE(pos + k)可以通过正余弦展开计算

image.png|525

image.png|300

解码器

以语音识别为例,输入一段声音,输出一串文字。

要让解码器产生输出,首先要先给它一个代表开始的特殊符号 <BOS>,即 Begin Of Sequence,这是一个特殊的词元(token)。

在词表(vocabulary)里面,在本来解码器可能产生的文字里面多加一个特殊的符号<BOS>。在机器学习里面,假设要处理自然语言处理的问题,每一个词元都可以用一个独热的向量来表示。独热向量其中一维是 1,其他都是 0,所以 <BOS> 也是用独热向量来表示,其中一维是 1,其他是 0。

接下来解码器会“吐”出一个向量,该向量的长度跟词表的大小是一样的(eg.中文里常用汉字的数量)。在产生这个向量之前,跟做分类一样,通常会先进行一个 softmax 操作。这个向量里面的分数是一个分布,该向量里面的值全部加起来,总和是 1。这个向量会给每一个中文字一个分,分数最高的中文字就是最终的输出。“机”的分数最高,所以“机”就当做是解码器的第一个输出。

image.png|500

接下来把“机”当成解码器新的输入。根据两个输入:特殊符号 <BOS>和“机”,解码器输出一个向量,向量里面会给出每一个中文字的分数。因此,每次解码器的输入是其前一个时间点的输出,反复输入进行迭代。

但是也可能会输入错误,使得一步错步步错的误差传播问题

image.png|475

会发现除了中间多了多头自注意力和残差连接部分,其余部分实际上encoder和decoder是一样的,解码器最后会执行一个softmax,以使得其输出变为概率

此外还有个掩码多头自注意力,原来的自注意力输入一排向量,输出另外一排向量,这一排中每个向量都要看过完整的输入以后才做决定。掩蔽自注意力的不
同点是不能再看右边的部分,如图 7.19 所示,产生 $b^1$ 的时候,只能考虑 $a^1$ 的信息,不能再考虑 $a^2、a^3、a^4$。

是因为防止后面的信息对前面产生影响,decoder的输出是先有$a^1$才有$a^2$,再有后面的$a^3$和$a^4$。所以实际上有$a^2$想要计算$b^2$的时候,$a^3$和$a^4$是没有的,所以无法考虑。解码器的输出是一个一个产生的,所以只能考虑其左边的东西,没有办法考虑其右边的东西

image.png|500

[!question] 实际应用中输入跟输出长度的关系是非常复杂的,我们无法从输入序列的长度知道输出序列的长度,因此解码器必须决定输出的序列的长度

要让解码器停止运作,需要特别准备一个特别的符号 **<EOS>**。产生完“习”以后,再把“习”当作解码器的输入以后,解码器就要能够输出 <EOS>,解码器看到编码器输出的嵌入、<BOS>、“机”、“器”、“学”、“习”以后,其产生出来的向量里面 <EOS> 的概率必须是最大的,于是输出 <EOS>

image.png|600

Q、K、V模式:
image.png|525

非自回归解码器

自回归的模型是先输入 <BOS>,输出 $w_1$,再把 $w_1$ 当做输入,再输出 $w_2$,直到输出 <EOS> 为止。
假设产生是中文的句子,非自回归不是一次产生一个字,它是一次把整个句子都产生出来。
非自回归的解码器可能“吃”的是一整排的 <BOS> 词元,一次产生产生一排词元。
比如输入 4 个 <BOS>的词元到非自回归的解码器,它就产生 4 个中文的字。因为输出的长度是未知的,所以当做非自回归解码器输入的 <BOS> 的数量也是未知的,因此有如下两个做法:

  • 用分类器解决:分类器接收编码器输入,输出一个数字,数字代表解码器的输出长度。
  • 给编码器输入一组<BOS>词元,规定词元数量。

优点:

  • 平行化,计算迅速
  • 能够控制输出长度 eg.语音合成领域可以通过调整长度控制输出速度

编码器-解码器注意力

image.png|500

image.png|450

编码器输入一排向量,输出一排向量 $a^1,a^2,a^3$ ,解码器先读入<BOS>,经过 mask attention 得到一个向量,然后将这个向量乘上一个矩阵,得到查询$q$,$a^1,a^2,a^3$也都产生键 $k^1,k^2,k^3$ 。把 $q$ 和 $k^1,k^2,k^3$ 计算注意力分数,得到 $\alpha_{1}, \alpha_{2},\alpha_{3}$,做softmax得到 $\alpha_{1}’,\alpha_{2}’,\alpha_{3}’$。于是可以计算 $v$ :

$$
v=\alpha_{1}’ \times v^1 + \alpha_{2}’ \times v^2 + \alpha_{3}’ \times v^3
$$

$v$ 接下来会“丢”给全连接网络,这个步骤 $q$ 来自于解码器,$k$ 跟 $v$ 来自于编码器,该步骤就叫做编码器-解码器注意力,所以解码器就是凭借着产生一个 $q$,去编码器这边抽取信息出来,当做接下来的解码器的全连接网络的输入。

训练过程

image.png|450

计算标准答案(ground truth)与分布之间的交叉熵,希望该交叉熵的值越低越好
每一次解码器在产生一个中文字的时候做了一次类似分类的问题。假设中文字有四千个,就是做有四千个类别的分类的问题。

如图所示,实际训练的时候,输出应该是“机器学习”。解码器第一次的输出、第二次的输出、第三次的输出、第四次输出应该分别就是“机”、“器”、“学”、“习”这四个中文字的独热向量,输出跟这四个字的独热向量越接近越好。

在训练的时候,每一个输出跟其对应的正确答案都有一个交叉熵。图中做了四次分类问题,希望这些分类的问题交叉熵总和越小越好。

注意解码器最后还需要输出一个<EOS>

教师强制:解码器训练时,在输入的时候给它正确的答案

训练技巧

复制机制(copy mechanism)

对于很多任务,解码器没有必要自己创造输出,可以从输入的东西里复制一些东西

对话服务:从使用者的词汇中复制一些内容
摘要任务:从文章里直接复制一些信息

Pointer Network 和 Copy Network

引导注意力

有时候训练结果会有异常

强迫attention的样貌,例如强制学习注意力要从左到右
image.png

束搜索

假设解码器就只能产生两个字 A 和 B,假如世界上只有两个字 A 跟 B,即词表 $V = {A, B}$。对解码器而言,每一次在第一个时间步(time step),它在 A、B 里面决定一个。比如解码器可能选 B 当作输入,再从 A、B 中选一个。在上文中,每一次解码器都是选分数最高的那一个。假设 A 的分数是 $0.6$,B 的分数是 $0.4$,解码器的第一次就会输出 A。接下来假设 B 的分数为 $0.6$,A 的分数为 $0.4$,解码器就会输出 B。

以此类推,每次找分数最高的词元作为输出的方法称为贪心搜索(greedy search),其也被称为贪心解码

但贪心不一定最优。第一步可以先稍微舍弃一点东西,第一步虽然 B 是 0.4,但先选 B。选了 B,第二步时 B 的可能性就大增就变成 0.9。到第三步时,B 的可能性也是0.9。绿色路径虽然第一步选了一个较差的输出,但是接下来的结果是好的。

image.png

没办法进行暴搜。束搜索是用较有效的方法找一个近似解.

如果任务答案非常明确,这种任务束搜索比较有用;但是如果需要有创造力,束搜索没那么好

加入噪声

语音合成中,模型的训练和测试过程均需要加入噪声,这样能提高结果

使用强化学习训练

评估标准是BLEU,但是训练的时候是最小化交叉熵,两者存在一定区别,最小化交叉熵不一定可以最大化BLEU分数
但如果要计算BLEU分数,损失无法做微分

因此可以用强化学习进行训练,把损失函数作为强化学习的奖励,把解码器作为智能体

计划采样

测试的时候,解码器看到的是自己的输出,因此它会看到一些错误的东西。但是在训练的时候,解码器看到的是完全正确的,这种不一致的现象叫做曝光偏差(exposure bias)。

假设解码器在训练的时候永远只看过正确的东西,在测试的时候,只要有一个错,就会一步错步步错。因为解码器从来没有看过错的东西,它看到错的东西会非常的惊奇,接下来它产生的结果可能都会错掉。

有一个可以的思考的方向是:给解码器的输入加一些错误的东西,不要给解码器都是正确的答案,偶尔给它一些错的东西,它反而会学得更好,这一技巧称为计划采样(scheduled sampling)

image.png|375