logo

深度解析:斯坦福NLP第6讲——循环神经网络与语言模型全览

作者:JC2025.09.26 18:40浏览量:0

简介:本文基于斯坦福大学NLP课程第6讲,系统梳理循环神经网络(RNN)与语言模型的核心原理、技术实现及应用场景,结合理论推导与代码示例,为NLP开发者提供从基础到进阶的完整学习路径。

一、循环神经网络(RNN)的底层逻辑与序列建模优势

1.1 传统神经网络的序列处理缺陷

传统前馈神经网络(FNN)采用固定输入维度,无法直接处理变长序列数据(如文本、语音)。例如,在句子分类任务中,FNN需将整个句子编码为固定长度的向量,导致:

  • 信息丢失:长序列中关键信息可能被截断或稀释;
  • 参数冗余:需为不同长度序列设计独立模型。

1.2 RNN的核心创新:时间步递归与隐藏状态

RNN通过引入隐藏状态(Hidden State)实现序列信息的动态传递。其数学表达为:
[
ht = \sigma(W{hh}h{t-1} + W{xh}xt + b_h)
]
[
y_t = \text{softmax}(W
{hy}ht + b_y)
]
其中,(h_t)为第(t)步的隐藏状态,融合了当前输入(x_t)与上一时刻状态(h
{t-1})的信息。这种设计使RNN能够:

  • 处理变长输入:通过递归展开适应任意长度序列;
  • 捕捉长期依赖:理论上可通过无限步递归记忆全部历史信息。

1.3 梯度消失与梯度爆炸问题

RNN的递归结构导致反向传播时梯度呈指数级衰减或增长:

  • 梯度消失:长序列中早期步骤的梯度趋近于0,模型无法学习远距离依赖(如“The cat…was cute”中“cat”与“was”的主谓关系);
  • 梯度爆炸:梯度数值过大导致训练不稳定。

解决方案

  • 梯度裁剪(Gradient Clipping):限制梯度最大范数;
  • 门控机制(Gated RNN):如LSTM、GRU,通过引入可学习的门控单元控制信息流。

二、LSTM与GRU:门控机制破解长期依赖难题

2.1 LSTM的三大核心组件

LSTM(长短期记忆网络)通过以下结构实现选择性记忆:

  1. 输入门(Input Gate):控制当前输入信息进入细胞状态的流量;
  2. 遗忘门(Forget Gate):决定上一时刻细胞状态中哪些信息被丢弃;
  3. 输出门(Output Gate):调节细胞状态对当前隐藏状态的贡献。

数学表达如下:
[
\begin{align}
ft &= \sigma(W_f \cdot [h{t-1}, xt] + b_f) \quad \text{(遗忘门)} \
i_t &= \sigma(W_i \cdot [h
{t-1}, xt] + b_i) \quad \text{(输入门)} \
\tilde{C}_t &= \tanh(W_C \cdot [h
{t-1}, xt] + b_C) \quad \text{(候选细胞状态)} \
C_t &= f_t \odot C
{t-1} + it \odot \tilde{C}_t \quad \text{(细胞状态更新)} \
o_t &= \sigma(W_o \cdot [h
{t-1}, x_t] + b_o) \quad \text{(输出门)} \
h_t &= o_t \odot \tanh(C_t) \quad \text{(隐藏状态输出)}
\end{align
}
]

2.2 GRU的简化设计

GRU(门控循环单元)合并了LSTM的细胞状态与隐藏状态,仅保留两个门控:

  1. 重置门(Reset Gate):决定忽略多少历史信息;
  2. 更新门(Update Gate):控制新信息与旧信息的混合比例。

其优势在于参数更少、训练更快,适合资源受限场景。

三、语言模型:从统计到神经网络的演进

3.1 统计语言模型(N-gram)的局限性

N-gram模型基于马尔可夫假设,通过统计词频计算条件概率:
[
P(wt|w{t-n+1},\dots,w{t-1}) = \frac{\text{Count}(w{t-n+1},\dots,wt)}{\text{Count}(w{t-n+1},\dots,w_{t-1})}
]
问题

  • 数据稀疏性:高阶N-gram(如5-gram)在训练集中可能未出现;
  • 上下文窗口固定:无法捕捉全局依赖。

3.2 神经语言模型(NNLM)的突破

NNLM使用前馈神经网络预测下一个词的概率分布:

  1. 输入层:将前(n-1)个词映射为低维词向量;
  2. 隐藏层:非线性变换提取特征;
  3. 输出层:softmax函数生成词汇表概率。

优势

  • 参数共享:词向量层减少数据稀疏影响;
  • 上下文扩展:通过增加隐藏层深度捕捉更远依赖。

3.3 RNN语言模型(RNN-LM)的实现

RNN-LM直接以序列为输入,递归预测每个位置的词:
[
P(w1,\dots,w_T) = \prod{t=1}^T P(wt|w_1,\dots,w{t-1})
]
训练技巧

  • 交叉熵损失:最小化预测分布与真实分布的KL散度;
  • 教师强制(Teacher Forcing):训练时使用真实前文而非预测结果,稳定梯度传播。

四、实战:基于PyTorch的RNN-LM代码解析

4.1 数据预处理

  1. import torch
  2. from torch.nn.utils.rnn import pad_sequence
  3. # 示例:构建词汇表与序列填充
  4. text = "the cat sat on the mat".split()
  5. vocab = {"<pad>": 0, "<unk>": 1}
  6. vocab.update({word: i+2 for i, word in enumerate(set(text))})
  7. # 序列编码与填充
  8. sequences = [[vocab.get(word, vocab["<unk>"]) for word in ["the", "cat"]],
  9. [vocab.get(word, vocab["<unk>"]) for word in ["the", "mat"]]]
  10. padded_sequences = pad_sequence([torch.tensor(s) for s in sequences],
  11. batch_first=True, padding_value=vocab["<pad>"])

4.2 模型定义

  1. import torch.nn as nn
  2. class RNNLM(nn.Module):
  3. def __init__(self, vocab_size, embed_dim, hidden_dim, num_layers):
  4. super().__init__()
  5. self.embedding = nn.Embedding(vocab_size, embed_dim)
  6. self.rnn = nn.RNN(embed_dim, hidden_dim, num_layers, batch_first=True)
  7. self.fc = nn.Linear(hidden_dim, vocab_size)
  8. def forward(self, x):
  9. # x: [batch_size, seq_len]
  10. embedded = self.embedding(x) # [batch_size, seq_len, embed_dim]
  11. output, hidden = self.rnn(embedded) # output: [batch_size, seq_len, hidden_dim]
  12. logits = self.fc(output) # [batch_size, seq_len, vocab_size]
  13. return logits

4.3 训练与评估

  1. model = RNNLM(vocab_size=len(vocab), embed_dim=64, hidden_dim=128, num_layers=2)
  2. criterion = nn.CrossEntropyLoss(ignore_index=vocab["<pad>"])
  3. optimizer = torch.optim.Adam(model.parameters())
  4. # 假设输入为padded_sequences,目标为右移一位的序列
  5. inputs = padded_sequences[:, :-1]
  6. targets = padded_sequences[:, 1:]
  7. # 训练步骤
  8. outputs = model(inputs) # [batch_size, seq_len-1, vocab_size]
  9. loss = criterion(outputs.view(-1, outputs.size(-1)), targets.view(-1))
  10. optimizer.zero_grad()
  11. loss.backward()
  12. optimizer.step()

五、应用场景与优化方向

5.1 典型应用

  • 机器翻译:编码器-解码器框架中的序列生成;
  • 文本生成:基于条件RNN的诗歌、对话生成;
  • 语音识别:结合CTC损失的时序对齐。

5.2 性能优化

  • 双向RNN:融合前向与后向上下文信息;
  • 注意力机制:动态聚焦关键历史步骤;
  • Transformer替代:在长序列场景中,自注意力机制可替代RNN。

六、总结与学习建议

本讲深入剖析了RNN在序列建模中的核心地位,从基础结构到门控变体(LSTM/GRU),再到语言模型的神经化演进。对于开发者,建议:

  1. 动手实现:通过PyTorch/TensorFlow复现RNN-LM,理解梯度传播细节;
  2. 对比实验:比较FNN、RNN、LSTM在长序列任务中的表现差异;
  3. 关注前沿:学习Transformer如何通过自注意力机制解决RNN的并行化问题。

下一讲将聚焦注意力机制与Transformer架构,揭示NLP进入“预训练时代”的技术基石。

相关文章推荐

发表评论

活动