仅仅使用pytorch来手撕transformer架构(1):位置编码的类的实现和向前传播
最适合小白入门的Transformer介绍
仅仅使用pytorch来手撕transformer架构(2):多头注意力MultiHeadAttention类的实现和向前传播
仅仅使用pytorch来手撕transformer架构(3):编码器模块和编码器类的实现和向前传播
话不多说,直接上代码
# Transformer 解码器模块
class DecoderBlock(nn.Module):
def __init__(self, embed_size, heads, forward_expansion, dropout, device):
super(DecoderBlock, self).__init__()
self.attention = MultiHeadAttention(embed_size, heads)
self.norm = nn.LayerNorm(embed_size)
self.transformer_block = TransformerBlock(
embed_size, heads, dropout, forward_expansion
)
def forward(self, x, value, key, src_mask, trg_mask):
attention = self.attention(x, x, x, trg_mask)
query = self.dropout(self.norm(attention + x))
out = self.transformer_block(value, key, query, src_mask)
return out
# 解码器
class Decoder(nn.Module):
def __init__(self, trg_vocab_size, embed_size, num_layers, heads, forward_expansion, dropout, device, max_length):
super(Decoder, self).__init__()
self.device = device
self.word_embedding = nn.Embedding(trg_vocab_size, embed_size)
self.position_embedding = PositionalEncoding(embed_size, dropout, max_length)
self.layers = nn.ModuleList(
[
DecoderBlock(embed_size, heads, forward_expansion, dropout, device)
for _ in range(num_layers)
]
)
self.fc_out = nn.Linear(embed_size, trg_vocab_size)
self.dropout = nn.Dropout(dropout)
def forward(self, x, enc_out, src_mask, trg_mask):
N, seq_length = x.shape
x = self.dropout(self.position_embedding(self.word_embedding(x)))
for layer in self.layers:
x = layer(x, enc_out, enc_out, src_mask, trg_mask)
out = self.fc_out(x)
return out
DecoderBlock
的结构DecoderBlock
的结构Transformer 解码器中的一个基本模块——DecoderBlock
。每个 DecoderBlock
包含两个主要部分:掩码多头自注意力(Masked Multi-Head Self-Attention) 和 Transformer 块(TransformerBlock)。
MultiHeadAttention
)self.attention = MultiHeadAttention(embed_size, heads)
x
(解码器的输入序列)。trg_mask
(目标序列的掩码,用于防止解码器看到未来的信息)。nn.LayerNorm
)self.norm = nn.LayerNorm(embed_size)
attention + x
(注意力输出与输入的残差连接)。TransformerBlock
)self.transformer_block = TransformerBlock(embed_size, heads, dropout, forward_expansion)
value
和 key
:来自编码器的输出(编码器的上下文信息)。query
:经过归一化的解码器输入。src_mask
:编码器的掩码(用于忽略填充部分)。DecoderBlock
的前向传播(forward
方法)def forward(self, x, value, key, src_mask, trg_mask):
attention = self.attention(x, x, x, trg_mask)
query = self.dropout(self.norm(attention + x))
out = self.transformer_block(value, key, query, src_mask)
return out
attention = self.attention(x, x, x, trg_mask)
x
:解码器的输入序列(通常是目标序列的嵌入表示)。trg_mask
:目标序列的掩码,用于防止解码器看到未来的信息。query = self.dropout(self.norm(attention + x))
x
进行残差连接(attention + x
),以保留输入的信息。LayerNorm
对残差连接的结果进行归一化。Dropout
进行正则化。query
)传递到下一个模块。out = self.transformer_block(value, key, query, src_mask)
value
和 key
:来自编码器的输出(编码器的上下文信息)。query
:经过归一化的解码器输入。src_mask
:编码器的掩码(用于忽略填充部分)。DecoderBlock
的作用DecoderBlock
是 Transformer 解码器的核心模块,它结合了以下两个主要功能:
TransformerBlock
,结合编码器的上下文信息(value
和 key
)和解码器的查询(query
),生成最终的输出。DecoderBlock
是 Transformer 解码器中的一个模块,它包含:
通过多个 DecoderBlock
的堆叠,解码器能够逐步生成目标序列,同时利用编码器提供的上下文信息。
Transformer 的解码器(Decoder
)部分,它是整个 Transformer 模型的关键组件之一,用于生成目标序列(例如,在机器翻译任务中生成翻译后的句子)。以下是对代码的详细解析:
nn.Embedding
)self.word_embedding = nn.Embedding(trg_vocab_size, embed_size)
trg_vocab_size
:目标词汇表的大小。embed_size
:嵌入向量的维度。(N, seq_length, embed_size)
的张量,其中 N
是批量大小,seq_length
是目标序列的长度。PositionalEncoding
)self.position_embedding = PositionalEncoding(embed_size, dropout, max_length)
embed_size
:嵌入向量的维度。dropout
:Dropout 概率,用于正则化。max_length
:模型能够处理的最大序列长度。(N, seq_length, embed_size)
的张量,包含位置信息的嵌入向量。DecoderBlock
)self.layers = nn.ModuleList(
[
DecoderBlock(embed_size, heads, forward_expansion, dropout, device)
for _ in range(num_layers)
]
)
DecoderBlock
,每个块包含掩码多头自注意力和 Transformer 块。num_layers
:解码器中模块的数量。DecoderBlock
的参数:
embed_size
:嵌入向量的维度。heads
:多头注意力中的头数。forward_expansion
:前馈网络中的扩展因子。dropout
:Dropout 概率。device
:设备(CPU 或 GPU)。nn.Linear
)self.fc_out = nn.Linear(embed_size, trg_vocab_size)
embed_size
。trg_vocab_size
。(N, seq_length, trg_vocab_size)
的张量,表示目标序列中每个位置的单词预测概率。self.dropout = nn.Dropout(dropout)
forward
方法)def forward(self, x, enc_out, src_mask, trg_mask):
N, seq_length = x.shape
x = self.dropout(self.position_embedding(self.word_embedding(x)))
for layer in self.layers:
x = layer(x, enc_out, enc_out, src_mask, trg_mask)
out = self.fc_out(x)
return out
x = self.dropout(self.position_embedding(self.word_embedding(x)))
(N, seq_length, embed_size)
的张量。for layer in self.layers:
x = layer(x, enc_out, enc_out, src_mask, trg_mask)
x
,结合编码器的输出 enc_out
。DecoderBlock
包含:
trg_mask
防止看到未来的信息。enc_out
)和解码器的查询(x
)。out = self.fc_out(x)
(N, seq_length, trg_vocab_size)
的张量,表示目标序列中每个位置的单词预测概率。解码器的主要任务是根据编码器的上下文信息(enc_out
)和目标序列的输入(x
),逐步生成目标序列。它通过以下步骤实现:
DecoderBlock
,逐步处理目标序列,结合编码器的上下文信息。解码器是 Transformer 模型中的关键部分,它通过以下组件实现目标序列的生成:
通过堆叠多个 DecoderBlock
,解码器能够有效地捕捉目标序列中的依赖关系,并利用编码器提供的上下文信息生成高质量的输出。
作者码字不易,觉得有用的话不妨点个赞吧,关注我,持续为您更新AI的优质内容。