一. 整体架构

其他模块组件:
Embedding
Softmax
Positional Encoding
输入和输出处理
填充掩码
未来信息掩码
二.编码器层(单个编码器)
组件: ①多头自注意力 ②前馈神经网络 ③残差连接和层归一化
class EncoderLayer(nn.Module):
def__init__(self,d_model,h,d_ff,dropout):
"""
编码器层。
参数:
d_model: 嵌入维度
h: 多头注意力的头数
d_ff: 前馈神经网络的隐藏层维度
dropout: Dropout 概率
"""
super(EncoderLayer, self).__init__()
self.self_atn =MultiHeadAttention(d_model,h) #多头自注意力
self.feed_forward = PositionwiseFeedForward(d_model, d_ff, dropout) # 前馈神经网络
# 定义两个子层连接,分别用于多头自注意力和前馈神经网络(对应模型架构图中的两个残差连接)
self.sublayers = nn.ModuleList([SublayerConnection(d_model, dropout) for _ in range(2)])
self.d_model = d_model
def forward(self, x, src_mask):
x = self.sublayers[0](x, lambda x: self.self_attn(x, x, x, src_mask)) # 自注意力子层
x = self.sublayers[1](x, self.feed_forward) # 前馈子层
return x
三.解码器层(单个解码器)
组件: ①掩码多头自注意力 ② 多头交叉注意力(Multi-Head Cross-Attention) ③前馈神经网络
④残差连接和层归一化
class DecoderLayer(nn.Module):
def__init__(self,d_model,h,d_ff,dropout):
"""
解码器层。
参数:
d_model: 嵌入维度
h: 多头注意力的头数
d_ff: 前馈神经网络的隐藏层维度
dropout: Dropout 概率
"""
super(DecoderLayer, self).__init__()
self.self_attn = MultiHeadAttention(d_model, h) # 掩码多头自注意力(Masked Multi-Head Self-Attention)
self.cross_attn = MultiHeadAttention(d_model, h) # 多头交叉注意力(Multi-Head Cross-Attention)
self.feed_forward = PositionwiseFeedForward(d_model, d_ff, dropout) # 前馈神经网络
# 定义三个子层连接,分别用于掩码多头自注意力、多头交叉注意力和前馈神经网络(对应模型架构图中的三个残差连接)
self.sublayers = nn.ModuleList([SublayerConnection(d_model, dropout) for _ in range(3)])
self.d_model = d_model
def forward(self, x, memory, src_mask, tgt_mask):
"""
前向传播函数。
参数:
x: 解码器输入 (batch_size, seq_len_tgt, d_model)
memory: 编码器输出 (batch_size, seq_len_src, d_model)
src_mask: 源序列掩码,用于交叉注意力
tgt_mask: 目标序列掩码,用于自注意力
返回:
x: 解码器层的输出
# 第一个子层:掩码多头自注意力(Masked Multi-Head Self-Attention)
x = self.sublayers[0](x, lambda x: self.self_attn(x, x, x, tgt_mask))
# 第二个子层:交叉多头注意力(Multi-Head Cross-Attention),使用编码器的输出 memory
x = self.sublayers[1](x, lambda x: self.cross_attn(x, memory, memory, src_mask))
# 第三个子层:前馈神经网络
x = self.sublayers[2](x, self.feed_forward)
return x
五.编码器(N 个编码器)
class Encoder(nn.Module):
def __init__(self, d_model, N, h, d_ff, dropout=0.1):
"""
编码器,由 N 个 EncoderLayer 堆叠而成。
参数:
d_model: 嵌入维度
N: 编码器层的数量
h: 多头注意力的头数
d_ff: 前馈神经网络的隐藏层维度
dropout: Dropout 概率
"""
super(Encoder, self).__init__()
self.layers=nn.ModuleList([
EncoderLayer(d_model, h, d_ff, dropout) for _ in range(N)
])
self.norm = LayerNorm(d_model) # 最后层归一化
def forward(self, x, mask):
"""
前向传播函数。
参数:
x: 输入张量 (batch_size, seq_len, d_model)
mask: 输入掩码
返回:
编码器的输出
"""
for layer in self.layers:
x = layer(x, mask)
return self.norm(x) # 最后层归一化
六.解码器(N 个解码器)
class Decoder(nn.Module):
def __init__(self, d_model, N, h, d_ff, dropout=0.1):
"""
解码器,由 N 个 DecoderLayer 堆叠而成。
参数:
d_model: 嵌入维度
N: 解码器层的数量
h: 多头注意力的头数
d_ff: 前馈神经网络的隐藏层维度
dropout: Dropout 概率
"""
super(Decoder, self).__init__()
self.layers = nn.ModuleList([
DecoderLayer(d_model, h, d_ff, dropout) for _ in range(N)
])
self.norm = LayerNorm(d_model) # 最后层归一化
def forward(self, x, memory, src_mask, tgt_mask):
"""
前向传播函数。
参数:
x: 解码器输入 (batch_size, seq_len_tgt, d_model)
memory: 编码器的输出 (batch_size, seq_len_src, d_model)
src_mask: 用于交叉注意力的源序列掩码
tgt_mask: 用于自注意力的目标序列掩码
返回:
解码器的输出
"""
for layer in self.layers:
x = layer(x, memory, src_mask, tgt_mask)
return self.norm(x) # 最后层归一化
七.Transformer完整架构
完整组件:
输入嵌入和位置编码:
SourceEmbedding:对源序列进行嵌入并添加位置编码。
TargetEmbedding:对目标序列进行嵌入并添加位置编码。
多头注意力和前馈网络:
MultiHeadAttention:多头注意力机制。
PositionwiseFeedForward:位置前馈网络。
编码器和解码器:
Encoder:由多个 EncoderLayer 堆叠而成。
Decoder:由多个 DecoderLayer 堆叠而成。
输出层:
fc_out:线性层,将解码器的输出映射到目标词汇表维度。
class Transformer(nn.Module):
def__init__(self,src_vocab_size,tgt_vocab_size,d_model,N,h,d_ff,dropout=0.1):
"""
Transformer 模型,由编码器和解码器组成。
参数:
src_vocab_size: 源语言词汇表大小
tgt_vocab_size: 目标语言词汇表大小
d_model: 嵌入维度
N: 编码器和解码器的层数
h: 多头注意力的头数
d_ff: 前馈神经网络的隐藏层维度
dropout: Dropout 概率
"""
super(Transformer,self).__init__()
# 输入嵌入和位置编码,src 对应于编码器输入,tgt 对应于解码器输入
self.src_embedding = SourceEmbedding(src_vocab_size, d_model, dropout)
self.tgt_embedding = TargetEmbedding(tgt_vocab_size, d_model, dropout) # 共享:self.tgt_embedding = self.src_embedding
# 编码器和解码器
self.encoder = Encoder(d_model, N, h, d_ff, dropout)
self.decoder = Decoder(d_model, N, h, d_ff, dropout)
# 输出线性层
self.fc_out = nn.Linear(d_model, tgt_vocab_size)
def forward(self, src, tgt):
"""
前向传播函数。
参数:
src: 源序列输入 (batch_size, seq_len_src)
tgt: 目标序列输入 (batch_size, seq_len_tgt)
返回:
Transformer 的输出(未经过 Softmax)
"""
# 生成掩码
src_mask = create_padding_mask(src)
tgt_mask = create_decoder_mask(tgt)
# 编码器
enc_output = self.encoder(self.src_embedding(src), src_mask)
# 解码器
dec_output = self.decoder(self.tgt_embedding(tgt), enc_output, src_mask, tgt_mask)
# 输出层
output = self.fc_out(dec_output)
return output
八.问题
1.什么是自回归与非自回归?
自回归生成是指序列生成过程中,每个新生成的 token 依赖于之前生成的 token。这意味着生成过程是串行的,每一步的输入由前面已生成的 token 组成的上下文序列构成。
非自回归生成是一种并行生成的方式,一次性生成多个甚至全部的 token,从而显著提高生成速度,但也会牺牲一定的生成质量。
2.既然输出hth_tht 同样依赖于ht−1h_{t-1}ht−1,那么并行体现在哪里呢?
虽然在推理阶段(inference),生成过程看起来必须是顺序的(实际也是如此),因为每一步的输出都依赖于前一步的结果(即
hth_tht 依赖于 ht−1h_{t-1}ht−1。但在训练阶段,模型可以实现并行处理(稍微停顿一会,猜猜是如何去做的):
在训练阶段,我们无需像推理时那样依赖解码器的先前输出来预测当前时间步的结果,而是使用已知的目标序列(Teacher Forcing)作为解码器每个时间步的输入,这意味着解码器的所有时间步(所有 token)可以同时进行预测:
Teacher Forcing 是指在训练过程中,使用真实的目标输出(ground truth)作为解码器每一步的输入,而不是依赖模型自己生成的预测结果,对于 Transformer 来说,这个目标输出就是对应的翻译文本。
参考文章链接:https://github.com/Hoper-J/AI-Guide-and-Demos-zh_CN/blob/master/PaperNotes/Transformer
之终结版整体架构&spm=1001.2101.3001.5002&articleId=156647336&d=1&t=3&u=2d5b7689b7d341a7b890bc482b132014)
947

被折叠的 条评论
为什么被折叠?



