课程进度
15 / 15
上一节词嵌入与自然语言处理
自在学
分类课程智能体订阅
分类课程AI导师价格
编程深度学习序列到序列模型与注意力机制

序列到序列模型与注意力机制

2016年,Google翻译切换到神经机器翻译系统,翻译质量大幅提升。2017年,“Attention is All You Need”论文提出Transformer,彻底改变了NLP领域。这些突破的核心是注意力机制——让模型能够聚焦于输入的重要部分,而不是平等对待所有信息。

注意力机制是近年来深度学习最重要的创新之一。它不仅用于翻译,还是BERT、GPT等大语言模型的基础。理解注意力机制,是理解现代AI系统的关键。

序列到序列模型与注意力机制


Seq2Seq模型:从序列到序列

机器翻译是典型的序列到序列(Sequence-to-Sequence)任务:输入是源语言句子,输出是目标语言句子,两者长度通常不同。

编码器-解码器架构:

编码器处理输入序列,将信息压缩到一个固定维度的向量(上下文向量):

ht=LSTM(xt,ht−1)h_t = \text{LSTM}(x_t, h_{t-1})ht​=LSTM(xt​,ht−1​) c=hT(最后时刻的隐藏状态)c = h_T \quad \text{(最后时刻的隐藏状态)}c=hT​(最后时刻的隐藏状态)

解码器基于上下文向量生成输出序列:

st=LSTM(yt−1,st−1,c)s_t = \text{LSTM}(y_{t-1}, s_{t-1}, c)st​=LSTM(yt−1​,st−1​,c) yt=softmax(Wsst)y_t = \text{softmax}(W_s s_t)yt​=softmax(Ws​st​)
python
class Seq2SeqModel(nn.Module):
    def __init__(self, src_vocab_size, tgt_vocab_size, embedding_dim, hidden_dim):
        super().__init__()
        self.encoder_embedding = nn.Embedding(src_vocab_size, embedding_dim)
        self.encoder_lstm = nn.LSTM(embedding_dim, hidden_dim, batch_first=True)
        
        self.decoder_embedding = nn.Embedding(tgt_vocab_size, embedding_dim)
        self.decoder_lstm = nn.LSTM(embedding_dim, hidden_dim, batch_first=True)
        self.output_layer = nn.Linear(hidden_dim, tgt_vocab_size)
    
    def forward(self, src, tgt):
        # 编码
        src_embedded = self.encoder_embedding(src)
        _, (h_n, c_n) = self.encoder_lstm(src_embedded)
        
        # 解码
        tgt_embedded = self.decoder_embedding(tgt)
        decoder_output, _ = self.decoder_lstm(tgt_embedded, (h_n, c_n))
        
        # 输出层
        output = self.output_layer(decoder_output)
        return output

问题:将整个输入句子压缩到一个固定维度的向量 ccc,信息瓶颈。长句子的信息会丢失。


注意力机制:动态聚焦

注意力机制:动态聚焦

标准Seq2Seq的问题是:解码器只能看到编码器最后的隐藏状态 hTh_ThT​。翻译“我爱深度学习”到英文时,生成“love”应该更多关注“爱”,生成“learning”应该更多关注“学习”。但标准Seq2Seq平等对待所有源词。

注意力机制让解码器能动态地关注不同的源词。解码器在时刻 ttt 不只看固定的 ccc,而是计算一个动态的上下文向量 ctc_tct​,它是所有编码器隐藏状态的加权和:

ct=∑i=1Txαt,ihic_t = \sum_{i=1}^{T_x} \alpha_{t,i} h_ict​=i=1∑Tx​​αt,i​hi​

权重 αt,i\alpha_{t,i}αt,i​ 表示在生成第 ttt 个输出词时,应该关注第 iii 个输入词多少。这些权重通过一个注意力网络计算:

et,i=a(st−1,hi)(对齐分数)e_{t,i} = a(s_{t-1}, h_i) \quad \text{(对齐分数)}et,i​=a(st−1​,hi​)(对齐分数) αt,i=exp⁡(et,i)∑j=1Txexp⁡(et,j)(softmax归一化)\alpha_{t,i} = \frac{\exp(e_{t,i})}{\sum_{j=1}^{T_x} \exp(e_{t,j})} \quad \text{(softmax归一化)}αt,i​=∑j=1Tx​​exp(et,j​)exp(et,i​)​(softmax归一化)

这里 aaa 可以是一个小的神经网络(如单层全连接),或者简单的点积 st−1This_{t-1}^T h_ist−1T​hi​。

python
class AttentionDecoder(nn.Module):
    def __init__(self, embedding_dim, hidden_dim, output_dim):
        super().__init__()
        self.embedding = nn.Embedding(output_dim, embedding_dim)
        self.lstm = nn.LSTMCell(embedding_dim + hidden_dim, hidden_dim)
        self.attention = nn.Linear(hidden_dim * 2, 1)
        self.output_layer = nn.Linear(hidden_dim, output_dim)
    
    def forward(self, prev_word, prev_hidden, encoder_outputs):
        """
        prev_word: 前一个词,shape (batch,)
        prev_hidden: 前一时刻隐藏状态,shape (batch, hidden_dim)
        encoder_outputs: 所有编码器隐藏状态,shape (batch, src_len, hidden_dim)
        """
        batch_size = encoder_outputs.shape[0]
        src_len = encoder_outputs.shape[1]
        
        # 计算注意力权重
        # 将prev_hidden扩展为(batch, src_len, hidden_dim)
        prev_hidden_expanded = prev_hidden.unsqueeze(1).expand(-1, src_len, -1)
        
        # 拼接并通过注意力网络
        combined = torch.cat([encoder_outputs, prev_hidden_expanded], dim=2)
        attention_scores = self.attention(combined).squeeze(2)  # (batch, src_len)
        attention_weights = F.softmax(attention_scores, dim=1)  # (batch, src_len)
        
        # 计算上下文向量
        context = torch.bmm(attention_weights.unsqueeze(1), encoder_outputs).squeeze(1)  # (batch, hidden_dim)
        
        # 嵌入当前输入词
        embedded = self.embedding(prev_word)  # (batch, emb_dim)
        
        # LSTM输入是[embedded, context]拼接
        lstm_input = torch.cat([embedded, context], dim=1)
        hidden_new, cell_new = self.lstm(lstm_input, (prev_hidden, prev_cell))
        
        # 输出
        output = self.output_layer(hidden_new)
        
        return output, hidden_new, cell_new, attention_weights

注意力的直观理解:

翻译“我爱深度学习”→“I love deep learning”时:

  • 生成“I”:90%注意力在“我”,10%在其他词
  • 生成“love”:85%注意力在“爱”
  • 生成“deep”:80%注意力在“深度”
  • 生成“learning”:90%注意力在“学习”

注意力权重可视化能清楚地展示模型在“看”哪里,这也提供了可解释性。


Beam Search:寻找最优序列

解码时,我们需要找到概率最大的输出序列。贪婪解码每步选择概率最大的词,但可能错过全局最优。集束搜索(Beam Search)是一个平衡的方案。

维护 BBB 个最可能的候选序列(BBB 是集束宽度,如3或10):

  1. 第一步:选概率最高的 BBB 个词作为候选开头
  2. 第二步:对每个候选,扩展所有可能的第二个词,得到 B×VB \times VB×V 个序列,保留概率最高的 BBB 个
  3. 重复直到所有候选都生成结束标记
python
def beam_search_decode(model, src, beam_width=3, max_length=50):
    """
    集束搜索解码
    """
    # 编码
    context = model.encode(src)
    
    # 初始化:起始标记
    sequences = [[BOS_token]]
    scores = [0.0]
    
    for _ in range(max_length):
        all_candidates = []
        
        # 扩展每个候选序列
        for i in range(len(sequences)):
            seq = sequences[i]
            score = scores[i]
            
            if seq[-1] == EOS_token:  # 已结束的序列
                all_candidates.append((score, seq))
                continue
            
            # 预测下一个词的概率
            probs = model.decode_step(seq, context)
            
            # 取top-K个词
            top_k_probs, top_k_words = torch.topk(probs, beam_width)
            
            for j in range(beam_width):
                candidate_seq = seq + [top_k_words[j].item()]
                candidate_score = score + np.log(top_k_probs[j].item())
                all_candidates.append((candidate_score, candidate_seq))
        
        # 按分数排序,保留top-B
        ordered = sorted(all_candidates, key=lambda x: x[0], reverse=True)
        sequences = [seq for _, seq in ordered[:beam_width]]
        scores = [score for score, _ in ordered[:beam_width]]
        
        # 如果所有序列都结束了,提前停止
        if all(seq[-1] == EOS_token for seq in sequences):
            break
    
    # 返回分数最高的序列
    return sequences[0]

B=1B=1B=1 就是贪婪搜索,BBB 越大越可能找到全局最优,但计算量是 O(B)O(B)O(B) 倍。实践中 B=3B=3B=3 到 B=10B=10B=10 通常够用。


从RNN到Transformer

注意力机制如此有效,引发了一个疑问:既然注意力能捕捉序列依赖,我们还需要RNN吗?

2017年,Google的“Attention is All You Need”论文给出答案:不需要。Transformer完全抛弃了RNN,只用注意力机制。

自注意力(Self-Attention)让序列中的每个词关注其他所有词,捕捉任意距离的依赖。更重要的是,自注意力可以并行计算——不像RNN必须顺序处理,训练速度快了几十倍。

Transformer的成功催生了BERT(2018)、GPT-2/3(2019/2020)、GPT-4(2023)等大语言模型。2026年的今天,几乎所有SOTA的NLP模型都基于Transformer,RNN已经很少用于新项目。

Flash Attention等优化:

标准自注意力的复杂度是 O(n2)O(n^2)O(n2)(nnn 是序列长度),限制了能处理的最大长度。2022年提出的Flash Attention通过GPU内存层级优化,将速度提升3倍,内存占用降低10倍,让处理数万token的序列成为可能。

python
# Transformer的自注意力(简化版)
def self_attention(Q, K, V):
    """
    Q, K, V: (batch, seq_len, d_model)
    """
    d_k = Q.shape[-1]
    
    # 计算注意力分数
    scores = torch.matmul(Q, K.transpose(-2, -1)) / np.sqrt(d_k)
    
    # Softmax得到注意力权重
    attention_weights = F.softmax(scores, dim=-1)
    
    # 加权和
    output = torch.matmul(attention_weights, V)
    
    return output, attention_weights

多模态应用:

注意力机制不限于文本。2020年后,视觉Transformer(ViT)将注意力应用到图像,CLIP将图像和文本通过注意力对齐,DALL-E用注意力生成图像。注意力成为深度学习的通用机制,跨越视觉、语言、音频等模态。


从基础到前沿

我们的深度学习之旅至此阶段性告一段落。我们系统学习了神经网络的基本单元、前向与反向传播、梯度下降等核心理论,掌握了正则化、优化算法、批归一化等实用训练技巧,了解了错误分析、迁移学习、端到端学习等工程策略,深入探索了卷积网络及其在计算机视觉中的成功应用,并理解了序列建模领域的关键技术——如RNN、词嵌入和注意力机制。 通过这些理论与方法的融合,我们已经全面构建起深度学习的知识体系。

但深度学习远未停止发展。2026年的今天:

  • 大语言模型:ChatGPT、Claude、GPT-5等能力持续提升
  • 多模态模型:CLIP、Flamingo等统一处理图像和文本
  • 高效训练:Flash Attention、混合精度、模型并行让训练更快
  • 边缘部署:模型压缩、量化让AI能在手机和IoT设备运行

技术在快速演进,但核心原理保持稳定。掌握了这门课程的内容,你已经具备了深度学习的坚实基础。无论未来出现什么新模型,理解它们的原理、调试训练过程、优化性能,都离不开这些基础知识。 接下来我们建议你:

  • 实践项目:从Kaggle选一个竞赛题目,完整实现一遍——数据处理、模型训练、超参数调优、结果分析。
  • 阅读论文:从经典论文开始(AlexNet、ResNet、Transformer),理解它们的创新点和局限。
  • 参与社区:GitHub上的开源项目、论文复现、技术博客,都是学习的好途径。
  • 持续学习:深度学习每年都有新突破。关注顶会(NeurIPS、ICML、CVPR),保持对前沿的了解。

深度学习的魅力在于,它仍在快速发展。你学到的不仅是现有的技术,更是一种思维方式——如何将问题形式化、如何设计模型、如何通过数据驱动的实验改进。这些能力在AI的下一个十年仍将重要。

祝你在深度学习的道路上不断探索、不断进步!

  • Seq2Seq模型:从序列到序列
  • 注意力机制:动态聚焦
  • Beam Search:寻找最优序列
  • 从RNN到Transformer
  • 从基础到前沿

目录

  • Seq2Seq模型:从序列到序列
  • 注意力机制:动态聚焦
  • Beam Search:寻找最优序列
  • 从RNN到Transformer
  • 从基础到前沿
自在学

© 2025 - 2026 自在学,保留所有权利。

公网安备湘公网安备43020302000292号 | 湘ICP备2025148919号-1

关于我们隐私政策使用条款

© 2025 自在学,保留所有权利。

公网安备湘公网安备43020302000292号湘ICP备2025148919号-1