GRU 模型 - 代码演示
1 课程概览
本课讲解 GRU 模型的 API 和代码实现。GRU 的 API 与 RNN 一模一样,只需要把 nn.RNN 换成 nn.GRU,其他参数都不变。GRU 只需要传 H0,不需要传 C0。
2 核心概念与定义
- GRU API:与 RNN 一模一样,只换
nn.RNN为nn.GRU。 - 重置门(Reset Gate):对上部要使用多少。
- 更新门(Update Gate):本次内部要使用多少。
3 模型与算法详解
GRU 简介
门控循环单元,简化版的 LSTM。
- 全称:Gate Recurrent Unit
- 作用:既能像 LSTM 那样处理长序列信息,计算上也更简单、更节省资源
- 核心设计思路:重置门和更新门
GRU 的优点
- 和 LSTM 一样,能够有效捕捉长序列之间的语义关联,缓解梯度消失和爆炸问题
- 关于长序列的处理效果优于 RNN
- 计算复杂度比 LSTM 要小
GRU 的缺点
- 不能完全解决梯度消失和爆炸问题
- 不能并行计算
- 在数据量和模型体量逐步增大的未来,是 RNN 发展的关键瓶颈
GRU API
与 RNN 一模一样。
gru = nn.GRU(input_size, hidden_size, num_layers,
batch_first=True, bidirectional=False)
GRU vs RNN
| 特性 | RNN | GRU |
|---|---|---|
| API | nn.RNN | nn.GRU |
| 参数 | 一样 | 一样 |
| 传参 | H0 | H0 |
| 返回 | output, hn | output, hn |
4 数学原理与推导
GRU 前向传播
$$r_t = \sigma(W_r \cdot [h_{t-1}, x_t] + b_r)$$
$$z_t = \sigma(W_z \cdot [h_{t-1}, x_t] + b_z)$$
$$\tilde{h}t = \tanh(W \cdot [r_t \cdot h{t-1}, x_t] + b)$$
$$h_t = (1 - z_t) \cdot h_{t-1} + z_t \cdot \tilde{h}_t$$
5 代码示例
import torch
import torch.nn as nn
def gru_demo1():
"""演示 GRU 模型的用法"""
# 1. 创建 GRU 模型对象
# 参数1: input_size, 词向量维度(5)
# 参数2: hidden_size, 隐藏层维度(6)
# 参数3: num_layers, 隐藏层层数(1)
# 参数4: bidirectional, 是否双向(False)
gru = nn.GRU(
input_size=5,
hidden_size=6,
num_layers=1,
batch_first=True,
bidirectional=False
)
# 2. 创建输入数据
# [batch_size, seq_len, input_size]
input_data = torch.randn(1, 3, 5)
# 3. 创建初始隐藏状态(GRU 没有细胞状态)
# [num_layers, batch_size, hidden_size]
h0 = torch.zeros(1, 1, 6)
# 4. 运行 GRU 模型
output, hn = gru(input_data, h0)
# 5. 打印结果
print(f"输入: {input_data.shape}")
print(f"输出: {output.shape}")
print(f"隐藏状态: {hn.shape}")
# 测试
if __name__ == "__main__":
print("=== GRU 模型代码演示 ===")
gru_demo1()
代码说明
| 代码 | 说明 |
|---|---|
nn.GRU(...) | 创建 GRU 模型(与 RNN 一样) |
input_size=5 | 词向量维度 |
hidden_size=6 | 隐藏层维度 |
num_layers=1 | 隐藏层层数 |
bidirectional=False | 单向 |
h0 = torch.zeros(1, 1, 6) | 初始隐藏状态(没有 C0) |
output, hn = gru(...) | 前向传播(没有 cn) |
6 重难点与易错提醒
- ❗重点:GRU 的 API 与 RNN 一模一样,只换
nn.RNN为nn.GRU。 - ❗重点:GRU 只需要传 H0,不需要传 C0。
- ❗重点:GRU 返回 output 和 hn,没有 cn。
- 💡技巧:可以复制 RNN 的代码,只改一个地方。
7 课堂问答精选
Q1:GRU 的 API 与 RNN 有什么区别?
A:没有区别,只需要把 nn.RNN 换成 nn.GRU,其他参数都不变。
Q2:GRU 的优缺点是什么?
A:优点:①捕捉长序列语义关联;②缓解梯度消失和爆炸;③计算复杂度比 LSTM 小。缺点:①不能完全解决梯度消失和爆炸;②不能并行计算。
Q3:GRU 和 LSTM 的 API 有什么区别?
A:LSTM 需要传 H0 和 C0,返回 output, (hn, cn);GRU 只需要传 H0,返回 output, hn。
8 本课小结
- GRU 的 API 与 RNN 一模一样,只换
nn.RNN为nn.GRU。 - GRU 只需要传 H0,不需要传 C0。
- GRU 返回 output 和 hn,没有 cn。
- 可以复制 RNN 的代码,只改一个地方。
9 延伸思考
- RNN 人名分类案例的需求是什么?
- 如何构建数据集对象?