当前位置:   article > 正文

1、什么是Transformer_transformer编码器层

transformer编码器层

目录

Transformer 架构概览

编码器层(Encoder Layer)

解码器层(Decoder Layer)

注意力机制

自注意力(Self-Attention)

多头注意力(Multi-Head Attention)

为什么使用LayerNorm

为什么使用多头注意力机制


Transformer的原理是基于自注意力机制(Self-Attention),该机制可以直接计算序列中各个位置之间的依赖关系。与传统的循环神经网络(RNN)和长短期记忆网络(LSTM)不同,Transformer完全依赖注意力机制,没有使用循环结构。这允许模型并行处理整个序列的数据。

Transformer 架构概览

Transformer 模型由编码器(Encoder)和解码器(Decoder)两部分组成,每部分由若干个相同的层叠加而成。

编码器层(Encoder Layer)

每个编码器层包括两个子层:

  1. 多头自注意力(Multi-Head Self-Attention):允许模型同时关注序列中的不同位置,并计算序列中不同单词之间的相互影响。
  2. 前馈神经网络(Feed-Forward Neural Network):对自注意力层的输出进行进一步的处理。

这两个子层都有残差连接,并且其输出通过层归一化(Layer Normalization)。

解码器层(Decoder Layer)

每个解码器层也包括三个子层:

  1. 遮蔽多头自注意力(Masked Multi-Head Self-Attention):与编码器的自注意力相似,但在处理解码器输入时,为了防止位置 i 获取未来位置 j(i < j)的信息,需要加入一个掩码(Mask)。
  2. 编码器-解码器注意力:用于让解码器关注编码器的输出。
  3. 前馈神经网络:与编码器中的前馈网络相同。

解码器每层的这三个子层也都有残差连接,并且其输出通过层归一化。

注意力机制

自注意力(Self-Attention)

自注意力机制的关键是以下三个向量:

  • Queries(Q)
  • Keys(K)
  • Values(V)

        对于给定的输入 X,我们首先将其映射到 Q、K、V 三个向量上。然后,计算 Q 与 K 的点积,得到注意力权重,接着对该权重进行 softmax 操作,最后用这个 softmax 权重与 V 相乘得到最终的输出。

多头注意力(Multi-Head Attention)

Transformer 使用了多头注意力机制,将 Q、K、V 映射到不同的表示空间,计算多组注意力,并将这些注意力的结果拼接起来,最后再次映射得到最终的输出。

  1. import torch
  2. import torch.nn as nn
  3. class SelfAttention(nn.Module):
  4. def __init__(self, d_model, num_heads, mask=True, scale=True):
  5. super(SelfAttention, self).__init__()
  6. self.num_heads = num_heads
  7. self.d_model = d_model
  8. self.d_k = d_model // num_heads
  9. self.mask = mask
  10. self.scale = scale
  11. self.q_linear = nn.Linear(d_model, d_model)
  12. self.k_linear = nn.Linear(d_model, d_model)
  13. self.v_linear = nn.Linear(d_model, d_model)
  14. self.out_linear = nn.Linear(d_model, d_model)
  15. def forward(self, x):
  16. batch_size, seq_len, _ = x.size()
  17. # 线性变换,通过线性层对输入进行变换,得到查询(Q)、键(K)和值(V)的表示。
  18. q = self.q_linear(x)
  19. k = self.k_linear(x)
  20. v = self.v_linear(x)
  21. # 多头分割和转置,将查询、键和值进行多头分割,并进行维度的转置操作。
  22. q = q.view(batch_size, seq_len, self.num_heads, self.d_k)
  23. k = k.view(batch_size, seq_len, self.num_heads, self.d_k)
  24. v = v.view(batch_size, seq_len, self.num_heads, self.d_k)
  25. q = q.permute(2, 0, 1, 3).contiguous().view(-1, seq_len, self.d_k)
  26. k = k.permute(2, 0, 1, 3).contiguous().view(-1, seq_len, self.d_k)
  27. v = v.permute(2, 0, 1, 3).contiguous().view(-1, seq_len, self.d_k)
  28. # 注意力得分计算
  29. scores = torch.matmul(q, k.transpose(1, 2))
  30. if self.scale:
  31. scores = scores / torch.sqrt(torch.tensor(self.d_k).float())
  32. # 掩码处理
  33. if self.mask:
  34. mask = torch.triu(torch.ones(seq_len, seq_len), diagonal=1)
  35. mask = mask.unsqueeze(0).unsqueeze(0).to(x.device)
  36. scores = scores.masked_fill(mask == 0, float('-inf'))
  37. # 注意力权重计算
  38. attention_weights = torch.softmax(scores, dim=-1)
  39. attention_output = torch.matmul(attention_weights, v)
  40. # 多头拼接和转置
  41. attention_output = attention_output.view(self.num_heads, batch_size, seq_len, self.d_k)
  42. attention_output = attention_output.permute(1, 2, 0, 3).contiguous().view(batch_size, seq_len, -1)
  43. # 线性变换
  44. output = self.out_linear(attention_output)
  45. return output

在自注意力机制中,mask和scale是重要的步骤。Masking用于避免在注意力计算中不必要或者不合适的信息流,而scale(缩放)则是用来稳定训练过程。

  1. Masking

    在序列生成任务中(如语言模型或者机器翻译中的解码器),mask用来确保模型不会看到未来的信息。这通常通过将注意力权重矩阵中对应于未来位置的条目设置为非常小的负数(例如,-1e9)来实现。这在softmax之前完成,所以这些位置的权重在softmax后趋近于0。在处理填充(padding)的序列时,mask也用于忽略填充的位置,从而不影响注意力权重的计算。
  2. Scale(缩放)

    缩放的目的是为了控制内积的大小,防止过大的内积值使得softmax函数的梯度几乎为0,从而导致梯度消失问题。缩放操作通常是在计算注意力权重之前,将内积除以一个缩放因子,这个因子通常是embed_size的平方根。

为什么使用LayerNorm

在Transformer模型中使用LayerNorm而不使用其他归一化方法,如BatchNorm,主要由以下原因:

  1. 独立性: LayerNorm在每一个样本内对所有的特征进行归一化,而不像BatchNorm那样依赖于一个batch中的其他样本。这样的特性使得LayerNorm在处理不同长度的输入序列时更加灵活,因为序列处理任务中的批次中每个样本的长度可能不同。

  2. 批次大小不敏感: 由于LayerNorm不依赖于批次维度,它对批次大小不敏感。这意味着即使在批次大小为1时也可以正常工作,这对于在线学习、强化学习或者资源受限的情况很有用。

  3. 便于并行计算: 在Transformer模型中,自注意力层允许并行处理整个序列。使用LayerNorm而不是BatchNorm可以确保模型中每个时间步的归一化操作是独立的,这使得整个模型更适合并行计算。

  4. 序列处理适用性: LayerNorm特别适用于序列处理任务,因为它在每个时间步独立处理激活值。对于序列数据,尤其是当序列长度变化或者模型需要记住长距离依赖时,LayerNorm更有优势。

  5. 计算稳定性: LayerNorm可以减少训练过程中的梯度消失和梯度爆炸问题,这对于训练深度网络尤其重要。在Transformer中,由于存在大量的残差连接和自注意力操作,维持梯度的稳定性是非常关键的。

  6. 避免潜在的批次效应: BatchNorm可能会引入批次之间的相互依赖,这可能导致模型在训练时与实际应用时表现不一致,特别是当实际应用中的批次大小不同或者数据分布有变化时。LayerNorm避免了这些问题。

为什么使用多头注意力机制

多头注意力机制(Multi-Head Attention)是Transformer模型中的一个关键创新。它允许模型在不同的表示子空间中并行地学习信息。以下是使用多头注意力机制的主要原因和优势:

  1. 捕捉不同子空间的信息: 每个“头”可以被看作是一个独立的注意力学习机制,该机制关注输入的不同部分并从不同的角度解读信息。这样可以让模型捕捉到更加丰富和多样化的信息。

  2. 提高表示能力: 各个头学习到的注意力表示被合并起来,提供了一个综合的表示,这可能比任何单个头学到的表示包含更多信息,从而增强了模型的表示能力。

  3. 并行计算: 多头注意力可以并行计算各个头,这样在训练和推断时可以显著提高效率,尤其是在使用现代硬件(如GPU或TPU)时。

  4. 模型稳健性: 多头注意力使模型更加稳健,因为即使一些头可能学习到不太有用的信息,其他头仍然可以学习到有价值的特征。这种多元化的学习策略提高了模型的泛化能力。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号