GPT - TransformerDecoderBlock

本节代码定义了一个 TransformerDecoderBlock 类,它是 Transformer 架构中解码器的一个基本模块。这个模块包含了多头自注意力(Multi-Head Attention)、前馈网络(Feed-Forward Network, FFN)和层归一化(Layer Normalization)。

⭐这一节代码理解即可,知道Transformer的关键组成部分:多头自注意力(Multi-Head Attention)、前馈网络(Feed-Forward Network, FFN)和层归一化(Layer Normalization),不同DecoderBlock 有不同的复现方式,本文只给出了自己的实现方式

1. 初始化方法
复制代码
def __init__(self, d_model, dff, dropout):
    super().__init__()

    self.linear1 = nn.Linear(d_model, dff)
    self.activation = nn.GELU()
    self.dropout = nn.Dropout(dropout)
    self.linear2 = nn.Linear(dff, d_model)

    self.norm1 = nn.LayerNorm(d_model)
    self.norm2 = nn.LayerNorm(d_model)
    self.norm3 = nn.LayerNorm(d_model)
    self.dropout1 = nn.Dropout(dropout)
    self.dropout2 = nn.Dropout(dropout)
    self.dropout3 = nn.Dropout(dropout)

    self.mha_block1 = MultiHeadAttention(d_model, num_heads, dropout)
    self.mha_block2 = MultiHeadAttention(d_model, num_heads, dropout)
  • d_model:模型的维度,通常是嵌入维度。

  • dff:前馈网络的中间层维度。

  • dropout:Dropout 的概率。

  • num_heads:多头注意力机制中的头数(未在代码中定义,需要传入)。

2. 多头自注意力机制
复制代码
self.mha_block1 = MultiHeadAttention(d_model, num_heads, dropout)
self.mha_block2 = MultiHeadAttention(d_model, num_heads, dropout)
  • MultiHeadAttention 是一个自定义的多头自注意力模块,通常包含查询(Q)、键(K)和值(V)的线性变换,以及多头注意力机制。

  • mha_block1mha_block2 分别表示两个多头自注意力模块。

3. 前馈网络
复制代码
self.linear1 = nn.Linear(d_model, dff)
self.activation = nn.GELU()
self.dropout = nn.Dropout(dropout)
self.linear2 = nn.Linear(dff, d_model)
  • 前馈网络由两个线性层组成,中间使用激活函数(如 GELU 或 ReLU)和 Dropout。

  • linear1 将输入从 d_model 映射到 dfflinear2 将输出从 dff 映射回 d_model

4. 层归一化
复制代码
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)
self.norm3 = nn.LayerNorm(d_model)
  • 层归一化用于稳定训练过程,减少内部协变量偏移。
5. Dropout
复制代码
self.dropout1 = nn.Dropout(dropout)
self.dropout2 = nn.Dropout(dropout)
self.dropout3 = nn.Dropout(dropout)
  • Dropout 用于防止过拟合,通过随机丢弃一些神经元的输出来增强模型的泛化能力。
6. 前向传播
复制代码
def forward(self, x, mask=None):
    x = self.norm1(x + self.dropout1(self.mha_block1(x, mask)))
    x = self.norm2(x + self.dropout2(self.mha_block2(x, mask)))
    x = self.norm3(self.linear2(self.dropout(self.activation(self.linear1(x)))))

    return x
  • mha_block1mha_block2 :两个多头自注意力模块,分别处理输入 x

  • norm1norm2:在每个自注意力模块后应用层归一化。

  • linear1linear2:前馈网络的两个线性层,中间使用激活函数和 Dropout。

  • norm3:在前馈网络后应用层归一化。

需复现的完整代码(未标红部分为上节提到的多头自注意力机制)

复制代码
class MultiHeadAttention(nn.Module):
    def __init__(self, d_model, num_heads, dropout):
        super().__init__()
        self.num_heads = num_heads
        self.d_k = d_model // num_heads
        self.q_project = nn.Linear(d_model, d_model)
        self.k_project = nn.Linear(d_model, d_model)
        self.v_project = nn.Linear(d_model, d_model)
        self.o_project = nn.Linear(d_model, d_model)

        self.dropout = nn.Dropout(dropout)

    def forward(self, x, attn_mask=None):
        
        batch_size, seq_len, d_model = x.shape
        Q = self.q_project(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)
        K = self.q_project(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)
        V = self.q_project(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)

        atten_scores = Q @ K.transpose(2, 3) / math.sqrt(self.d_k)

        if attn_mask is not None:
            attn_mask = attn_mask.unsqueeze(1)
            atten_scores = atten_scores.masked_fill(attn_mask == 0, -1e9)

        atten_scores = torch.softmax(atten_scores, dim=-1)
        out = atten_scores @ V
        out = out.transpose(1, 2).contiguous().view(batch_size, seq_len, d_model)
        out = self.o_project(out)
        return self.dropout(out)
复制代码
class TransformerDecoderBlock(nn.Module):
    def __init__(self, d_model, dff, dropout):
        super().__init__()

        self.linear1 = nn.Linear(d_model, dff)
        self.activation = nn.GELU()
        # self.activation = nn.ReLU()

        self.dropout = nn .Dropout(dropout)
        self.linear2 = nn.Linear(dff, d_model)

        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        self.norm3 = nn.LayerNorm(d_model)
        self.dropout1 = nn.Dropout(dropout)
        self.dropout2 = nn.Dropout(dropout)
        self.dropout3 = nn.Dropout(dropout)

        self.mha_block1 = MultiHeadAttention(d_model, num_heads, dropout)
        self.mha_block2 = MultiHeadAttention(d_model, num_heads, dropout)


    def forward(self, x, mask=None):
        x = self.norm1(x + self.dropout1(self.mha_block1(x, mask)))
        x = self.norm2(x + self.dropout2(self.mha_block2(x, mask)))
        x = self.norm3(self.linear2(self.dropout(self.activation(self.linear1(x)))))

        return x
相关推荐
视觉语言导航2 小时前
ICCV-2025 | 复杂场景的精准可控生成新突破!基于场景图的可控 3D 户外场景生成
人工智能·深度学习·具身智能
AI街潜水的八角4 小时前
深度学习图像分类数据集—濒危动物识别分类
人工智能·深度学习
安思派Anspire4 小时前
LangGraph + MCP + Ollama:构建强大代理 AI 的关键(一)
前端·深度学习·架构
FF-Studio5 小时前
大语言模型(LLM)课程学习(Curriculum Learning)、数据课程(data curriculum)指南:从原理到实践
人工智能·python·深度学习·神经网络·机器学习·语言模型·自然语言处理
CoovallyAIHub5 小时前
YOLO模型优化全攻略:从“准”到“快”,全靠这些招!
深度学习·算法·计算机视觉
G.E.N.7 小时前
开源!RAG竞技场(2):标准RAG算法
大数据·人工智能·深度学习·神经网络·算法·llm·rag
zm-v-159304339869 小时前
ArcGIS 水文分析升级:基于深度学习的流域洪水演进过程模拟
人工智能·深度学习·arcgis
SHIPKING39311 小时前
【机器学习&深度学习】什么是下游任务模型?
人工智能·深度学习·机器学习
伍哥的传说16 小时前
React 各颜色转换方法、颜色值换算工具HEX、RGB/RGBA、HSL/HSLA、HSV、CMYK
深度学习·神经网络·react.js
要努力啊啊啊18 小时前
YOLOv3-SPP Auto-Anchor 聚类调试指南!
人工智能·深度学习·yolo·目标检测·目标跟踪·数据挖掘