AI大模子系列之七:Transformer架构讲解

打印 上一主题 下一主题

主题 783|帖子 783|积分 2349

目录
Transformer网络是什么?
输入模块结构:
编码器模块结构:
解码器模块:
输出模块结构:
Transformer 具体是如何工作的?
Transformer核心思想是什么?
Transformer的代码架构
自留意力机制是什么?
多头留意力有什么用?
前馈神经网络
编码器(Encoder)
解码器(Decoder):
基于卷积神经网络(CNN)的编码器-解码器结构
基于Transformer架构的主流语言模子有哪些?


Transformer网络是什么?

是一种基于留意力机制(attention mechanism)的神经网络架构,最初由Vaswani等人在论文《Attention Is All You Need》中提出。它在自然语言处理(NLP)范畴取得了巨大成功,特别是在机器翻译任务中。
传统的循环神经网络(RNNs)和是非时影象网络(LSTM)在处理长间隔依赖关系时存在一些题目,而Transformer引入了自留意力机制来办理这些题目。自留意力机制允许模子在处理序列数据时关注输入序列中的不同位置,而不仅仅是当前位置。这使得Transformer能够并行处理输入序列,加速训练。
Transformer模子设计之初,用于办理机器翻译题目,是完全基于留意力机制构建的编码器-解码器架构,编码器息争码器均由多少个具有雷同结构的层叠加而成,每一层的参数不同。编码器主要负责将输入序列转化为一个定长的向量表示,解码器则将这个向量解码为输出序列。Transformer总体架构可分为四个部门:输入部门、编码器、解码器、输出部门。
如何明确Transformer 架构?
第一,Transformer 架构。它是模子的底座,但 Transformer 不即是大模子,但大模子的架构可以基于 Transformer;第二,GPT。严格意义上讲,GPT 可能不算是一个模子,更像是一种预训练范式,它本身模子架构是基于 Transformer,但 GPT 引入了“预测下一个词”的任务,即不断通过前文内容预测下一个词。之后,在大量的数据上进行学习才达到大模子的效果。
          输入模块结构:


  • 源文本嵌入层及其位置编码器
  • 目的文本嵌入层及其位置编码器
编码器模块结构:


  • 由N个编码器层堆叠而成
  • 每个编码器层由两个子层连接结构组成
  • 第一个子层连接结构包括一个多头自留意力子层、规范化层和一个残差连接
  • 第二个子层连接结构包括一个前馈全连接子层、规范化层和一个残差连接
         编码器encoder,包罗两层,一个self-attention层和一个前馈神经网络,self-attention能帮助当前节点不仅仅只关注当前的词,从而能获取到上下文的语义。
解码器模块:


  • 由N个解码器层堆叠而成
  • 每个解码器层由三个子层连接结构组成
  • 第一个子层连接结构包括一个多头自留意力子层、规范化层和一个残差连接
  • 第二个子层连接结构包括一个多头留意力子层、规范化层和一个残差连接
  • 第三个子层连接结构包括一个前馈全连接子层、规范化层和一个残差连接​​​​​​
      解码器decoder也包罗encoder提到的两层网络,但是在这两层中间还有一层attention层,帮助当前节点获取到当前必要关注的重点内容。
输出模块结构:


  • 线性层
  • softmax层

Transformer 具体是如何工作的?

起首,是对输入进行标识符化,基于单词形式,或字母,或字符子串,将输入文本切分成几个 token,对应到字典中的 ID 上,并对每个 ID 分配一个可学习的权重作为向量表示,之后就可以针对做训练,这是一个可学习的权重。
在输入 Transformer 结构之后,其核心的有自留意力模块和前向传播层。而在自留意力模块中,Transformer 自留意力机制建模能力优于 RNN 序列建模能力。因此,有了 Transformer 架构后,基本上就办理了运行效率和训练很大模子的题目。
Transformer核心思想是什么?

自留意力机制(Self-Attention): 模子能够同时思量输入序列中的全部位置,而不是像传统的固定窗口大小的卷积或循环神经网络一样渐渐处理。 传统的神经网络在处理序列数据时,对每个位置的信息处理是固定的,而自留意力机制允许模子在处理每个位置时关注输入序列的其他部门,从而更好地捕获全局信息。
位置编码(Positional Encoding): 由于Transformer没有显式的次序信息,为了保留输入序列中元素的位置信息,必要添加位置编码。
多头留意力(Multi-Head Attention): 将自留意力机制应用多次,通过多个留意力头来捕获不同的关系。
前馈神经网络(Feedforward Neural Network): 每个留意力子层后接一个前馈神经网络,用于学习非线性关系。
Transformer的成功不仅限于NLP范畴,还在盘算机视觉等范畴取得了重要希望。由于其并行盘算的上风,Transformer已成为深度学习中的经典模子之一,被广泛用于各种任务。
Transformer的代码架构

因为它涉及到自留意力机制、位置编码、多头留意力等多个关键概念。
  1. import torch
  2. import torch.nn as nn
  3. class PositionalEncoding(nn.Module):
  4.     def __init__(self, d_model, max_len=512):
  5.         super(PositionalEncoding, self).__init__()
  6.         self.encoding = torch.zeros(max_len, d_model)
  7.         position = torch.arange(0, max_len).unsqueeze(1).float()
  8.         div_term = torch.exp(torch.arange(0, d_model, 2).float() * -(torch.log(torch.tensor(10000.0)) / d_model))
  9.         self.encoding[:, 0::2] = torch.sin(position * div_term)
  10.         self.encoding[:, 1::2] = torch.cos(position * div_term)
  11.         self.encoding = self.encoding.unsqueeze(0)
  12.         
  13.     def forward(self, x):
  14.         return x + self.encoding[:, :x.size(1)].detach()
  15. class TransformerModel(nn.Module):
  16.     def __init__(self, vocab_size, d_model, nhead, num_encoder_layers, num_decoder_layers):
  17.         super(TransformerModel, self).__init__()
  18.         self.embedding = nn.Embedding(vocab_size, d_model)
  19.         self.positional_encoding = PositionalEncoding(d_model)
  20.         self.transformer = nn.Transformer(d_model, nhead, num_encoder_layers, num_decoder_layers)
  21.         self.fc = nn.Linear(d_model, vocab_size)
  22.         
  23.     def forward(self, src, tgt):
  24.         src = self.embedding(src)
  25.         src = self.positional_encoding(src)
  26.         tgt = self.embedding(tgt)
  27.         tgt = self.positional_encoding(tgt)
  28.         output = self.transformer(src, tgt)
  29.         output = self.fc(output)
  30.         return output
  31. # 定义模型
  32. vocab_size = 10000  # 词汇表大小
  33. d_model = 512  # 模型维度
  34. nhead = 8  # 多头注意力的头数
  35. num_encoder_layers = 6  # 编码器层数
  36. num_decoder_layers = 6  # 解码器层数
  37. model = TransformerModel(vocab_size, d_model, nhead, num_encoder_layers, num_decoder_layers)
  38. # 定义输入
  39. src = torch.randint(0, vocab_size, (10, 32))  # 10个序列,每个序列长度为32
  40. tgt = torch.randint(0, vocab_size, (20, 32))  # 20个序列,每个序列长度为32
  41. # 前向传播
  42. output = model(src, tgt)
复制代码
自留意力机制是什么?

Self Attention
先看例子,下列句子是我们想要翻译的输入句子:
The animal didn’t cross the street because it was too tired
这个“it”在这个句子是指什么呢?它指的是street照旧这个animal呢?这对于人类来说是一个简单的题目,但是对于算法则不是。
当模子处理这个单词“it”的时候,自留意力机制会允许“it”与“animal”建立联系。
随着模子处理输入序列的每个单词,自留意力会关注整个输入序列的全部单词,帮助模子对本单词更好地进行编码。
如果你熟悉RNN(循环神经网络),回忆一下它是如何维持隐蔽层的。RNN会将它已经处理过的前面的全部单词/向量的表示与它正在处理的当前单词/向量联合起来。而自留意力机制会将全部相关单词的明确融入到我们正在处理的单词中
当我们在编码器#5(栈中最上层编码器)中编码“it”这个单词的时,留意力机制的部门会去关注“The Animal”,将它的表示的一部门编入“it”的编码中。


自留意力机制(Self-Attention Mechanism)是Transformer模子的核心组成部门之一,用于处理输入序列中各个位置之间的依赖关系。以下是对自留意力机制的具体解读:
留意力的概念:
留意力机制模拟了人类视觉系统的工作原理,即在处理某个任务时,我们不是对全部信息一视同仁,而是在某个时候关注一部门信息,而另一时候可能关注其他信息。在自留意力机制中,模子通过学习到的权重分配给输入序列中的不同位置,以便在天生输出时更加关注相关的部门。
自留意力机制的基本原理:
Query(查询): 通过将输入序列与权重矩阵相乘,得到每个位置的查询向量。查询向量用于衡量每个位置与其他位置的相关性。
Key(键): 通过将输入序列与权重矩阵相乘,得到每个位置的键向量。键向量用于被查询向量衡量,从而盘算留意力分布。
Value(值): 通过将输入序列与权重矩阵相乘,得到每个位置的值向量。值向量将根据留意力分布加权求和,形成最终的输出。
留意力分布盘算:
盘算相似度: 通过查询向量和键向量的点积,盘算每个位置的相似度得分。
缩放: 为了制止相似度过大导致的梯度消散或梯度爆炸题目,一般会对相似度进行缩放,常用的缩放因子是输入维度的平方根。
Softmax: 对缩放后的相似度应用Softmax函数,得到留意力权重分布。Softmax确保全部权重的总和为1,使其成为有效的概率分布。
留意力加权求和: 将值向量按照得到的留意力权重进行加权求和,得到最终的自留意力输出。
多头留意力(Multi-Head Attention):
为了增强模子的表达能力,自留意力机制通常会使用多个独立的留意力头。每个头学习不同的查询、键、值权重矩阵,最后将多个头的输出拼接在一起并通过线性映射进行融合。
位置编码(Positional Encoding):
自留意力机制没有直接思量序列中元素的次序,为了捕获序列的位置信息,经常会在输入序列中添加位置编码。位置编码是一个与位置有关的可学习参数,使得模子能够更好地处理序列的次序信息。
多头留意力有什么用?


多头留意力机制的引入具有以下几个上风:
多头并行盘算: 不同留意力头可以并行盘算,进步了盘算效率。
学习不同表示: 不同头关注输入序列的不同部门,有助于模子学习更丰富、更复杂的特征表示。
进步模子泛化能力: 多头留意力可以使模子在处理不同类型的信息时更加灵活,进步了模子的泛化能力。
通过这种方式,多头留意力机制在Transformer模子中起到了至关重要的作用,使得模子能够更好地捕获输入序列中的关系,进步了模子的表达能力。
前馈神经网络


前馈神经网络(Feedforward Neural Network)是一种最基本的神经网络结构,也被称为多层感知机(Multilayer Perceptron,MLP)。在深度学习中,前馈神经网络被广泛应用于各种任务,包括图像分类、语音辨认、自然语言处理等。下面是对前馈神经网络的具体解读:
1. 基本结构
前馈神经网络由输入层、隐蔽层和输出层组成。每一层都包罗多个神经元(或称为节点),每个神经元与上一层的全部神经元都有连接,连接上带有权重。每个连接上都有一个权重,表示连接的强度。
输入层(Input Layer): 继承输入特征的层,每个输入特征对应一个输入层神经元。
隐蔽层(Hidden Layer): 在输入层和输出层之间的一层或多层神经元,负责学习输入数据中的复杂模式。
输出层(Output Layer): 提供网络的输出,输出的维度通常与任务的要求相匹配,例如,对于二分类任务,可以有一个输入迷经元表示两个类别的概率。
2. 激活函数
每个神经元在接收到输入后,会通过激活函数进行非线性变换。常用的激活函数包括:
Sigmoid 函数: 将输入映射到范围 ((0, 1)),适用于二分类题目。
Hyperbolic Tangent(tanh)函数: 将输入映射到范围 ((-1, 1)),具有零中心性,有助于减少梯度消散题目。
Rectified Linear Unit(ReLU)函数: 对于正数输入,输出即是输入;对于负数输入,输出为零。ReLU 是如今最常用的激活函数之一。
Softmax 函数: 用于多分类题目的输出层,将输出转化为概率分布。
3. 前向传播
前馈神经网络的训练过程中,信息从输入层传播到输出层的过程称为前向传播。具体步调如下:
输入层接收输入特征。
每个神经元接收来自上一层神经元的输入,盘算加权和。
加权和经过激活函数进行非线性变换,得到每个神经元的输出。
输出传递到下一层作为输入,重复以上步调。
最终,网络的输出被用于任务的预测。

编码器+解码器
编码器-解码器结构是深度学习中常用的一种网络架构,特别在图像分割和天生任务中得到广泛应用。以下是对编码器-解码器结构的具体解读:
编码器(Encoder)


特征提取: 编码器的主要作用是从输入数据中提取关键特征。对于图像任务,输入通常是图像,编码器通过一系列卷积层(Convolutional Layers)进行特征提取。这些卷积层可以捕获图像中的低级别和高级别特征,例如边沿、纹理和对象形状。
降维: 随着网络深度的增加,编码器通常会进行降维操作,通过池化层(Pooling Layers)或步幅较大的卷积层减小特征图的尺寸。这有助于减少盘算复杂性和内存需求,并进步网络对输入的抽象表示能力。
语义信息提取: 在编码器的高层级特征表示中,网络通常能够捕获到更抽象的语义信息,例如图像中的物体类别、结构等。这些特征通常被称为“语义特征”。
解码器(Decoder):


上采样: 解码器负责将编码器提取的特征映射还原为输入数据的尺寸。这通常涉及到上采样操作,其中通过插值或反卷积操作将特征图的尺寸放大。
特征融合: 解码器通常必要与编码器的相应层进行特征融合,以保留从输入到编码器的条理结构中学到的语义信息。这可以通过连接编码器息争码器的相应层来实现,形成所谓的“跳跃连接”(Skip Connections)。
重建输出: 解码器的最终目的是天生与输入数据相匹配的输出。对于图像分割任务,输出通常是一个与输入图像尺寸雷同的特征图,其中每个像素或区域对应一个类别的概率或标签。
基于卷积神经网络(CNN)的编码器-解码器结构

  1. import torch
  2. import torch.nn as nn
  3. class EncoderDecoder(nn.Module):
  4.     def __init__(self):
  5.         super(EncoderDecoder, self).__init__()
  6.         
  7.         # 编码器部分
  8.         self.encoder = nn.Sequential(
  9.             nn.Conv2d(3, 64, kernel_size=3, padding=1),
  10.             nn.ReLU(inplace=True),
  11.             nn.MaxPool2d(kernel_size=2, stride=2),
  12.             nn.Conv2d(64, 128, kernel_size=3, padding=1),
  13.             nn.ReLU(inplace=True),
  14.             nn.MaxPool2d(kernel_size=2, stride=2)
  15.             # 添加更多卷积层和池化层...
  16.         )
  17.         
  18.         # 解码器部分
  19.         self.decoder = nn.Sequential(
  20.             # 添加上采样层和特征融合...
  21.             nn.Conv2d(128, 64, kernel_size=3, padding=1),
  22.             nn.ReLU(inplace=True),
  23.             nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False),
  24.             nn.Conv2d(64, 32, kernel_size=3, padding=1),
  25.             nn.ReLU(inplace=True),
  26.             nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False),
  27.             nn.Conv2d(32, 1, kernel_size=3, padding=1),
  28.             nn.Sigmoid()  # 用于二分类任务时添加Sigmoid激活函数
  29.         )
  30.     def forward(self, x):
  31.         # 编码器前向传播
  32.         x = self.encoder(x)
  33.         
  34.         # 解码器前向传播
  35.         x = self.decoder(x)
  36.         
  37.         return x
  38. # 创建模型实例
  39. model = EncoderDecoder()
  40. # 打印模型结构
  41. print(model)
复制代码
编码器息争码器的结构可能会更加复杂,具体的设计取决于任务的要求和数据集的特点。上述代码中使用的是PyTorch的简单卷积层、池化层和上采样层,实际场景中可能必要更深的网络结构和更复杂的组件。
基于Transformer架构的主流语言模子有哪些?

一是,自编码模子,如 BERT,简单讲就是给到一句话,然后把这句话的内容挖空,当问及挖空的内容时,就把内容填回去,这其实是典范地用来做一个自然语言明确的任务,但做天生任务黑白常弱的;
二是,自回归模子,如 GPT,它是通过不断地预测下一个词,特点是只能从左到右天生,而看不到背面的内容。GPT-1 最后接了一个 Linear 层做分类或选题题等任务,到了 GPT-2 ,已经将一些选择任务或者分类任务全部都变成文本任务,统一了天生的范式;
三是,编码器-解码器模子,如 T5,它的输入和输出是分为比力显着的两块内容,或者是问答式,或者序列到序列的转换型的任务;
四是,通用语言模子,如 GLM,该模子联合了自回归和自编码两种形式的模子,举个例子,“123456”是一串输入的序列,如今把 “3”、“5”、“6” 挖空,让模子去学习,那么,挖空以后换成一个 “ mask token” 告诉模子这个地方遮掉了一些内容,如今必要去预测出来遮掉的内容。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万万哇

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表