Transformer中的Encoder、Decoder

一、Transformer博客推荐

Transformer源于谷歌公司2017年发表的文章Attention is all you need,Jay Alammar在博客上对文章做了很好的总结:
英文版:The Illustrated Transformer

优快云上又博主(于建民)对其进行了很好的中文翻译:
中文版:The Illustrated Transformer【译】

Google AI blog写的一篇简述可以作为科普文:
Transformer: A Novel Neural Network Architecture for Language Understanding

李宏毅老师的Transformer课程

二、Transformer的Encoder

关于Encoder的相关细节,Miguel Romero Calvo的总结博客如下:
Dissecting BERT Part 1: The Encoder

三、Transformer的Decoder

关于Decoder的相关细节(包括如何将Encoder的输入利用到Decoder端),Miguel Romero Calvo的总结博客如下:
Dissecting BERT Appendix: The Decoder

四、Transformer结构及其应用–BERT、GPT

知乎的Ph0en1x在文章中介绍得不错Transformer结构及其应用详解–GPT、BERT、MT-DNN、GPT-2

五、Transformer中的Masked

Trnsformer中的三种Mask详解可以参考如下博文:
Transformer的矩阵维度分析和Mask详解

知乎文章在结尾部分对Padding Mask and Sequence mask进行了简要的介绍。

六、Transformer实现代码

Tensorflow实现:A TensorFlow Implementation of the Transformer

Pytorch实现:Facebook AI Research Sequence-to-Sequence

Harvardnlp: The Annotated Transformer

<think>嗯,用户想了解Transformerencoderdecoder的构建方法。这个问题非常有针对性,说明用户已经对Transformer有了基本认知,现在想深入实现细节。从引用内容看,用户提供的资料已经涵盖了架构差异、代码片段和典型应用,我需要系统梳理这些信息。 用户可能正在学习Transformer的代码实现,或者需要对照理论理解实际模块设计。特别注意用户引用的第三篇提到两个关键差异:decoder的mask机制和模块连接方式,第四篇则提到PyTorch的register_buffer技巧,这些都是实操重点。 首先需要区分encoderdecoder的结构共性:它们都包含多头注意力和前馈网络,但decoder多了一层encoder-decoder attention。用户引用的代码片段显示decoder有三个子层,而encoder只有两个,这个细节必须强调。 关于mask机制,decoder的自注意力层需要防止看到未来信息,所以引用[3]特别提到requires_mask=True这个实现开关。位置编码部分,引用[4]提醒我们用register_buffer保存,这点在PyTorch实现中很重要——不过用户没问框架细节,可以简略带过。 注意到用户上次回答要求"结构清晰",这次我会拆解为三个层面:基础模块、组合方式、特殊处理。代码示例保留Python但简化变量名,因为引用[3]的config对象可能让初学者困惑。典型模型引用(BERT/GPT)能帮助用户关联实际应用。 突然想到,用户没问训练细节(如teacher forcing),所以暂时聚焦架构。但相关问题里可以加入位置编码的实现技巧,因为引用[4]提到这点值得展开。 </think>TransformerEncoderDecoder 采用**堆叠的相同层结构**,但在具体模块组成和功能实现上存在关键差异。以下是核心构建方法: --- ### **1. Encoder 构建** #### **核心组件(单层)** 1. **多头自注意力层(Multi-Head Self-Attention)** - **作用**:捕捉输入序列内部各位置的依赖关系(如上下文语义)。 - **公式**: $$ \text{Attention}(Q,K,V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V $$ 其中 $Q,K,V$ 均为输入序列的线性变换结果。 2. **前馈神经网络层(Feed-Forward Network, FFN)** - **结构**:两层全连接层 + ReLU 激活函数(例如:$ \text{FFN}(x) = \text{ReLU}(xW_1 + b_1)W_2 + b_2 $)。 - **作用**:对注意力输出进行非线性变换。 3. **残差连接与层归一化(Add & Norm)** - 每个子层(注意力/FFN)后执行: $$ \text{Output} = \text{LayerNorm}(x + \text{Sublayer}(x)) $$ #### **整体结构** - 由 **$N$ 个相同的层**堆叠而成(通常 $N=6$ 或 $12$)。 - **输入**:词嵌入向量 + 位置编码(Positional Encoding)。 - **输出**:上下文相关的语义表示(每个 token 的向量)。 > **代码片段(PyTorch 风格)** > ```python > class EncoderLayer(nn.Module): > def __init__(self, d_model, n_heads, d_ff, dropout): > super().__init__() > self.self_attn = MultiHeadAttention(d_model, n_heads) # 多头自注意力 > self.ffn = PositionwiseFFN(d_model, d_ff) # 前馈网络 > self.norm1 = nn.LayerNorm(d_model) > self.norm2 = nn.LayerNorm(d_model) > self.dropout = nn.Dropout(dropout) > > def forward(self, x, mask): > # 自注意力 + 残差连接 & 归一化 > attn_output = self.self_attn(x, x, x, mask) # Q=K=V=x > x = x + self.dropout(attn_output) > x = self.norm1(x) > > # 前馈网络 + 残差连接 & 归一化 > ffn_output = self.ffn(x) > x = x + self.dropout(ffn_output) > x = self.norm2(x) > return x > ``` --- ### **2. Decoder 构建** #### **核心组件(单层)** 1. **掩码多头自注意力层(Masked Multi-Head Self-Attention)** - **作用**:确保预测时仅依赖已生成的部分(防止信息泄露)。 - **实现**:在注意力权重计算时添加下三角掩码矩阵($ -\infty $ 屏蔽未来位置)。 2. **编码器-解码器注意力层(Encoder-Decoder Attention)** - **作用**:融合 Encoder 输出的语义表示。 - **输入**: - $Q$:来自 Decoder 上一层的输出 - $K, V$:来自 Encoder 的最终输出 3. **前馈网络层(FFN)**:与 Encoder 相同。 4. **残差连接与层归一化(Add & Norm)** - 在 **三个子层**(掩码自注意力、交叉注意力、FFN)后均执行。 #### **整体结构** - 由 **$N$ 个相同的层**堆叠。 - **输入**: - 目标序列的词嵌入 + 位置编码(训练时使用完整序列,预测时自回归生成)。 - **输出**:下一个 token 的预测概率分布。 > **代码片段(PyTorch 风格)** > ```python > class DecoderLayer(nn.Module): > def __init__(self, d_model, n_heads, d_ff, dropout): > super().__init__() > self.self_attn = MultiHeadAttention(d_model, n_heads) # 掩码自注意力(需传入掩码) > self.cross_attn = MultiHeadAttention(d_model, n_heads) # 编码器-解码器注意力 > self.ffn = PositionwiseFFN(d_model, d_ff) > self.norm1 = nn.LayerNorm(d_model) > self.norm2 = nn.LayerNorm(d_model) > self.norm3 = nn.LayerNorm(d_model) > self.dropout = nn.Dropout(dropout) > > def forward(self, x, enc_output, tgt_mask, src_mask): > # 掩码自注意力 + 残差归一化 > self_attn_output = self.self_attn(x, x, x, tgt_mask) # 使用目标序列掩码 > x = x + self.dropout(self_attn_output) > x = self.norm1(x) > > # 编码器-解码器注意力 + 残差归一化 > cross_attn_output = self.cross_attn(x, enc_output, enc_output, src_mask) # Q=x, K=V=enc_output > x = x + self.dropout(cross_attn_output) > x = self.norm2(x) > > # 前馈网络 + 残差归一化 > ffn_output = self.ffn(x) > x = x + self.dropout(ffn_output) > x = self.norm3(x) > return x > ``` --- ### **关键差异总结** | **组件** | Encoder | Decoder | |------------------------|----------------------------------|----------------------------------| | **注意力类型** | 自注意力 | 掩码自注意力 + 编码器-解码器注意力 | | **输入来源** | 原始输入序列 | 目标序列 + Encoder 输出 | | **掩码要求** | 仅填充掩码(Padding Mask) | 填充掩码 + 序列掩码(未来屏蔽) | | **子层数量(每层)** | 2(自注意力 + FFN) | 3(掩码自注意力 + 交叉注意力 + FFN)| | **典型应用** | BERT(纯 Encoder)[^1] | GPT(纯 Decoder)[^1] | --- ### **附加说明** - **位置编码**:通过 $\sin/\cos$ 函数或可学习参数生成,使用 `register_buffer` 在 PyTorch 中注册为非参数张量[^4]。 - **层堆叠**:$N$ 层 Encoder/Decoder 的输出通过 **残差连接** 传递,缓解梯度消失问题。 - **纯架构变体**: - *纯 Encoder*(如 BERT):仅需移除 Decoder 部分。 - *纯 Decoder*(如 GPT):移除 Encoder 及交叉注意力层,保留掩码自注意力[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值