词嵌入与自然语言处理
15 / 15
自在学
首页课程创意工坊价格
首页课程创意工坊价格
编程深度学习序列到序列模型与注意力机制

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

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​)
|
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​。

|
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. 重复直到所有候选都生成结束标记
|
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的序列成为可能。

|
# 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 自在学,保留所有权利。

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

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

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

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