LSTM 模型 - 代码实现
1 课程概览
本课讲解 LSTM 的 API 和代码实现。LSTM 的 API 较之于传统 RNN 多了一个 C0(细胞状态),传参时需要传 H0 和 C0,返回也是本次的隐藏状态和本次更新后的记忆细胞。
2 核心概念与定义
- LSTM API:比 RNN 多一个 C0(细胞状态)。
- C0:初始细胞状态,与隐藏状态一样。
- input_size:词向量维度。
- hidden_size:隐藏层维度。
- num_layers:LSTM 隐藏层层数。
- bidirectional:是否双向。
3 模型与算法详解
LSTM 简介
长短时记忆结构。
- 全称:Long Short-Term Memory
- 作用:解决传统 RNN 处理长序列数据效果差的问题
LSTM 组成
3 门 + 1 状态。
| 组成 | 说明 |
|---|---|
| 遗忘门 | 决定忘掉哪些记忆 |
| 输入门 | 决定加入哪些新信息 |
| 细胞状态 | 长期记忆 |
| 输出门 | 决定输出哪些信息 |
LSTM 的优点
- 能够解决长序列依赖问题
- 缓解梯度消失和爆炸问题,训练更稳定
- 能够抓取复杂的特征
LSTM 的缺点
- 计算慢,消耗资源大(4 个神经网络)
- 调参相对较难(参数太多)
- 可解释性稍差
LSTM API
比 RNN 多一个 C0。
lstm = nn.LSTM(input_size, hidden_size, num_layers,
batch_first=True, bidirectional=False)
传参
需要传 H0 和 C0。
output, (hn, cn) = lstm(input, (h0, c0))
4 数学原理与推导
LSTM 前向传播
$$f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f)$$
$$i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i)$$
$$\tilde{C}t = \tanh(W_C \cdot [h{t-1}, x_t] + b_C)$$
$$C_t = f_t \cdot C_{t-1} + i_t \cdot \tilde{C}_t$$
$$o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o)$$
$$h_t = o_t \cdot \tanh(C_t)$$
5 代码示例
import torch
import torch.nn as nn
def demo_lstm():
"""演示 LSTM 模型的用法"""
# 1. 创建 LSTM 模型对象
# 参数1: input_size, 词向量维度(5)
# 参数2: hidden_size, 隐藏层维度(6)
# 参数3: num_layers, 隐藏层层数(1)
# 参数4: bidirectional, 是否双向(False)
lstm = nn.LSTM(
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. 创建初始隐藏状态和细胞状态
# [num_layers, batch_size, hidden_size]
h0 = torch.zeros(1, 1, 6)
c0 = torch.zeros(1, 1, 6)
# 4. 运行 LSTM 模型
output, (hn, cn) = lstm(input_data, (h0, c0))
# 5. 打印结果
print(f"输入: {input_data.shape}")
print(f"输出: {output.shape}")
print(f"隐藏状态: {hn.shape}")
print(f"细胞状态: {cn.shape}")
# 测试
if __name__ == "__main__":
print("=== LSTM 模型代码演示 ===")
demo_lstm()
代码说明
| 代码 | 说明 |
|---|---|
nn.LSTM(...) | 创建 LSTM 模型 |
input_size=5 | 词向量维度 |
hidden_size=6 | 隐藏层维度 |
num_layers=1 | 隐藏层层数 |
bidirectional=False | 单向 |
h0 = torch.zeros(1, 1, 6) | 初始隐藏状态 |
c0 = torch.zeros(1, 1, 6) | 初始细胞状态 |
output, (hn, cn) = lstm(...) | 前向传播 |
6 重难点与易错提醒
- ❗重点:LSTM API 比 RNN 多一个 C0(细胞状态)。
- ❗重点:传参时需要传 H0 和 C0。
- ❗重点:返回也是本次的隐藏状态和本次更新后的记忆细胞。
- ⚠️易错:C0 的维度与 H0 一样。
- 💡技巧:参数 561(许三多)便于记忆。
7 课堂问答精选
Q1:LSTM 的 API 与 RNN 有什么区别?
A:LSTM 的 API 比 RNN 多一个 C0(细胞状态),传参时需要传 H0 和 C0,返回也是本次的隐藏状态和本次更新后的记忆细胞。
Q2:LSTM 的优缺点是什么?
A:优点:①解决长序列依赖问题;②缓解梯度消失和爆炸;③抓取复杂特征。缺点:①计算慢,消耗资源大;②调参较难;③可解释性稍差。
Q3:LSTM 的参数有哪些?
A:参数1:input_size(词向量维度);参数2:hidden_size(隐藏层维度);参数3:num_layers(隐藏层层数);参数4:bidirectional(是否双向)。
8 本课小结
- LSTM API 比 RNN 多一个 C0(细胞状态)。
- 传参时需要传 H0 和 C0。
- 返回也是本次的隐藏状态和本次更新后的记忆细胞。
- LSTM 的优缺点。
9 延伸思考
- GRU 模型是什么?
- GRU 和 LSTM 有什么区别?