Transformer学习笔记

参考了很多大神@DASOU_NLP从入门到放弃 @台大李宏毅 @霹雳吧啦Wz  @跟李沐学AI的讲解,记录一下自己的学习历程。


目录

1 Transformer总体架构

2 Encoder层

3 输入部分(Embedding层+位置编码)

4 注意力机制

4.1 自注意力机制

4.2 多头注意力机制

4.3 Self-attention  VS RNN

4.4 Self-attention  VS CNN

5 Decoder层

5.1 Masked muti-head attention

5.2 交互层

6 一些补充知识

6.1 残差结构

6.2 batch norm

6.3 layer norm

参考链接:


1 Transformer总体架构

Transformer是Google在2017年提出的一种全新的神经网络结构,主要用于序列学习任务,如机器翻译、文本摘要等。它通过自注意力机制来建模序列元素之间的依赖关系,实现序列到序列的建模。

《 Attention is all you need》本篇主要应用在NLP任务里,我们以机器翻译为例,Transformer做的事情就是,输入一句话,再把它的翻译结果输出出来。Transformer相当于黑箱子,它主要分为encoder和decoder两部分。论文里的encoder和decoder分别为6层,这里的编码层和解码层架构相同但是参数不一样!且并不是只训练一个encoder,剩下的5层都是复制来的,它是一起训练的

2 Encoder层

Encoder编码器,主要用于对输入序列进行特征提取与编码。包含多层Encoder Layer,多个Encoder Layer是同时训练的,它们的参数是独立的,但输出是通过残差连接和层归一化相加得到的,每个Encoder Layer又包含两个子层

  •  Self-Attention:自注意力子层,利用多头注意力机制来建模序列内部的依赖关系,获得序列的上下文表征。输出为Attention Outputs
  • Feed Forward:前馈子层,包含两个线性变换与ReLU激活函数,用来增强Self-Attention的表征,输出为FFN Outputs

然后,这两个子层的输出通过残差连接和层归一化相加,作为Encoder Layer的最终输出:

EncoderLayer Output = LayerNorm(Attention Outputs + FFN Outputs)

所有的Encoder Layer输出也按照同样方式相加,作为Encoder的最终输出:

Encoder Output = EncoderLayer1 Output  
                 + EncoderLayer2 Output  
                 + ... 
                 + EncoderLayerN Output

在训练过程中,每个Encoder Layer都有自己的训练参数,但它们最终的输出是相加的。这样的设计有以下好处:

  1. 每个Encoder Layer可以建模输入序列的不同特征与模式。不同层的Self-Attention会聚焦在不同的依赖关系上。这增强了模型的表达能力。
  2. 通过残差连接,每个Encoder Layer只需要学习输入与其输出的差异部分。这缓解了网络加深时的退化问题,使得模型可以达到更深的层数。
  3. 层归一化可以更好地 propagating each Encoder Layer的梯度,使其可以并行优化。这提高了训练的效率。
  4. 在推理时,直接将所有Encoder Layer的输出相加可以得到序列的最后表征。这简化了模型的部署过程。

3 输入部分(Embedding层+位置编码)

Transformer输入的信息可以是一段音频、一个图网络、一句话,输出的信息也可以分为两类

  • 输入的每个向量都有标签或者数值

  • 输入的向量作为一个整体进行分析:

RNN是非常典型的循环神经网络,它在处理nlp任务时面对输入的句子信息,自然而然的包含时序信息,transformer抛弃了神经网络结构,改用self-attention,在可以并行同时也丢失了词序信息,我们就需要将包含位置编码的数据进行输入。

one-hot也是可以的,每一个维度代表一个数据,当数据量比较小的时候也可以用,但是数据量比较大的时候就不是很适合了,假如10w个数据,总不能给它一个10w的向量矩阵吧,且这个矩阵里根本看不出来语义信息,字向量之间是没有关联的。用Embedding可以将相似的点在空间里更聚集,语义相关的词拥有接近的向量表示。

输入部分整体就是对某个词向量都在512维的空间里进行拼接,使它作为整体的输入

input = input_embedding + positional_embedding

位置编码:位置编码(Position Encoding)是一种特殊的Embedding方式,它为序列中的每个元素赋予一个唯一的向量表示,用以表示该元素在序列中的位置信息,transformer论文里采用正余弦编码,这样的编码既可以蕴含绝对位置信息也包含相对位置信息。

  1. 用于提供绝对位置信息,表示每个token在整个序列中的相对顺序。这是Transformer缺失的位置敏感性。
  2. 通常是模型参数的函数,如正弦函数PE(pos,i)=sin(pos/10000^(2i/d_model))。因此不需要训练,并且对所有序列都适用。
  3. 随着维度的增加,每个位置的编码也在变化,这使得模型可以利用不同的维度对不同的位置进行编码,获知丰富的位置信息。
  4. 通过与Embedding的相加,将位置信息融入每个token的表达中。这使得模型既具有语义信息也具有位置信息,可以建立语义与位置的关系。

Embedding:Embedding是机器学习中的一个概念,指将高维稀疏的数据映射到低维空间的过程。它的主要目的是找到数据中潜在的低维结构,使得相似的数据点在低维空间中更加聚集。这可以用于数据的可视化、降维与特征学习

  1. 用于提供语义信息,将输入的one-hot词向量映射为语义丰富的dense词向量。这降低了输入的维度,并编码了词与词之间的语义依赖关系。
  2. 是模型训练的参数矩阵E,需要经过大量数据进行学习与优化。不同的矩阵会对不同的输入进行不同的映射。
  3. 仅根据输入字典的大小来确定行数,忽略了位置信息。这使得Embedding层本身是位置无关的。
  4. Embedding矩阵中的每一行都对应一个输入token的词向量。通过查表的方式,根据输入的one-hot ID查找对应的词向量。 
  5. Embedding可以通过矩阵的学习,自动获得数据集的语义信息与规律,这减轻了模型的难度且增强了泛化性。但这也要求有足够的数据进行有效学习。

综上,位置编码为Transformer模型提供了位置信息,使其能够建模输入序列的顺序关系。Embedding为Transformer模型提供了语义信息,增强其对词与词之间关系的理解。


Transformer模型使用嵌入层(Embedding)将词转换为向量表示。其主要步骤如下:

  1. 构建词表:收集训练数据中的所有词,并按出现频率排序,选取排名较高的N个词构建词表。N的选择需要权衡模型的覆盖率与参数量。Transformer中常用的词表大小为30000~50000。
  2. 初始化词向量:为词表中的每个词随机初始化一个实值向量。通常初始化为[0,1]区间内的实数,使初始词向量接近于0均值。
  3. 加入位置编码:为输入序列中的每个词加入一个位置编码向量。这使模型对词的位置信息具有感知,可以进行序列建模。位置编码一般通过正弦函数与余弦函数进行映射。
  4. 输入Embedding:将输入序列中的词索引通过Embedding层转换为对应的词向量。同时加上位置编码向量,得到Embedding层的输出结果。

4 注意力机制

   4.1 自注意力机制

针对一个sequence,我们不仅要看到当前词向量,也希望看到上下文的语义信息,怎么做呢?

可以把这个窗口拉大一点,如下:

 但是输入的sequence很长呢?窗口无限增大参数量和计算量无疑也会变大

芜湖~自注意力机制来咯~

 我们希望不仅可以看到上下文信息,但是不用那么大的参数量:

 

  •  self-attention:关注全局信息
  • FC层:关注某个具体位置的信息

 那么self-attention是怎么做的呢?

a1,a2,a3,a4是输入信息(事实上它们作为sequence里的数据,都是并行化处理的,并没有位置信息,通过上面的embedding加了位置编码之后才会有),b1,b2,b3,b4是考虑了整个所有a的sequence 才输出的结果,4个a所以会对应产生4个b,且b1,b2,b3,b4是同时得出的。

 以b1为例,用α表示整个sequence中与a1关联程度,通常用Dot-product和Additive两种方法,如下图:Dot-product是输入两个向量,分别乘以两个不同的W矩阵,得到的结果相乘,即为α值,Transformer就是用的这个方法。

计算α值,并经过softmax做归一化处理,得到最终的结果。通过数值就可以看出向量是a1的相似度。(也可以不用softmax,也有人尝试relu6,得到了更好的效果,炼丹侠名不虚传~)

 通过得到的α'找到最相似的a,在整个sequence里抽取相关信息,如何抽取呢?

v1,v2,v3,v4分别来自于a1,a2,a3,a4,将其乘以Wv矩阵,再乘以α'得到b值

so如果两个值关联性很强,比如a1与a2,那么他们的α'就会很大,得到的b值就会比较接近~

(我觉得:上面用soft-max就是要对结果进行归一化处理,好加权~)

(我还觉得:是因为qkv都是来自自己,所以叫自注意力)

 

 下面就是矩阵角度再解释了一遍:

 

 总结起来就是下面这张图片,整个训练过程中只有红框里的参数是需要学习的~

Encoder的训练步骤主要包括:

  1. 定义Encoder结构:Encoder由多个相同的Layer堆叠构成,每个Layer包含一个Multi-Head Attention层和一个Position-wise Feed-Forward层。
  2. 制作训练数据:源语言序列的词表编码作为Encoder的输入,每个位置的词ID构成一个向量作为该位置的表达。同时生成该序列的Position Encoding,为每个位置提供绝对位置信息。
  3. 迭代训练Encoder参数:(1)输入源语言序列的表达,并添加Position Encoding,得到Encoder的输入。 (2)Encoder的第一个Layer使用输入序列作为Query,Key和Value,计算Attention权重,得到Attention层的输出。(3)Attention层的输出传入Feed Forward层,进行非线性变换,得到Encoder第一层的输出。(4)Encoder第二层使用上一层的输出作为输入,重复(2)-(3)步骤,计算Attention与得到Feed Forward层输出。(5)Encoder重复(4)步骤,逐层堆叠直到最后一层。最后一层的输出作为Encoder的输出表达。(6)Encoder的输出传入Decoder,用于计算损失与更新参数。基于该损失,Encoder的各层参数通过反向传播进行更新。 (7)重复(1)-(6)步骤,迭代更新Encoder的各层参数直到损失收敛。
  4. Encoder表达的提取:在推理时,输入源语言序列到Encoder中,输出最后一层的输出作为序列的表达。这种表达可以用于各下游任务,如机器翻译、摘要、分类等。

综上,Encoder的训练主要是定义其结构,构造训练数据,并迭代更新其Attention层与Feed Forward层的参数。在推理时可以提取输入序列的表达,这段表达捕捉了序列的全局语义与语法,是完成各下游任务的关键信息。

   4.2 多头注意力机制

多头实际上是希望捕获不同维度的特征信息

多头注意力机制在翻译和语音辨识等方面比较常用,因为对于一个输入向量,计算机需要注意不同的信息,多个q负责不同种类的相关性。计算方式和步骤和自注意力机制是一样的,需要注意的是如上图箭头标注的,a1产生的第一个q,k,v(第二层的那12个)只与a2产生的第一个q,k,v作相关运算。

4.3 Self-attention  VS RNN

  1. Self-attention可以并行化处理,Rnn只能按顺序执行;
  2. 因此如果网络较深的话,前面的信息可能会丢失;
  3. Self-attention可以考虑全部的输入,而RNN似乎只能考虑之前的输入(左边)。(但是当使用双向RNN的时候可以避免这一问题)

4.4 Self-attention  VS CNN

 

 

5 Decoder层

 Decoder的训练步骤主要包括:

  1. 定义Decoder结构:Decoder由多个相同的Layer堆叠构成,每个Layer包含两个Multi-Head Attention层和一个Position-wise Feed-Forward层。
  2. 制作训练数据:源语言序列的编码通过Encoder处理得到的中间表达作为Decoder第一个Attention层的Key和Value。目标语言序列与源语言序列对齐,每个位置的目标词作为Decoder输出的教师强制标签。
  3. 计算Attention Mask:对Decoder的第一个Attention层构造掩码矩阵,屏蔽Encoder表达中后续位置的信息。这个掩码在训练与推理过程中保持不变。
  4. 迭代训练Decoder参数
  5. beam search解码

综上,Decoder的训练主要通过迭代更新其Attention层和Feed Forward层的参数,并在推理时采取beam search策略进行解码。Attention Mask确保其第一个Attention层不会考虑后续位置的信息。

5.1 Masked muti-head attention

因为多头注意力机制是并行处理的,就是所有的输入计算机都是可以看到了,如果训练的时候也采用这样子的方法,所有的输入信息都对当前节点的输出提供了信息,训练结果很好,但是预测的时候可能效果不佳(就相当于平时抄作业但是考试的时候啥也不会)

 

 比如上图,我们希望you是它自己根据前面的信息自己训练出来的,不是看了全部的信息之后才得到的。解码端预测的时候是一个个解码,看不到当前单词之后的信息,所以在训练的时候需要把这个信息抹掉,保证一致性。

(就是训练的时候把“答案”遮住,不然知道答案训练,然后去预测结果会很差)

5.2 交互层

所有Encoder的输出和Decoder的每一层进行交互

 迭代训练Decoder参数:

  1. Decoder的第一个Attention层使用Encoder的表达作为Key和Value,计算Attention权重。该层的输出作为第二个Attention层的Query输入。
  2. Decoder的第二个Attention层使用上一层Attention的输出作为Key和Value,计算Attention权重。该层的输出与目标输出词进行比较,计算交叉熵损失。
  3.  基于该损失, Decoder的参数通过反向传播进行更新。
  4. Decoder的Feed Forward层对Attention层的输出进行变换,其输出作为Decoder下一层的输入。
  5. 重复上述步骤,逐层训练Decoder的参数,直到损失收敛。

beam search解码:在推理时,Decoder逐层解码以生成最终的序列输出。具体步骤如下:

  1. Encoder的输出作为Decoder第一层Attention的Key和Value,计算Attention权重,得到输出。
  2. Decoder第一层的输出与所有可能的目标词比较,选取得分最高的前k个词作为第二层Attention的Query输入。
  3. Decoder第二层Attention使用上一层Attention的输出作为Key和Value,计算k个Query的Attention权重与输出。    
  4. 重复上述步骤直到解码出完整的目标序列。
  5. 从k个解码序列中选择得分最高的作为最终输出。

6 一些补充知识:

6.1 残差结构

 残差结构(Residual Connection)是Transformer模型中用于加速训练与提高模型深度的一种关键技术。它将深层网络的中间层输出与相对应的输入进行相加,然后将结果作为最终的输出。

梯度消失一般情况下是因为连乘(但是对于RNN有一点小小不一样的地方,RNN梯度消失是远距离梯度被近距离梯度主导,RNN中的总梯度不会消失,而是远距离输出对应的梯度更容易消失,从而导致模型难以学到远距离的依赖关系。)

但是对上面的输出进行链式求导,因为有1的存在,不管连乘再多,都不会发生梯度消失。

这也是为什么,NLP任务里,网络可以变得比较深的原因,缓解梯度消失

6.2 batch norm

对batch的样本,在同一维度做处理(针对同意特征)

为什么不用batch norm,而用layer norm?

 bn优点:

  1. 可以解决内部协变量偏移
  2. 缓解了梯度饱和问题(如果使用sigmoid激活函数的话),加快收敛

bn缺点:

  1. batch_size较小的时候,效果差。(因为它是用batch样本模拟所有的样本的均值和方差,如果batch-size比较小的话,差异就会很大,影响结果)
  2. BN 在RNN中效果比较差(Rnn的输入是动态的,不能有效的得到整个样本的均值和方差)

 比如上面的例子,10个样本,前9个样本都是5个单词长度,第10个单词长度为20,那么前5个单词的均值和方差容易得到,6-20的方差怎么得到呢,如果只取第10个样本,那么又回到了它的第一个缺点,batch_size较小

6.3 layer norm

LayerNorm单独对一个样本的所有单词做缩放可以起到效果。

 

参考链接:

1.【李宏毅机器学习2021】自注意力机制 (Self-attention) (下)_哔哩哔哩_bilibili

2.位置编码详细解读_哔哩哔哩_bilibili

3.Transformer论文逐段精读【论文精读】_哔哩哔哩_bilibili 

4.Transformer中Self-Attention以及Multi-Head Attention详解_哔哩哔哩_bilibili

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值