关于Transformer的理解

结合李宏毅老师机器学习2021——Transformer课程和网上查阅的资料,总结一下对Transformer的理解

Transformer是什么?

从宏观角度来看,Transformer是一种基于Self-Attention机制的Seq2seq模型(序列模型),由编码器和解码器组成(自己总结的)。所以在学习Transformer前,需要先弄明白Seq2seq、编码器 / 解码器、Self-Attention(见本人之前的csdn博客)是什么。

  • Seq2seq模型:
    这是一个序列到序列的模型,输入一个序列,输出另一个序列,通常可用于NLP任务,例如机器翻译、语音识别等等。这个Seq2seq模型包含了一个编码器和一个解码器(换言之,有编码器和解码器的模型就可以认为是Seq2seq模型的范畴)。因此呢,Seq2seq模型有很多种变形,例如编码器 / 解码器可以是RNN,LSTM、也可以是CNN,还可以是Self-Attention等等。
    但是要特别注意,Seq2seq和RNN / LSTM等是不同层面的东西,Seq2seq模型专指输入和输出均为序列的模型,LSTM 等可以用作其编码器和解码器的一种实现方法。但 RNN / LSTM 并不是Seq2seq模型的子集,它们也可以用来做别的问题。
  • 编码器 / 解码器:
    所谓编码,就是将输入序列转化成一个固定长度的向量;解码,就是将之前生成的固定向量再转化成输出序列。具体实现的时候,编码器和解码器都不是固定的,可选的有RNN / BiRNN / GRU / LSTM等等都是可以的,你可以*组合。比如说,你在编码时使用BiRNN,解码时使用RNN,或者在编码时使用RNN,解码时使用LSTM等等。(最基础的是编码解码都是RNN)
    关于Transformer的理解

怎么理解Transformer的流程图?

Transformer虽好,但流程蛮复杂,如果去看明白这张图呢?
关于Transformer的理解

  • 首先左边的是编码器,右边的是解码器。我们将一段序列(向量组)输入到编码器中。在输入时要注意加上位置信息(Positional Encoding)。这段向量组经过多头自注意力机制后输出新的向量组,然后将这个新输出的向量组与旧的输入的向量组相加(残差网络),相加后做一个层归一化(注意是层归一化)。然后在经过一个全连接层,并继续做Add & Norm。这就是编码器的任务。其实都很好理解,主要是得明白self-attention。
  • 然后再看解码器。解码器与编码器是类似的。毕竟直觉上来说,编码器与解码器如果是镜像关系可能更容易train。首先我们将一个begin信号输入到解码器中,意思是“我要开始解码啦”,当然这个信号也需要加上Positonal Encoding,然后解码器每解出一个新的“码”,就将新的“码”当做输入,输送给解码器,进行解下一个码,就这么循环下去一直解就行。这里还有许多注意的细节,例如:
    注意观察解码器比编码器中间多了一层。这一层的作用是用来接收此前编码器计算出来的 K 和 V 矩阵。其实这个很容易理解,我解码器是用来解编码器的,那我肯定要有编码器的信息呀。编码器的K和V矩阵代表了什么?K和V矩阵其实本质就是编码器的输入数据(因为通过输入数据计算出来的K和V矩阵),然后这个 K、V 矩阵与解码器中第一层Self-Attention的Q矩阵一起输入到中间的Self-Attention中。
    另外还要注意,第一层的Self-Attention是Mask的,这个什么意思如果忘了去再看看李宏毅老师的PPT。
    这篇博客比较好,可以作为参考:https://zhuanlan.zhihu.com/p/338817680

Transformer的优点?

  • Transformer 与 RNN /LSTM 等不同,它可以比较好地并行训练。

  • Transformer 与 CNN 不同(有一些是基于CNN的Seq2seq模型),尽管CNN也可以进行并行训练,但是它的内存占用很大,相反 Transformer 的矩阵维度较少。更重要的是,Transformer 可以处理变长的序列样本,而CNN不行。

    备注:其实归根结底,这是 Self-Attention 相较于 RNN / LSTM / CNN 等传统模型的优点(因为Transformer是基于Self-Attention的)

  • Transformer 不像 RNN / LSTM / CNN 等模型一样,需要较强的 domain knowledge (领域知识),其几乎可以对任意非结构化数据(图片、文本、音频)成立。这个其实也很好理解,例如CNN是专门进行图像处理设计的,需要对图像的本质有很深刻的理解。

Transformer有关的其他问题

Transformer是如何处理可变长度数据的?

  • 首先要明白数据的怎么表示的,比如我有一句话“我爱中国”,“我”这个向量是一个one-hot,“爱”这个向量也是one-hot,假设共有8000个常用汉字,那么就是一个8000维的独热向量。这四个字在一起就是一个向量组,这个向量组里包含了4个向量。

  • 弄白了这个之后我们再看什么叫做可变长度数据?这个可变长度,变得是什么?答:变的是向量组的长度,而不是向量的维度。什么意思呢,就是那个8000维是不会变的(因为你每个向量都要做矩阵运算啊,Self-Attention里求KVQ啊,所以肯定维度得一样才行),但是向量的个数是可以任意的。可以是“我爱中国”,也可以是“我爱你中国”,都是OK的。

  • 所以Transformer是可以处理可变长度的,但是RNN、CNN是固定长度的,是不可以输入任意多的向量的,输入向量的个数是被固定死的。

  • 但是,这时候又有一个容易被误解的地方了。就是我们经常会看到一份程序中,假设有的句子是10个字,有的句子(最长的句子)是20个字,我们一般是以20个字为标准来处理的,那个10个字的,我们通过padding方法补0,补齐到20个字。OK,既然Transformer可以处理任意长度的,为啥还要把非任意长度的补齐呢?
    因为我们往往是通过batch输入的啊!一下子输入一个batch,因此,同一个batch里的句子,必须要一样的长度,不同的batch的长度可以不同,同一个batch的长度得相同。这个是batch决定的!一定要搞清楚这一点。

  • 这里再补充一点,如果是batch预测或者训练,要求batch内数据长度保持一致。一般有两种做法,一种是直接padding到固定长度(通常是512,bert里是512),多退少补,即超过最大长度就截断,不够的就补上一个标志位。这样的好处是实现简单,缺点是如果补标志位太多的话,有些效率低下。还有一种做法是每个batch padding到当前batch的最大长度,这样比较省资源,甚至可以做下按长度排序这种操作

Transformer中,为什么是 LayerNorm ,而不是 BatchNorm ?

  • 先给出明确的答案,可以用BatchNorm,但是效果往往不如LayerNorm好、训练难度大。为什么呢?且为什么序列问题就用LayerNorm,图像问题大多用BatchNorm?

  • 首先解释为什么LayerNorm效果比BatchNorm更好。这里面有两个原因:

    第一,要从序列模型本质入手。比如说一个语言模型,我们关注的是一句话中的相似程度(或者叫差异程度),比如一句话说“我爱中华民族”,另一句话说“今天打王者又输了”,这两句话都在一个batch里,但是我们没有必要去讨论这两句话的联系,我们关心的是一句话不同token的内在联系。因此没必要去做BatchNorm,反而LayerNorm会更好。(总结来说,词之间的信息是储存在同一个句子里的。因而用LayerNorm更合理。)

    第二,不同的数据样本可能尺寸并不一样,尽管一个batch中都是一样的长度。但是结合我们之前说的 “有的句子(最长的句子)是20个字,我们一般是以20个字为标准来处理的,那个10个字的,我们通过padding方法补0,补齐到20个字。” 因此一个Batch中对应位置的分量不一定有意义,它可能是padding的结果。虽然序列长度一致了,但是好多embedding是没有意义的,有意义的embedding不应该和它们的分布一致,如果BN会导致有意义的embedding损失信息,所以embedding你就自己和自己归一化吧。

  • 其次解释为什么序列问题就用LayerNorm,图像问题大多用BatchNorm?

    有了上面的基础后,这个也很好理解了,图像数据都是【B,C,W,H】排列的,不同数据样本在每个维度的每个位置都是有值的,这样不同的batch均值、方差都是有意义的。而不同的序列是通过padding补齐的,做batchnorm是是没有意义的。因此图像问题就是BN。

上一篇:c# – SSH.NET – 消息类型80无效


下一篇:Batch Normalization