Transformer解码器(Decoder)
在Transformer架构中,解码器(Decoder) 的作用是根据编码器的输出生成最终的预测结果。解码器和编码器一样,使用了自注意力机制,但与编码器不同的是,解码器还需要考虑到当前时刻生成的目标词(如在机器翻译中是目标语言的单词)。在生成时,解码器要根据当前词及之前的生成词来输出下一个词。
Transformer的解码器由多个相同的解码器层堆叠而成,每个解码器层由三个主要部分组成:
- 自注意力机制(Self-Attention)
- 编码器-解码器注意力机制(Encoder-Decoder Attention)
- 前馈神经网络(Feed-Forward Neural Network)
和编码器一样,每个解码器层也包含残差连接(Residual Connection)和层归一化(Layer Normalization),确保训练的稳定性。
1. Transformer解码器的结构
每个解码器层包含以下几部分:
-
Masked Multi-Head Self-Attention:
解码器的自注意力机制在这里与编码器的自注意力有所不同。为了避免模型利用当前时刻之后的信息(即当前时刻的预测结果),解码器的自注意力机制使用了掩码(Masking)。这个掩码确保了每个位置只能看到当前位置之前的信息,而不能看到未来的信息。 -
Multi-Head Attention(编码器-解码器注意力):
解码器中的第二部分是编码器-解码器注意力,其目的是让解码器能够利用编码器输出的上下文信息。解码器通过查询(Query)和编码器的键(Key)和值(Value)进行自注意力计算,生成当前时刻的上下文向量。 -
前馈神经网络:
解码器层的第三部分是前馈神经网络,其功能与编码器层中的前馈神经网络类似。通过前馈网络进一步处理每个位置的信息。 -
残差连接与层归一化:
每一层的子部分(如自注意力、编码器-解码器注意力、前馈网络)都包含残差连接和层归一化。
2. 解码器的计算过程
Transformer解码器的计算过程通常分为以下几个阶段:
-
输入嵌入与位置编码:
- 与编码器相同,解码器也需要对输入序列中的每个词进行嵌入,然后加入位置编码(Positional Encoding),以保留词序信息。
-
Masked Self-Attention层:
- 解码器的自注意力机制使用了掩码机制。掩码是为了确保解码器在生成某个词时,只能看到当前词及其之前的词,而不能看到后续的词(防止泄漏信息)。
-
Encoder-Decoder Attention层:
- 解码器会与编码器的输出进行交互。具体来说,解码器会使用编码器的输出作为键(Key) 和值(Value),而解码器的输出则作为查询(Query) 来进行注意力计算。这样,解码器能够基于编码器的信息生成目标序列。
-
前馈神经网络:
- 前馈神经网络对每个位置进行独立的计算,通常包含两个线性层以及一个激活函数(例如 ReLU)。
-
输出层:
- 解码器的输出会通过一个线性层映射到目标词汇表的维度,最终通过softmax函数生成词汇的概率分布。
3. Transformer解码器的数学公式
与编码器类似,解码器也使用自注意力和前馈神经网络,但在自注意力部分添加了掩码机制。在解码器的自注意力机制中,掩码操作确保了模型只能看到当前位置及之前的位置。
3.1 Masked Multi-Head Self-Attention
对于解码器中的自注意力层,查询( Q Q Q)、键( K K K)、值( V V V)的计算和编码器中的自注意力相似,但加入了掩码 M M M:
Attention ( Q , K , V , M ) = softmax ( Q K T + M d k ) V \text{Attention}(Q, K, V, M) = \text{softmax}\left(\frac{QK^T + M}{\sqrt{d_k}}\right) V Attention(Q,K,V,M)=softmax(dkQKT+M)V
这里, M M M 是掩码矩阵,其目的是将未来位置的注意力分数置为负无穷,从而避免模型访问未来的位置信息。
3.2 Encoder-Decoder Attention
解码器中的编码器-解码器注意力部分计算如下:
Attention ( Q , K encoder , V encoder ) = softmax ( Q K encoder T d k ) V encoder \text{Attention}(Q, K_{\text{encoder}}, V_{\text{encoder}}) = \text{softmax}\left(\frac{QK_{\text{encoder}}^T}{\sqrt{d_k}}\right) V_{\text{encoder}} Attention(Q,Kencoder,Vencoder)=softmax(dkQKencoderT)Vencoder
其中, K encoder K_{\text{encoder}} Kencoder 和 V encoder V_{\text{encoder}} Vencoder 是来自编码器的输出, Q Q Q 是解码器的查询。
3.3 前馈神经网络
每个位置的输出 z z z 会通过前馈神经网络处理,通常包括两个线性层和一个激活函数(如 ReLU):
z = ReLU ( X W 1 + b 1 ) W 2 + b 2 z = \text{ReLU}(XW_1 + b_1)W_2 + b_2 z=ReLU(XW1+b1)W2+b2
3.4 层归一化与残差连接
在每个子层的计算后,都会进行残差连接和层归一化操作,以确保训练稳定性。
4. Transformer解码器的PyTorch实现
在PyTorch中,Transformer解码器的实现可以通过 torch.nn.TransformerDecoder
和 torch.nn.TransformerDecoderLayer
来完成。以下是一个简单的示例代码:
import torch
import torch.nn as nn
class TransformerDecoderExample(nn.Module):
def __init__(self, output_dim, model_dim, num_heads, num_layers):
super(TransformerDecoderExample, self).__init__()
# 输出嵌入层
self.embedding = nn.Embedding(output_dim, model_dim)
# 解码器层
decoder_layers = nn.TransformerDecoderLayer(
d_model=model_dim,
nhead=num_heads
)
self.transformer_decoder = nn.TransformerDecoder(decoder_layers, num_layers=num_layers)
# 输出层
self.fc_out = nn.Linear(model_dim, output_dim)
def forward(self, tgt, memory):
# tgt 是目标序列的嵌入,memory 是来自编码器的上下文信息
tgt = self.embedding(tgt) # (seq_len, batch_size, model_dim)
memory = memory.permute(1, 0, 2) # (batch_size, seq_len, model_dim) -> (seq_len, batch_size, model_dim)
output = self.transformer_decoder(tgt, memory) # (seq_len, batch_size, model_dim)
output = output.mean(dim=0) # 聚合序列维度
output = self.fc_out(output) # 输出层
return output
# 示例
output_dim = 10 # 输出词汇表大小
model_dim = 512 # 模型维度
num_heads = 8 # 注意力头数
num_layers = 6 # 解码器层数
model = TransformerDecoderExample(output_dim, model_dim, num_heads, num_layers)
tgt = torch.randint(0, output_dim, (20, 32)) # 假设 batch_size=32, seq_len=20
memory = torch.randn(32, 20, model_dim) # 假设来自编码器的上下文信息
output = model(tgt, memory)
print(output.shape) # 输出形状: (batch_size, output_dim)
5. 总结
- Transformer解码器 是 Transformer 架构中的关键组件,负责生成目标序列的每个元素。它通过结合自注意力机制、编码器-解码器注意力机制和前馈神经网络来实现这一功能。
- 解码器的自注意力使用掩码来防止信息泄漏,同时结合编码器的上下文信息来生成目标序列。
- 在实际实现中,解码器通过与编码器输出的交互以及自注意力和前馈网络的处理,能够有效地生成准确的序列输出。