结合李宏毅老师机器学习2021——Transformer课程和网上查阅的资料,总结一下对Transformer的理解
从宏观角度来看,Transformer是一种基于Self-Attention机制的Seq2seq模型(序列模型),由编码器和解码器组成(自己总结的)。所以在学习Transformer前,需要先弄明白Seq2seq、编码器 / 解码器、Self-Attention(见本人之前的csdn博客)是什么。
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是专门进行图像处理设计的,需要对图像的本质有很深刻的理解。
首先要明白数据的怎么表示的,比如我有一句话“我爱中国”,“我”这个向量是一个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的最大长度,这样比较省资源,甚至可以做下按长度排序这种操作
先给出明确的答案,可以用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。