仅仅使用pytorch来手撕transformer架构3编码器模块和编码器类的实现和向前传播
仅仅使用pytorch来手撕transformer架构(3):编码器模块和编码器类的实现和向前传播
仅仅使用pytorch来手撕transformer架构(2):编码器模块和编码器类的实现和向前传播
往期文章:
# Transformer 编码器模块
class TransformerBlock(nn.Module):
def __init__(self, embed_size, heads, dropout, forward_expansion):
super(TransformerBlock, self).__init__()
self.attention = MultiHeadAttention(embed_size, heads)
self.norm1 = nn.LayerNorm(embed_size)
self.norm2 = nn.LayerNorm(embed_size)
self.feed_forward = nn.Sequential(
nn.Linear(embed_size, forward_expansion * embed_size),
nn.ReLU(),
nn.Linear(forward_expansion * embed_size, embed_size),
)
self.dropout = nn.Dropout(dropout)
def forward(self, value, key, query, mask):
attention = self.attention(value, key, query, mask)
x = self.dropout(self.norm1(attention + query))
forward = self.feed_forward(x)
out = self.dropout(self.norm2(forward + x))
return out
# 编码器
class Encoder(nn.Module):
def __init__(self, src_vocab_size, embed_size, num_layers, heads, device, forward_expansion, dropout, max_length):
super(Encoder, self).__init__()
self.embed_size = embed_size
self.device = device
self.word_embedding = nn.Embedding(src_vocab_size, embed_size)
self.position_embedding = PositionalEncoding(embed_size, dropout, max_length)
self.layers = nn.ModuleList(
[
TransformerBlock(
embed_size,
heads,
dropout=dropout,
forward_expansion=forward_expansion,
)
for _ in range(num_layers)
]
)
self.dropout = nn.Dropout(dropout)
def forward(self, x, mask):
N, seq_length = x.shape
x = self.dropout(self.position_embedding(self.word_embedding(x)))
for layer in self.layers:
x = layer(x, x, x, mask)
return x
1.编码器模块的实现
这段代码实现了一个Transformer编码器模块(Transformer Block),它是Transformer架构的核心组件之一。Transformer架构是一种基于自注意力机制(Self-Attention)的深度学习模型,广泛应用于自然语言处理(NLP)任务,如机器翻译、文本生成等。以下是对代码的详细解释:
1.1 类定义
class TransformerBlock(nn.Module):
TransformerBlock
是一个继承自 PyTorch 的
nn.Module
的类,表示一个Transformer编码器模块。
nn.Module
是 PyTorch 中所有神经网络模块的基类,用于定义和管理神经网络的结构。
2.2 初始化方法
def __init__(self, embed_size, heads, dropout, forward_expansion):
super(TransformerBlock, self).__init__()
self.attention = MultiHeadAttention(embed_size, heads)
self.norm1 = nn.LayerNorm(embed_size)
self.norm2 = nn.LayerNorm(embed_size)
self.feed_forward = nn.Sequential(
nn.Linear(embed_size, forward_expansion * embed_size),
nn.ReLU(),
nn.Linear(forward_expansion * embed_size, embed_size),
)
self.dropout = nn.Dropout(dropout)
参数解释
embed_size
- 嵌入向量的维度,表示每个词或标记(token)的特征维度。
heads
- 多头注意力机制中的头数(
Multi-Head Attention
)。
dropout
- Dropout比率,用于防止过拟合。
forward_expansion
- 前馈网络(Feed-Forward Network, FFN)中隐藏层的扩展因子。
组件解释
多头注意力机制(
MultiHeadAttention
)self.attention = MultiHeadAttention(embed_size, heads)
这是Transformer的核心部分,实现了多头注意力机制。它允许模型在不同的表示子空间中学习信息。
MultiHeadAttention
的具体实现没有在这段代码中给出,但通常它会将输入分为多个“头”,分别计算注意力权重,然后将结果拼接起来。层归一化(
LayerNorm
)self.norm1 = nn.LayerNorm(embed_size) self.norm2 = nn.LayerNorm(embed_size)
层归一化(Layer Normalization)是一种归一化方法,用于稳定训练过程并加速收敛。它对每个样本的特征进行归一化,而不是像批量归一化(Batch Normalization)那样对整个批次进行归一化。
前馈网络(
Feed-Forward Network
)self.feed_forward = nn.Sequential( nn.Linear(embed_size, forward_expansion * embed_size), nn.ReLU(), nn.Linear(forward_expansion * embed_size, embed_size), )
前馈网络是一个简单的两层全连接网络。它的作用是进一步处理多头注意力机制的输出。
forward_expansion
参数控制隐藏层的大小,通常设置为一个较大的值(如4),表示隐藏层的维度是输入维度的4倍。Dropout
self.dropout = nn.Dropout(dropout)
Dropout 是一种正则化技术,通过随机丢弃一部分神经元的输出来防止过拟合。
dropout
参数表示丢弃的概率。
3. 前向传播方法
def forward(self, value, key, query, mask):
attention = self.attention(value, key, query, mask)
x = self.dropout(self.norm1(attention + query))
forward = self.feed_forward(x)
out = self.dropout(self.norm2(forward + x))
return out
参数解释
value
- 值向量,用于计算注意力权重后的加权求和。
key
- 键向量,用于计算注意力权重。
query
- 查询向量,用于计算注意力权重。
mask
- 掩码,用于防止某些位置的信息泄露(如在自注意力中屏蔽未来信息)。
流程解释
多头注意力
attention = self.attention(value, key, query, mask)
首先,使用多头注意力机制计算注意力输出。
value
、key
和query
是输入的三个部分,mask
用于控制哪些位置的信息可以被关注。残差连接与层归一化
x = self.dropout(self.norm1(attention + query))
将注意力输出与输入的
query
进行残差连接(attention + query
),然后通过层归一化(LayerNorm
)。最后,应用 Dropout 防止过拟合。前馈网络
forward = self.feed_forward(x)
将经过归一化的输出传递到前馈网络中进行进一步处理。
第二次残差连接与层归一化
out = self.dropout(self.norm2(forward + x))
将前馈网络的输出与之前的输出
x
进行残差连接,再次通过层归一化和 Dropout。返回结果
return out
最终返回处理后的输出。
4. 总结
Transformer编码器模块,其核心包括:
- 多头注意力机制(
MultiHeadAttention
)。 - 残差连接(Residual Connection)。
- 层归一化(
LayerNorm
)。 - 前馈网络(
Feed-Forward Network
)。 - Dropout 正则化。
这些组件共同作用,使得Transformer能够高效地处理序列数据,并在许多NLP任务中取得了优异的性能。
2.编码器的实现
这段代码定义了一个完整的 Transformer 编码器(Encoder) ,它是 Transformer 架构中的一个重要组成部分。编码器的作用是将输入序列(如源语言文本)转换为上下文表示,这些表示可以被解码器(Decoder)用于生成目标序列(如目标语言文本)。以下是对代码的详细解释:
1. 类定义
class Encoder(nn.Module):
Encoder
是一个继承自 PyTorch 的
nn.Module
的类,用于定义 Transformer 编码器的结构。
nn.Module
是 PyTorch 中所有神经网络模块的基类,用于定义和管理神经网络的结构。
2. 初始化方法
def __init__(self, src_vocab_size, embed_size, num_layers, heads, device, forward_expansion, dropout, max_length):
super(Encoder, self).__init__()
self.embed_size = embed_size
self.device = device
self.word_embedding = nn.Embedding(src_vocab_size, embed_size)
self.position_embedding = PositionalEncoding(embed_size, dropout, max_length)
self.layers = nn.ModuleList(
[
TransformerBlock(
embed_size,
heads,
dropout=dropout,
forward_expansion=forward_expansion,
)
for _ in range(num_layers)
]
)
self.dropout = nn.Dropout(dropout)
参数解释
src_vocab_size
- 源语言词汇表的大小,即输入序列中可能的标记(token)数量。
embed_size
- 嵌入向量的维度,表示每个词或标记的特征维度。
num_layers
- 编码器中 Transformer 块(
TransformerBlock
)的数量。
heads
- 多头注意力机制中的头数。
device
- 运行设备(如 CPU 或 GPU)。
forward_expansion
- 前馈网络(FFN)中隐藏层的扩展因子。
dropout
- Dropout 比率,用于防止过拟合。
max_length
- 输入序列的最大长度,用于位置编码。
组件解释
词嵌入(
word_embedding
)self.word_embedding = nn.Embedding(src_vocab_size, embed_size)
词嵌入层将输入的标记(token)索引映射为固定维度的嵌入向量。
src_vocab_size
是词汇表的大小,embed_size
是嵌入向量的维度。位置编码(
position_embedding
)self.position_embedding = PositionalEncoding(embed_size, dropout, max_length)
位置编码层用于为每个标记添加位置信息,使得模型能够捕捉序列中的顺序关系。
PositionalEncoding
的具体实现没有在这段代码中给出,但通常它会根据标记的位置生成一个固定维度的向量,并将其与词嵌入相加。Transformer 块(
TransformerBlock
)self.layers = nn.ModuleList( [ TransformerBlock( embed_size, heads, dropout=dropout, forward_expansion=forward_expansion, ) for _ in range(num_layers) ] )
编码器由多个 Transformer 块组成。每个 Transformer 块包含多头注意力机制和前馈网络。
num_layers
表示 Transformer 块的数量。Dropout
self.dropout = nn.Dropout(dropout)
Dropout 是一种正则化技术,通过随机丢弃一部分神经元的输出来防止过拟合。
dropout
参数表示丢弃的概率。
3. 前向传播方法
def forward(self, x, mask):
N, seq_length = x.shape
x = self.dropout(self.position_embedding(self.word_embedding(x)))
for layer in self.layers:
x = layer(x, x, x, mask)
return x
参数解释
x
- 输入序列,形状为
(N, seq_length)
,其中N
是批次大小,seq_length
是序列长度。
mask
- 掩码,用于防止某些位置的信息泄露(如在自注意力中屏蔽未来信息)。
流程解释
词嵌入与位置编码
x = self.dropout(self.position_embedding(self.word_embedding(x)))
- 首先,将输入序列
x
通过词嵌入层(word_embedding
)得到嵌入向量。 - 然后,将嵌入向量与位置编码(
position_embedding
)相加,为每个标记添加位置信息。 - 最后,应用 Dropout 防止过拟合。
- 首先,将输入序列
逐层传递
for layer in self.layers: x = layer(x, x, x, mask)
- 输入序列
x
逐层传递到每个 Transformer 块中。在每个块中:value
、key
和query
都是x
,因为这是自注意力机制(Self-Attention)。mask
用于控制哪些位置的信息可以被关注。
- 每个 Transformer 块的输出会作为下一层的输入。
- 输入序列
返回结果
return x
- 最终返回编码器的输出,形状为
(N, seq_length, embed_size)
,表示每个位置的上下文表示。
- 最终返回编码器的输出,形状为
4. 总结
Transformer 编码器,其主要功能包括:
- 词嵌入与位置编码 :将输入标记转换为嵌入向量,并添加位置信息。
- 多层 Transformer 块 :通过多头注意力机制和前馈网络逐层处理输入序列。
- 掩码机制 :通过掩码控制注意力的范围,避免信息泄露。
- Dropout 正则化 :防止过拟合。
编码器的输出是一个上下文表示,可以被解码器用于生成目标序列。这种架构在机器翻译、文本生成等任务中表现出色。
作者码字不易,觉得有用的话不妨点个赞吧,关注我,持续为您更新AI的优质内容。