Files
Notes/机器学习/深度学习模型/2-序列模型/2-LSTM-长短期记忆网络.md
2026-05-16 17:16:51 +08:00

321 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 2-LSTM-长短期记忆网络
draft: false
tags:
- LSTM
- 长短期记忆
- 序列模型
- 深度学习
---
# LSTMLong Short-Term Memory详解笔记
## 1. 为什么需要 LSTM
普通 RNN 的目标是处理序列数据也就是输入在时间上有顺序依赖的数据例如文本、语音、时间序列、视频帧等。RNN 的基本思想是:在每个时刻 $t$,不仅看当前输入 $x_t$,还看上一时刻的隐藏状态 $h_{t-1}$,从而得到当前隐藏状态 $h_t$。形式上可以写成:
$$
h_t = \phi(W_x x_t + W_h h_{t-1} + b)
$$
其中 $\phi$ 常常是 $\tanh$ 或 $\mathrm{ReLU}$$W_x, W_h, b$ 是参数。
这个结构的核心问题在于:它虽然能“记住过去”,但记忆能力很差。因为隐藏状态每一步都要经过非线性变换和反复矩阵乘法,时间一长,早期信息就容易在传播中衰减掉。这就是经典的“长期依赖”难题。
更准确地说RNN 在反向传播时会出现梯度消失和梯度爆炸问题。梯度消失意味着越早的时间步对最终损失的影响越难传回来,模型就很难学到“很久以前的信息到底该不该保留”。而 LSTM 正是为了解决这个问题而提出的。
## 2. LSTM 的核心思想
LSTM 的关键不是“更复杂”,而是“更会记”。它在 RNN 的基础上引入了一个新的记忆状态,通常记作 $c_t$,叫做 cell state细胞状态、记忆单元。可以把它理解成一条相对稳定的“记忆通道”信息可以沿着这条通道更直接地流动而不是每一步都被强烈改写。
LSTM 通过三个门来控制信息流动:
1. 遗忘门 $f_t$:决定上一时刻记忆 $c_{t-1}$ 有多少要保留;
2. 输入门 $i_t$:决定当前输入中有多少信息写入记忆;
3. 输出门 $o_t$:决定当前时刻从记忆中输出多少作为隐藏状态 $h_t$。
这三个门的值一般都在 $[0,1]$ 之间,因此可以看成“比例开关”。值越接近 1表示保留/写入/输出得越多;越接近 0表示越少。
## 3. LSTM 的标准数学形式
设当前输入为 $x_t$,上一时刻隐藏状态为 $h_{t-1}$,上一时刻细胞状态为 $c_{t-1}$。LSTM 的计算一般包括以下几步:
### 3.1 遗忘门
$$
f_t = \sigma(W_f [h_{t-1}, x_t] + b_f)
$$
这里 $[h_{t-1}, x_t]$ 表示把两个向量拼接起来,$\sigma$ 是 sigmoid 函数:
$$
\sigma(z) = \frac{1}{1+e^{-z}}
$$
因为 sigmoid 输出在 $[0,1]$,所以 $f_t$ 可以逐维地控制上一时刻记忆的保留比例。
### 3.2 输入门与候选记忆
输入门:
$$
i_t = \sigma(W_i [h_{t-1}, x_t] + b_i)
$$
候选记忆:
$$
\tilde{c}_t = \tanh(W_c [h_{t-1}, x_t] + b_c)
$$
其中 $\tilde{c}_t$ 表示“当前时刻准备写入的新内容候选”。它先经过 $\tanh$ 压缩到 $[-1,1]$,这样数值稳定一些。
### 3.3 更新细胞状态
这是 LSTM 最关键的一步:
$$
c_t = f_t \odot c_{t-1} + i_t \odot \tilde{c}_t
$$
其中 $\odot$ 表示按元素乘法。
这一步非常重要,它表达了两个动作:
- 旧记忆通过 $f_t$ 被选择性保留;
- 新信息通过 $i_t$ 被选择性写入。
这意味着记忆更新不再是“强行全覆盖”,而是“保留旧的,同时加入新的”。
### 3.4 输出门与隐藏状态
输出门:
$$
o_t = \sigma(W_o [h_{t-1}, x_t] + b_o)
$$
隐藏状态:
$$
h_t = o_t \odot \tanh(c_t)
$$
这里 $\tanh(c_t)$ 是对当前记忆内容做一个非线性压缩,再由输出门决定输出多少。
所以 LSTM 的本质可以概括为:
先决定“忘多少”,再决定“写多少”,最后决定“输出多少”。
## 4. 从信息流角度理解 LSTM
如果只看 RNN 的递推:
$$
h_t = \phi(W_x x_t + W_h h_{t-1} + b)
$$
每一步都要把全部历史压缩到一个新的隐藏状态里,历史信息会不断被“重编码”。这就像你每看一页书,都把整本书重新手写一遍,时间一长必然丢信息。
而 LSTM 把信息分成两条流:
- 一条是相对稳定的记忆流 $c_t$
- 一条是当前可见状态流 $h_t$。
记忆流不像普通 RNN 那样每次都被大幅变形,而是通过门控做“增量更新”。这就是它能保留长期信息的原因。
## 5. 为什么 LSTM 能缓解梯度消失
这是 LSTM 最值得认真理解的地方。
在普通 RNN 中,隐藏状态是连续嵌套的非线性函数,反向传播时梯度要经过很多次矩阵乘法和激活函数导数。如果这些导数大多小于 1梯度就会指数级衰减。
LSTM 的关键在于细胞状态更新公式:
$$
c_t = f_t \odot c_{t-1} + i_t \odot \tilde{c}_t
$$
注意这里对 $c_{t-1}$ 的传递是“加法”而不是“纯乘法嵌套”。如果在某些维度上 $f_t \approx 1$,那么 $c_{t-1}$ 可以较完整地传到 $c_t$,再传到更远的时刻。也就是说,梯度可以沿着这条近似线性的通道流动,减少了衰减。
更具体地看,如果只考虑 $c_t$ 对 $c_{t-1}$ 的局部导数,有:
$$
\frac{\partial c_t}{\partial c_{t-1}} = f_t
$$
因为 $f_t$ 的值在 $[0,1]$,所以它可以通过学习来决定保留多少梯度。如果模型发现某段信息很重要,它可以让对应维度的遗忘门接近 1从而让信息长距离传递如果不重要则让其接近 0快速遗忘。
这就是 LSTM 比 RNN 更适合长序列的根本原因。
## 6. LSTM 的“门”到底在做什么
可以把三个门理解成三个非常具体的控制器。
遗忘门 $f_t$ 负责“删旧内容”。例如在语言模型里,前文已经提到的主语可能在后面若干个词后仍然有用,但无关的修饰语就可以逐步遗忘。遗忘门让模型学会对不同维度的记忆进行不同程度的保留。
输入门 $i_t$ 负责“写新内容”。它不是盲目接受当前输入,而是判断当前输入中哪些信息值得写进长期记忆。比如在语音识别里,有些当前帧的细节只是局部噪声,不值得写入状态。
输出门 $o_t$ 负责“读出内容”。记忆不一定每一步都全部输出,输出门决定当前时刻应暴露多少内部状态给外部使用。这样既保持了内部记忆的稳定,也保留了对外输出的灵活性。
## 7. LSTM 和普通 RNN 的对比
### 7.1 结构上的区别
RNN 的状态更新很简单基本上就是一个递推函数LSTM 则多了记忆状态和门控机制。RNN 可以看成“单状态递推”LSTM 可以看成“带控制的双通道递推”。
### 7.2 表达能力上的区别
RNN 更容易记短期关系但长期关系难学。LSTM 通过记忆单元和门控机制,更容易建模长距离依赖,比如句子开头的主语和句末的谓语一致性、时间序列里很久以前的趋势影响等。
### 7.3 训练稳定性上的区别
RNN 训练时更容易出现梯度消失或爆炸。LSTM 因为有更好的梯度通路,训练通常更稳定。
### 7.4 代价上的区别
LSTM 不是白来的。它参数更多、计算更慢、显存占用更高。一个标准 LSTM 单元需要多组权重矩阵,开销明显大于普通 RNN。所以它的优势来自更复杂的结构代价是更高的计算成本。
## 8. LSTM 的参数形式与维度理解
如果输入维度是 $d_x$,隐藏状态维度是 $d_h$,那么拼接向量 $[h_{t-1}, x_t]$ 的维度是 $d_h + d_x$。
因此各门权重矩阵的形状通常是:
$$
W_f, W_i, W_c, W_o \in \mathbb{R}^{d_h \times (d_h + d_x)}
$$
偏置向量:
$$
b_f, b_i, b_c, b_o \in \mathbb{R}^{d_h}
$$
这意味着 LSTM 每个时间步都要做四次线性变换,再加上多次非线性操作,所以它比简单 RNN 计算更重。
如果是多层 LSTM那么上一层每个时间步的隐藏状态 $h_t^{(l)}$ 会作为下一层的输入 $x_t^{(l+1)}$。这样可以形成更深的时序特征抽象。
## 9. 训练过程LSTM 是怎么学出来的
LSTM 的训练本质上仍然是监督学习或自监督学习,只是网络结构换成了 LSTM。训练流程一般包括前向传播、损失计算、反向传播和参数更新。
### 9.1 前向传播
给定一个序列输入:
$$
x_1, x_2, \dots, x_T
$$
模型按时间顺序依次计算:
$$
f_t, i_t, \tilde{c}_t, c_t, o_t, h_t
$$
最后根据任务输出预测值。比如:
- 文本分类:使用最后时刻的 $h_T$ 作为分类依据;
- 序列标注:每个时刻都输出一个标签;
- 语言模型:每个时刻预测下一个词。
### 9.2 损失函数
损失函数取决于任务。比如分类常用交叉熵:
$$
\mathcal{L} = - \sum_k y_k \log \hat{y}_k
$$
序列预测则可能用每个时间步损失的和:
$$
\mathcal{L} = \sum_{t=1}^T \ell_t
$$
### 9.3 反向传播BPTT
LSTM 的反向传播通常使用 BPTTBackpropagation Through Time时间反向传播
思想是:把时间展开成一个很深的计算图,然后从后往前逐步求梯度。比如最终损失对某个早期参数的影响,会沿着时间链条逐步传回去。
这里 LSTM 的优势就体现出来了:由于 $c_t$ 的更新中存在较强的线性通路,梯度能比普通 RNN 更顺利地穿过多个时间步。
### 9.4 参数更新
参数可用 SGD、Momentum、Adam 等优化方法更新,例如:
$$
\theta \leftarrow \theta - \eta \nabla_\theta \mathcal{L}
$$
其中 $\eta$ 是学习率,$\theta$ 代表所有可训练参数。
---
## 10. 局限性分析
尽管 LSTM 功能强大,但在面对极长序列或大规模并行需求时仍存在短板:
- **梯度问题依然存在:** 它只是“缓解”而非“根治”。在超长序列(如数千步)中仍需配合 **梯度裁剪 (Gradient Clipping)** 使用。
- **并行性缺陷:** 由于 $h_t$ 强依赖于 $h_{t-1}$,模型无法像 Transformer 那样实现全序列并行化训练。
- **记忆容量限制:** 作为一个固定维度的向量,细胞状态 $c_t$ 的承载能力有限,难以完美记录所有历史细节。
## 11. 实战技巧与变体
- **双向 LSTM (BiLSTM)** 同时捕捉“过去”与“未来”的信息,常用于翻译和命名实体识别。
- **Peephole Connections** 让门控结构直接观察 $c_t$,增强对精确时间的控制能力。
- **调参建议:**
- **Dropout** 在层间使用,防止过拟合。
- **归一化:** 输入数据务必进行标准化,加速收敛。
- **截断 BPTT** 对于超长序列,只在一定窗口内传播梯度。
## 12. 典型应用场景
LSTM 目前仍是以下领域的核心工具:
- **时序建模:** 股票价格预测、传感器异常检测。
- **自然语言处理:** 情感分析、序列标注、机器翻译(作为 Encoder-Decoder 基础)。
- **信号处理:** 语音识别、心电图ECG分析。
## 13. 核心精髓总结
如果将循环神经网络的演进做个比喻:
- **普通 RNN** 像是一直把记忆揉成一个球传下去,传得越远,球表面的字迹越模糊。
- **LSTM** 像是一个**带旋转开关的记忆柜**。
- **遗忘门:** 清理过期文件。
- **输入门:** 筛选新入库信息。
- **输出门:** 决定向外展示哪些内容。
> **结论:** LSTM 的核心强项不在于它能“记住全部”,而在于它拥有出色的**“选择性记忆”**能力。
## 14. 衍生结构GRU
作为 LSTM 的“轻量化”版本,**GRU (Gated Recurrent Unit)** 合并了遗忘门和输入门,只有两个门控。它在保持大部分性能的同时,参数更少、计算速度更快,是追求效率时的首选。