深度学习中虽然网络模型众多,如Faster RCNN、Mask RCNN、LSTM......,现在也是每天都会有新的网络模型被提出,但是整体可以归为4种架构:

1)前馈神经网络:FNN,也叫做多层感知机(MLP),因为前馈神经网络就是多个感知机堆叠起来,可以解决感知机无法解决的异或问题,前馈神经网络的数学基础是通用近似定理,一个具有足够多神经元的前馈神经网络可以近似任意一个连续函数,具体介绍可见:深度学习基础-2 前馈神经网络

2)卷积神经网络:CNN,注意“卷积”并不是卷积神经网络独立提出的,在卷积神经网络提出之前卷积就已经在信号处理、图像处理中广泛使用了,如传统图像处理中的Solbel算子、拉普拉斯算子等,其实就是一种人工定义的卷积核,卷积这种计算方式因为先验的引入了局部相关这个假设,所以卷积神经网络处理那些具有局部相关性的数据效果较好,比如图像,图像中的物体往往都是聚集在某个区域中,而不会弥散到整张图像,具体介绍可见:深度学习基础-3 卷积神经网络

3)循环神经网络:RNN,循环神经网络如果深入介绍会涉及到动力系统近似、图灵计算等,如果简单的说,RNN其实就是一个带有历史输入信息的FNN,普通FNN中当前层的输入就是上一层的输出,但是RNN当前层的输入除了普通输入外,还有一个历史信息输入h,RNN中一般称h为隐状态,它表示对于所有历史输入的一种信息总结,具体介绍可见:

4)Transformer:这是这篇文章要介绍的网络结构,也是这个深度学习基础系列最后的内容。可以毫不夸张的说,近几年你能关注到的科技热点,背后都有Transformer的影子。那么Transformer究竟是什么呢?Transformer其实就是一个带有多头注意力机制的FNN,Transformer强大的特征表达能力来自于多头注意力机制,这篇文章会结合Transformer的原论文《Attention Is All You Need》梳理一下Transformer

一 注意力机制

注意力机制的计算过程定义如下:

图片

称Q为查询、K-V为索引-值对,Q、K、V一般维度是相同的,行的维度是dk。注意力机制先计算Q和K的内积,得到注意力权重矩阵,注意力权重矩阵通过内积运算记录了查询Q和索引K的相关性,除以dk是为了防止方差过大信息发散,softmax()操作将注意力权重矩阵转换为注意力得分矩阵A,注意力得分矩阵A每一行的和为1,是一个行随机矩阵

图片

但是A不是对称矩阵,所以不具有正定性,最终A乘以V是一个凸组合变换

图片

图片

图片

图片

简单理解,注意力机制就是一种“加权融合”,能从输入信息中筛选出重要的信息进行接下来的处理,在不同领域,可以从不同视角来理解这种“加权融合”机制

图片

对于注意力机制会有以下几个问题:

1 为什么用内积(点积)衡量相似性

高维数据可以简单理解为向量长度很大的数据,如向量[1,2,3]可以表示一个三维空间中的数据,位于x轴坐标为1、y轴坐标2、z轴坐标为3的位置,增加向量的长度,就相当于增加了向量所处空间的维度,一个[1,2,3,4,5,6,7,8,9,10]向量就表示一个十维空间中的向量,对于超过三维以上的空间,人是无法想象它具体样子的,我们只能通过运算法则、维度变化去捕捉它的性质和变化。

为什么要说高维数据呢?因为深度学习中处理的往往都是高维度的向量数据,比如一个词嵌入向量为512维,卷积神经网络中间输出的特征图是一个[c,h,w]维度的张量等等,高维空间中的数据具有距离失效的问题:

图片

欧式距离在高维空间中无法准确衡量距离,而“距离”又代表着相似性,那么如何解决高维数据的相似性衡量问题?

图片

图片

既然随机向量的内积、余弦相似度会失效,那么如果我们构建向量空间时,刻意的让深度学习模型生成的向量在向量空间中具有“语义相近,则向量相邻”这个性质,从而就可以解决距离失效的问题,也就是说将内积方式显示建模到模型中,避免高维数据出现的距离失效问题。那么既然内积可以建模,为什么不用欧式距离、余弦距离建模,答案是也可以,但是内积计算更高效,因为内积就是一个矩阵乘法,底层的GPU硬件能更好的支持,如果改为欧式距离需要开方再求根号等,很麻烦。

图片

2 为什么要除以根号下dk

图片

图片

3 为什么不用网络来学习注意力得分

既然最后就是为了得到一个注意力得分矩阵A,能否直接利用一个网络从输入中学习注意力得分,没必要非得计算Q、K的内积

图片

二 多头注意力机制

简单理解多头注意力机制就是做多次注意力机制,次数称为“头”,只不过每次计算注意力机制时,输入的Q、K、V不同,计算公式如下:

图片

先将Q、K、V利用投影矩阵投影到h个不同的空间中,h就是多头注意力的头数,然后在每个空间中进行注意力机制的计算,最后将h个不同空间的注意力结果进行拼接就是最终多头注意力的计算结果,普通注意力机制和多头注意力机制运行效果图如下:

图片

一定要理清:多头注意力不是简单的重复多次上面所讲的注意力机制运算

图片

图片

图片

图片

图片

图片

图片

图片

常见误解:

图片

三 Transformer

Transformer整体结构如下:

图片

从中间一分为二,称左侧部分为编码器(Encoder),负责对输入进行特征提取,Bert类模型就是只使用Encoder这一部分。

右侧部分为解码器(Decoder),负责根据输入,生成出我们想要的输出,GPT系列,我们现在使用的大模型系列就是只使用Decoder这一部分。

1 输入

图片

Encoder的输入在原论文里是一句话分词结果的词表ID序列,经过“Input Embedding”得到这句话的嵌入表示矩阵X,具体过程可以看:大模型应用开发-基础理论

Decoder的输入是原始训练对儿输出的整体右移一位。

举例来说,我们用Transformer处理翻译的问题,原始训练数据集中一个翻译训练对儿是“我爱你->I love you”,将“我爱你”经过分词器分词,得到词表ID序列,对词表ID序列进行词嵌入,得到词嵌入矩阵,作为Encoder的输入。“I love you”右移一位变为“I love”输入到Decoder中,其中是我们人为规定的一个符号,表示一句话的开始,这么说只是为了更好理解,但实际上是先对“I love you”进行分词处理,得到词表ID序列,假设为[1,2,3],右移操作是针对这个词表ID序列,变为[,1,2]输入到Decoder中,原先的[1,2,3]作为标签,通过监督学习的方式训练整体Transformer,也就是Transformer的任务是预测下一个词语(next token)。

2 位置编码

由前面的介绍,Transformer就是一个带有注意力机制的FNN,而注意力机制的核心是内积,内积对于输入的顺序是不敏感的,也就是<a,b>=<b,a>,但是我们处理的自然语言中,词语之间是有相对顺序的,也就是“我吃饭”和“饭吃我”在我们看来不是同一句话,但是在Transformer看来它们两个是一样的,那么如何让Transformer知道它们是两句不同的话呢,这就需要我们人为的为每个词语添加上位置信息,来告诉Transformer“这是第一个词语’我’、这是第二个词语’吃’......”。我们把添加位置信息这个动作叫做“位置编码”,原论文中使用的位置编码方式如下:   

图片

pos表示当前位置,比如第一个词语、第二个词语等,i是这个词语词嵌入向量的第i个维度,比如一个词嵌入向量维度是512,i就是其中的某个维度。带入位置编码计算公式,会得到一个和词嵌入向量相同维度大小的位置编码向量,将这个位置编码向量加到词嵌入向量上就完成了位置编码

图片

图片

图片

图片

图片

3 Encoder模块

图片

Encoder包含N个上图所示的模块,每个模块由多头注意力(Multi-Head Attention)、残差连接(Add)、正则化(Norm)、前馈神经网络(Feed Forward)构成。

图片

下面理清一个词嵌入矩阵X在Encoder中的变化

1)利用可学习矩阵W-Q、W-K、W-V对X进行变换,得到Q、K、V,带入上文所讲的多头注意力机制中得到计算结果

2)将X加到多头注意力结果上进行残差连接

3)对残差连接结果进行正则化

4)正则化结果输入到前馈神经网络中进行特征提取

5)前馈神经网络特征提取结果和3)结果进行残差连接

6)对5)的结果进行正则化,得到当前Encoder模块的输出

注意模块的输出维度和输入维度是相同的,都是[N,d-model],其中N是输入的序列长度,d-model是词嵌入维度。Encoder就是通过堆叠多个这样的模块,逐步的对输入的词嵌入矩阵X进行特征提取,最终生成X的语义特征表示矩阵[N,d-model],也就是输入的一句话的语义特征表示,我们也称其为这句话的嵌入向量,嵌入向量的生成有两种方法,一是直接对Encoder输出的[N,d-model]矩阵逐行相加求平均,得到[1,d-model]的嵌入向量,另外一种方法是类似Bert,在最初的词嵌入矩阵X上添加一个行向量,形式化表示为[cls]符号,[cls]对应的词嵌入向量是随机初始化,随着Encoder的训练过程逐步学习的,最终用[cls]这个向量作为这句话的嵌入向量。有了这个嵌入向量,我们就可以利用向量数据库、RAG技术等进行接下来的语义处理,具体可见大模型应用开发文章:大模型应用开发-Langchain(V1-最新版)-下

Encoder中的FFN层是一个细粒度的特征提取

图片

图片

图片

图片

图片

图片

论文中可视化了多头注意力的效果

图片

图片

4 Decoder模块

图片

Decoder模块由N个上图中的模块构成,根据Encoder模块的输出和训练对的输出,解码出真正的输出,听起来很拗口,解释如下,还是以翻译问题为例。

翻译训练数据集中有这样一个数据“我爱你->I love you”,将“我爱你”输入到Encoder中,Encoder对“我爱你”进行特征提取,得到我们上文所说的语义特征表示矩阵[3,d-model],”3”是因为“我爱你”长度为3,“d-model”是我们人工预先定义的词嵌入向量维度,一般使用512维,“I love you”整体左移一位变成“I love”,其中是我们人为添加的一个符号,表示一句话的开始,“I love”经过Decoder的嵌入层之后也会变为一个[3,d-model]的词嵌入矩阵。Decoder的任务就是根据Encoder输出的[3,d-model]矩阵,自己词嵌入层生成的矩阵[3,d-model],解码出真正的句子“I love you”,也是一个我们人为预先定义的符号,表示一句话的结束,如果我们观察到Decoder输出这个符号,就认为它解码完成了,我们可以根据它解码的内容和真实的内容计算损失,通过反向传播训练整个Transformer网络。

Decoder整体和Encoder相同,但是有两点需要注意:

1)Decoder相比Encoder多了一个多头注意力层,在这个多头注意力层中Encoder的输出作为K、V,Decoder上一个多头注意力层的输出作为Q,利用多头注意力机制获取解码时应该从Encoder中关注的信息

2)Decoder的任务是预测下一个词语,所以训练时为了避免Decoder提前看到下一个词语,需要用mask机制屏蔽掉下一个词语的相关信息,避免Decoder作弊

5 输出

图片

图片

四 Transformer拓展

Transformer最初是2017年谷歌为了解决翻译问题提出的,近几年针对最初的结构进行了很多研究,下面挑几个重点说

1 输入

1.1 mask机制

在训练 Transformer时,如果一个 batch 中的句子长度不一致,必须对输入进行 padding (填充),以使所有样本具有相同的序列长度,从而能够组成张量(tensor)进行批量计算

图片

图片

图片

图片

对于过短的句子需要pad,过长的句子则需要截断

图片

图片

图片

图片

图片

图片

Attention Mask 在 Transformer 中的使用贯穿整个注意力计算过程,其核心作用是:在 softmax 之前将无效位置(如 padding 或未来词)的注意力分数置为负无穷(-∞),使其 softmax 后权重为 0,从而“屏蔽”这些位置的影响。

图片

图片

图片

图片

图片

图片

图片

图片

1.2 多模态

Transformer要求输入的是一个序列,如何将文本、图像、声音等多模态的数据转换为序列,统一利用Transformer进行处理,如何对齐不同模态之间的信息,是多模态重点研究的内容

2 位置编码

最初Transformer的位置编码是一种基于公式的绝对位置编码,输入序列过长时效果较差,近几年为了让Transformer处理更长的序列,提出了相对位置编码,不关心整体序列长度,只关心序列不同位置之间的相对信息

3 注意力模块

注意力机制是Transformer高效特征提取的核心,其通过长距离关系建模、自适应注意力权重,对输入进行有效的特征提取,但是注意力机制的计算复杂度和输入序列长度N的平方成正比,严重阻碍了注意力机制的使用,近似注意力、高效注意力计算被提出,这些方面的代表是GQA、FlashAttention等

4 FFN模块拓展-MoE架构

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

5 输出

如何让Transformer的Decoder输出更可控,是现代大模型应用开发的核心关注点大模型应用开发-基础理论

五 整体总结

图片

更多推荐