Transformer
Transformer
编码器
每个Encoder Layer的主要任务都是对其输入序列进行上下文建模,使每个位置的表示能够融入整个序列的全局信息
两个子层:
- 自注意力子层(Self-Attention):用于捕捉序列中各位置之间的依赖关系
- 前馈神经网络子层(Feed-Forward):用于对每个位置的表示进行线性变换,从而提升模型的表达能力
自注意力子层
计算过程:
- 生成Query、Key、Value向量
- 计算位置之间的相关性
- 计算注意力权重:使用
softmax函数进行归一化 - 加权汇总生成输出
多头注意力机制
自注意力机制通过QKV向量计算每个位置与其他位置之间的依赖关系,使模型能够有效捕获序列中的全局信息
为理解显示语言中的句子,模型需要同时识别并建模多种层次和类型的依赖关系。但这些信息很难通过单一视角或一套注意力机制完整捕获
多头注意力机制(Multi-Head Attention),就是通过多组独立的QKV投影,让不同注意力头分别专注于不同的语义关系,最后将各头的输出拼接融合。
原始论文中为8头
前馈神经层
对每个位置的表示进行逐位置、非线性的特征变换,进一步提升模型的对复杂语义的建模能力。
通常使用ReLU激活函数
残差连接与层归一化
这两者是深层神经网络中常用的结构,用于缓解模型训练中的梯度消失、收敛困难等问题
残差连接
用于缓解深层神经网络中的梯度消失问题
核心思想:将子层的输入直接与其输出相加,形成一条跨越子层的“捷径”
$$
y=x+SubLayer(x)
$$
确保方向传播时,梯度至少有一条稳定通路可以回传
层归一化
每个子层在残差连接后都会进行层归一化,他的主要作用是规范输入序列中的每个token的特征分布(某个token的表示可能在不同维度上有较大数值差异),提升模型训练的稳定性。
位置编码
Transformer无法像RNN一样天然地捕捉词语之间的顺序关系,如果没有额外机制,无法区别“猫吃鱼”和”鱼吃猫“
引入位置编码,让模型在处理每个词时,既能获取词义信息,也能感知其在句子中的位置,从而具备基本语序的能力。
采用正弦和余弦编码方式对输入地token进行位置编码
解码器
每个Decoder Layer都包含三个子层:
- Masked自注意力子层
- 编码器=解码器注意力子层
- 前馈神经网络子层
Masked自注意力子层
用于建模当前位置与前文词之间的依赖关系。
限制每个位置只能关注它前面的词
编码器-解码器注意力子层
用于建模当前位置与源序列各位置之间的依赖关系。
通过注意力机制,模型能够根据当前状态从编码器的输出中提取相关上下文(相当于Seq2Seq模型中的Attention机制)
前馈神经网络子层
与编码器中的结构完全一致
每个子层也配有残差连接与归一化
词嵌入
分词器和独热编码,就是分别在利用不同的策略对token实施数字化
分词器就是为每个token没配一个独立的ID
独热编码就是把一个二进制里的每一位都对应一个token
利用潜空间
- 基于分词后的ID去升维
- 基于独热编码去降维
一个神经网络的隐藏层就是在进行一次空间变换
其中隐藏层中的神经元个数就是你在变换后空间的维度
隐藏层中神经元个数比输入的多就是升维,反之则是降维
数据在进行完线性运算之后,还要经过非线性的激活函数,只有靠激活函数引入非线性,才可以让模型描述更加复杂的情况
潜空间就是一个没有符号、发音等等这些形式上差别的非常纯粹的语义空间
编码就是就是先把文本里的一个token都先编写成独热码,然后进行降维这个过程就是把输入的一句话根据语义投射到一个潜空间中,把高维空间中的对象投射到低维空间,这个过程叫embeding,也就是嵌入,在语言处理领域主要针对的就是单词或者token,所以这个过程也叫词嵌入
注意力机制
对词和词组合后的语义进行理解靠的就是注意力机制
注意力机制:作为一组词向量然后经过三个矩阵相乘之后,分别得到QKV三个矩阵,然后在经过一顿运算,最后还是会输出一组词向量
词嵌入已经解决了单个词单个token词义的问题,注意力机制要解决的就是许多词组合在一起之后,整体体现出来的那个语义。
只有把一句话里多个词同时输入到模型里面,才能解决整体语义问题
得到QKV之后,先把k进行转置,q与转置k相乘,会得到一个txt的矩阵A,即注意力得分,得到A之后要将A中的每一项进行一个缩放,就是除以根号Dout,为了让A矩阵的数值分散,而不是集中在o和1之间的饱和区,在进行softmax计算,softmax之后每一行加起来都是1,得到A‘,最后A’和V相乘
V就是在表示从词典中查出来的token的客观语义,A‘就相当于是这段话因为上下文关联而产生的修改系数。
注意力机制需要做的就是,需要它识别出那些因为上下文关联,而对词典原本客观的语义进行调整和改变的幅度
为什么A’能表示修改系数,关键就是Q和K相乘的过程,q乘k的转置,就是表示向量之间的内积,而内积就是表示一个向量在另一个向量上的投影,某种程度上就是体现在两个向量之间的相关关系
为什么一定要有两个矩阵Q和K呢
只是一个矩阵相乘的话,输入数据x到输出A就是一个线性变化,只能表示线性关系
如果是两个矩阵相乘的话,把中间的Wq和Wk的转置算成一个矩阵,就看起来很像一个二次型
是在给注意力机制加入一些非线性要素,让模型可以表达一些更复杂的情况
Q和K可以分别表示成设定语义和,在一定设定语境情况下的表达语义
自注意力机制相当于蒙头自学
交叉注意力机制
交叉注意力机制是一种校准,解码器的每一层都会拿着编码器的结果作为参考,然后去比较相互之间的差异,每做一次注意力计算都需要校准一次
编码器输入好久不见,解码器输入long time no see,首先按照Transformer的编码和解码的过程逐渐向上运算,然后用交叉注意力进行匹配,看看他们是不是一样,最后得到一个损失函数
编码部分和解码部分都会得到一个潜空间的解向量,这个词向量是不是匹配,损失函数就是这个词向量的差异,通过损失函数得到损失值,然后在进行反向传播,去修改模型里的参数,最后达到编码器和解码器他们在潜空间中的词向量,所表示的词意是能对应起来的
最初的理解就是你输入多少个token输出个多少个token才行,现实中的中英文却不是这样,中文所表达的语义,要翻译成英文,token数就不一定了,也就是seq2seq的问题
最开始解决seq2seq,用的就是RNN,Transformer也是用到了RNN的思想
输入编码器,生成潜空间中的词向量,在解码器中需要输入一开始符,经过交叉注意力计算之后可以得到一个结果,这个结果经过升维和softmax计算之后,会将词汇表里的所有token都计算一个数值,然后拿出一个概率最大的值作为结果,这个结果代表的就是下一个token将会是什么
GPT只有解码器,他不是让模型从0开始去生成,而是把你输入的内容先输入到模型里面,然后让模型把你的内容看作是他已经生成的内容,它只继续生成后续内容就行了
多头注意力机制就是能力更强的CNN,其中词向量的维度就是对应的CNN中的通道,多头对应的就是卷积核
多头就是输入词向量分别计算多次,这几个注意力机制中系数是各自独立的,得到的结果也可能不同,最后将结果拼接起来,行数和输入的矩阵相同,维度他是每个输出的维度乘以头数,得到这个矩阵之后在和一个w相乘,得到一个词向量
位置信息:保证输入的一组词向量在并行计算的同时还能体现他们之间的顺序
解码器中的掩码:
解码器部分是一个词一个词生成的,就代表了你生成到某个词的时候,他只能收到他之前词的影响,不应该被未来生成词所决定。
注意力机制的矩阵A可以表示一个词和所有上下文之间的关系,既包含他之前的,也包含它之后的,所以就需要把矩阵A中的这部分词给屏蔽掉,屏蔽的方法就是在上三角位置分别加上一个无穷小,这样在softmax计算时他就一定是0




