transformer 各个部分主要内容

部署运行你感兴趣的模型镜像

自注意力详解:

  1. 预处理:将数据输入进行嵌入, 得到嵌入向量
  2. 获取三个向量:嵌入向量 与 三个矩阵(训练中的出来的) 相乘 分别得到 query 向量、key 向量、value 向量。如图1
  3. 分数计算:将当前位置的 query 向量 与各个位置的 key 向量 进行相乘得到。表示当前位置单词与其他单词的相关程度。如图2
  4. 分数处理: 将分数除以  (key向量维数的平方根), 然后进行softmax 。这个分数表示其他单词在这个位置的表达量。如图3
  5. 注意力的体现:如何体现注意力呢,将 value 向量分别乘上(或加上)softmax 分数。主要是为了增大对需要关注的词的关注度,减少无关词的关注度。
  6. 获取输出:对上一步的 所有单词的 结果进行加权求和 作为在当前位置的单词的输出。如图4

 

图1

 

 

图2

 

 

图3
​​

 

 

图4

 

矩阵方式进行运算可以将上面的步骤压缩两步即可:

  1. 首先获取三个向量矩阵,也即将嵌入后的向量 和 三个权重矩阵进行相乘 得到三个 矩阵  Q 、K、V
  2. 然后根据数学公式完成后面的步骤:

 注意:权重矩阵 刚开始是随机初始化的

 

所谓多头自注意力:

就是 上面的的 自注意力有N个 在transformer 中默认是8个 ,也就是说 一层中有八组 q k v 权重矩阵。那么为什么要用多头呢? 此处先留个位置。。。。

有了八组 权重矩阵 ,在随机初始化后 进行训练,得到对应的权重矩阵各个  嵌入向量 经过输入 到对应的每一组自注意力 流程里面 会产生对应的Z0 Z1 Z2 ...  也就是各个的一个分数值。那么怎么样像是用单个头一样 输入到前馈神经网络层呢?这里的做法是将这8组 产生的结果进行连接 ,然后经过另外一个权重矩阵 转换成 对用维度的 Z ,再次输入到 前馈层。这里的另一个权重矩阵也是 在训练中不断的调整参数的。这个过程如图5,6

图5

 

 

图6

 

 

另一个重要的点:位置编码

为什么要进行位置编码呢 ? 是为了吧位置信息引入到 模型中,使得上面的一些权重矩阵可以学习到 相对的特征。

怎么引入位置编码呢?位置编码的模式又是怎样呢?

首先第一个,怎么引入,transformer模型中是直接对于每一个经过嵌入的 嵌入向量 加上一个 位置向量。这个位置向量是每一个词都有的,如图7。它是怎么来的呢,看下面

第二个就是 编码模式是怎样的,为了使得向量可以相加,对于单个词的位置向量的维度是512 维的 也就是说要和 嵌入向量维度相同。然后编码的话是经过正弦余弦得到对应的位置向量的。如图8, 是20个词的位置编码,前半部分是正弦获取的值,后半部分是余弦获取的值,连在一起就是位置向量了。当然这不是唯一的编码方式,这种好处就是可以编码很(超)长的位置。

 

图7

 

 

图8

 

残差:

这是 transformer 结构中的另外一个细节地方,残差的操作在每一个子层都有,也就是 自注意力层和前馈层中,同时是结合了normalize 同时进行的。是在 进行 自注意力操作之前 的向量 和 之后的向量相加 然后进行normalize操作。在前馈层同样也是这样的,如图9

图9

值得注意的是运用在 解码器层的时候 ,这种思想是在 进行 encode-decoder attention 之前和之后,同样也进行了残差 和normalize 操作,如图10 ,也就是decoder#1  和decoder#2 分别表示 之前和之后,然后像上边那样进行残差和normalize

 

图10

 

 前面是主要讲了一些基本的操作,那么最主要的就是 怎么进行decode呢?

解码过程

主要是 : 每一个时间步骤都通过 编码器的输出得到一个词,并且在得到输出的词之后,在下一个时间步将这个词 喂入到解码器进行嵌入、位置编码、自注意力并且和 编码输出同时进行注意力操作,接着流经前馈神经网络层,最终输出这个时间步的词。以此循环,直到产生特殊的结束符号表示 输出已经完成,也就是这句话翻译完了。如图11 12

 

 

图11

好像是图片太大,这里上传不到csdn服务器,这里直接放一个图片链接

https://jalammar.github.io/images/t/transformer_decoding_2.gif

  https://jalammar.github.io/images/t/transformer_decoding_2.gif

 下面是小尺寸的图,防止外链失效

图12

 注意:The “Encoder-Decoder Attention” layer works just like multiheaded self-attention, except it creates its Queries matrix from the layer below it, and takes the Keys and Values matrix from the output of the encoder stack.

 

接下来就是比较关键的步骤了,怎么把 decoder 出来的内容,转换成人类可读的词语。

 

线性回归和柔性最大值回归层。(翻译成对应的词)

作用是什么呢,线性层就是一个全连接层,将decoder出来的向量 映射到 一个词表大小的逻辑向量这里的每一个值都表示这个单词的分数。 接下来就是 softmax 层了,这个是将这个分数转换成概率,也就是词的概率,然后呢从这些单元中选择最大概率的,并且找到对应的词,这也就是解码出了输出的词。

如下图13

图13

 

上面就是transformer的一些关键的地方了,有些地方只是说了怎么做的,具体做法的原因有些还不太清楚,欢迎有想法的同学一起讨论!vx : hpulfc

说的不够详细?没关系,原链接:

您可能感兴趣的与本文相关的镜像

TensorFlow-v2.9

TensorFlow-v2.9

TensorFlow

TensorFlow 是由Google Brain 团队开发的开源机器学习框架,广泛应用于深度学习研究和生产环境。 它提供了一个灵活的平台,用于构建和训练各种机器学习模型

Transformer结构主要包含以下几个部分及其对应的中文名称: ### 输入部分 - **Input Embedding**:输入嵌入层。它的作用是将输入的离散符号(如单词)转换为连续的向量表示,方便后续神经网络处理。 - **Positional Encoding**:位置编码。由于Transformer模型本身没有像循环神经网络(RNN)那样的顺序信息处理能力,位置编码用于为输入序列中的每个位置添加位置信息,让模型能够感知序列中元素的相对位置。 ### 编码器(Encoder)部分 - **Multi - Head Attention**:多头注意力机制。它是Transformer的核心组件之一,通过多个不同的注意力头并行地计算注意力,使得模型能够从不同的表示子空间中捕捉输入序列元素之间的依赖关系。 - **Layer Normalization**:层归一化。用于对神经网络层的输入进行归一化处理,加速模型的训练过程,提高模型的稳定性。 - **Feed - Forward Network**:前馈神经网络。通常由两个线性变换和一个非线性激活函数(如ReLU)组成,对多头注意力机制的输出进行进一步的特征变换。 ### 解码器(Decoder)部分 - **Masked Multi - Head Attention**:掩码多头注意力机制。与多头注意力机制类似,但在计算注意力分数时,会对未来的位置进行掩码操作,确保在生成当前位置的输出时,模型不会看到未来的信息,符合序列生成的因果性要求。 - **Encoder - Decoder Attention**:编码器 - 解码器注意力机制。用于解码器在生成输出时,能够关注编码器的输出信息,从而将输入序列的信息融入到输出序列的生成过程中。 ### 输出部分 - **Linear Layer**:线性层。将解码器的输出进行线性变换,将其映射到目标词汇表的维度。 - **Softmax Function**:Softmax函数。将线性层的输出转换为概率分布,用于预测每个词汇的生成概率。 ```python # 这里简单示意一个Transformer中多头注意力机制的部分代码框架 import torch import torch.nn as nn class MultiHeadAttention(nn.Module): def __init__(self, num_heads, d_model): super(MultiHeadAttention, self).__init__() self.num_heads = num_heads self.d_model = d_model self.d_k = d_model // num_heads self.W_q = nn.Linear(d_model, d_model) self.W_k = nn.Linear(d_model, d_model) self.W_v = nn.Linear(d_model, d_model) self.W_o = nn.Linear(d_model, d_model) def forward(self, Q, K, V, mask=None): batch_size = Q.size(0) Q = self.W_q(Q).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2) K = self.W_k(K).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2) V = self.W_v(V).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2) scores = torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(torch.tensor(self.d_k, dtype=torch.float32)) if mask is not None: scores = scores.masked_fill(mask == 0, -1e9) attention = torch.softmax(scores, dim=-1) output = torch.matmul(attention, V) output = output.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model) output = self.W_o(output) return output ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值