问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

从零理解Transformer架构:注意力机制与位置编码

创作时间:
作者:
@小白创作中心

从零理解Transformer架构:注意力机制与位置编码

引用
CSDN
1.
https://m.blog.csdn.net/sjdgehi/article/details/146230986

Transformer架构自2017年提出以来,已成为自然语言处理和深度学习领域的基石。其核心创新是使用注意力机制,完全抛弃了传统的卷积神经网络(CNN)和循环神经网络(RNN)。本文将从零开始解析Transformer架构,重点介绍其中的注意力机制与位置编码,并附带PyTorch代码实现。

一、Transformer架构概览

Transformer是由Encoder和Decoder两部分组成,通常用于序列到序列的任务,如机器翻译、文本生成等。Transformer的核心思想是通过自注意力机制(Self-Attention)来捕捉输入序列中的全局依赖关系,而不是像传统RNN那样顺序地处理信息。

1.1 Encoder-Decoder结构

Transformer架构可以简化为两大模块:

  • Encoder:负责对输入序列进行编码,产生对输入数据的理解。
  • Decoder:基于Encoder的输出,生成目标序列。

每个Encoder和Decoder都是由多个相同的子层(Layer)堆叠而成。每个Encoder层包括:

  1. 自注意力层(Self-Attention)
  2. 前馈神经网络(Feed-Forward Neural Network)
  3. 残差连接和层归一化

每个Decoder层与Encoder层类似,但是它还包括一个额外的跨注意力层(Cross-Attention),用于从Encoder的输出中获取信息。

二、注意力机制

在Transformer中,最关键的技术是注意力机制(Attention Mechanism)。传统的RNN是通过递归计算逐步更新信息的,而注意力机制则通过“赋予”每个输入元素不同的权重,使得模型能够灵活地关注输入序列中的重要部分。这种方法能够高效地并行化计算并更好地捕捉长程依赖。

2.1 注意力机制的原理

注意力机制的核心思想是:对于每一个输入的单元(如单词、词向量),我们都要计算它与其他输入单元的相似度,然后基于相似度加权求和,从而得到该单元的“注意力”向量。

常见的注意力计算方法是Scaled Dot-Product Attention,其计算公式为:

其中:

  • QQ:查询(Query)矩阵
  • KK:键(Key)矩阵
  • VV:值(Value)矩阵
  • dkdk :键的维度,作为缩放因子

2.2 计算过程

  1. 计算相似度:通过点积计算查询向量QQ与键向量KK的相似度。
  2. 缩放:通过除以dkdk 进行缩放,避免点积值过大。
  3. 应用Softmax:对相似度结果进行Softmax归一化,得到每个值的权重。
  4. 加权求和:用这些权重对值VV进行加权求和,得到输出。

2.3 PyTorch代码实现

import torch
import torch.nn.functional as F

def scaled_dot_product_attention(Q, K, V):
    # 计算相似度
    matmul_qk = torch.matmul(Q, K.transpose(-2, -1))
    
    # 缩放相似度
    d_k = Q.size(-1)
    scaled_attention_logits = matmul_qk / torch.sqrt(torch.tensor(d_k, dtype=torch.float32))
    
    # 应用Softmax
    attention_weights = F.softmax(scaled_attention_logits, dim=-1)
    
    # 加权求和
    output = torch.matmul(attention_weights, V)
    
    return output, attention_weights

# 示例数据
Q = torch.randn(1, 5, 64)  # 查询向量
K = torch.randn(1, 5, 64)  # 键向量
V = torch.randn(1, 5, 64)  # 值向量
output, attention_weights = scaled_dot_product_attention(Q, K, V)
print("Output Shape:", output.shape)
print("Attention Weights Shape:", attention_weights.shape)

在此代码中,Q、K和V分别是查询、键和值的矩阵,scaled_dot_product_attention函数实现了注意力机制的计算。

三、位置编码(Positional Encoding)

由于Transformer完全基于自注意力机制,输入的序列数据没有显式的顺序信息,因此需要引入位置编码来为每个单词(或词向量)添加位置信息。位置编码通过向每个词的表示中加入一个特定的向量,使得模型能够区分单词在句子中的顺序。

3.1 位置编码的数学公式

位置编码通常采用正弦和余弦函数来生成,这些函数的频率随着维度的增加而变化。公式为:

其中:

  • pospos:表示单词在句子中的位置
  • ii:位置编码向量中的维度索引
  • dmodeldmodel :词向量的维度

3.2 位置编码的作用

位置编码为每个位置生成唯一的向量,并将其加到输入的嵌入向量中。通过这种方式,Transformer能够区分不同位置的词语,同时保持序列中的顺序信息。

3.3 PyTorch代码实现

import numpy as np

def positional_encoding(seq_len, d_model):
    pe = np.zeros((seq_len, d_model))
    position = np.arange(0, seq_len).reshape(-1, 1)
    div_term = np.exp(np.arange(0, d_model, 2) * -(np.log(10000.0) / d_model))
    
    pe[:, 0::2] = np.sin(position * div_term)  # 偶数维度
    pe[:, 1::2] = np.cos(position * div_term)  # 奇数维度
    
    return torch.tensor(pe, dtype=torch.float32)

# 示例:生成一个长度为10,维度为512的位置编码
seq_len = 10
d_model = 512
pe = positional_encoding(seq_len, d_model)
print(pe.shape)

这段代码生成了一个形状为seq_len×d_modelseq_len×d_model的矩阵,其中每一行是一个位置的编码。

四、Transformer层的实现

4.1 Encoder层

一个标准的Encoder层由以下几个主要组件组成:

  1. 自注意力机制(Self-Attention)
  2. 前馈神经网络(Feed Forward Network)
  3. 残差连接和层归一化(Residual Connection & Layer Normalization)

Encoder层的计算顺序是:

  1. 输入首先通过自注意力机制。
  2. 经过前馈神经网络处理。
  3. 在每个子层之间有残差连接,并进行层归一化。

4.2 PyTorch代码实现

class TransformerEncoderLayer(torch.nn.Module):
    def __init__(self, d_model, n_heads, ff_hidden_dim):
        super(TransformerEncoderLayer, self).__init__()
        self.self_attention = torch.nn.MultiheadAttention(d_model, n_heads)
        self.feed_forward = torch.nn.Sequential(
            torch.nn.Linear(d_model, ff_hidden_dim),
            torch.nn.ReLU(),
            torch.nn.Linear(ff_hidden_dim, d_model)
        )
        self.layer_norm1 = torch.nn.LayerNorm(d_model)
        self.layer_norm2 = torch.nn.LayerNorm(d_model)
        self.dropout = torch.nn.Dropout(0.1)
    
    def forward(self, x):
        # 自注意力层
        attention_output, _ = self.self_attention(x, x, x)
        x = self.layer_norm1(x + self.dropout(attention_output))  # 残差连接 + 层归一化
        
        # 前馈神经网络
        ff_output = self.feed_forward(x)
        x = self.layer_norm2(x + self.dropout(ff_output))  # 残差连接 + 层归一化
        
        return x

# 示例:初始化一个Encoder层
encoder_layer = TransformerEncoderLayer(d_model=512, n_heads=8, ff_hidden_dim=2048)
input_tensor = torch.randn(10, 32, 512)  # (seq_len, batch_size, d_model)
output = encoder_layer(input_tensor)
print(output.shape)  # 输出形状

五、总结

本文深入解析了Transformer架构的核心机制——注意力机制位置编码。通过具体的数学公式与PyTorch代码实现,帮助理解Transformer如何通过自注意力机制来捕捉序列中的长程依赖,同时通过位置编码来补充顺序信息。希望通过这篇文章,读者能够对Transformer的内部工作原理有更深入的了解,并能够动手实现自己的Transformer模型。

在实际应用中,Transformer已经被广泛应用于自然语言处理、图像生成等领域,成为现代深度学习模型的基础架构之一。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号