在6.28号我发了一个博客《RNN(循环神经网络)与LSTM(长短期记忆网络)输出的详细对比分析》,但是我并未详细讲解LSTM,LSTM是循环神经网络中的一个模型,然而通过这篇博客给大家深度解析一下LSTM,重点关注其内部结构和参数。
LSTM是为了解决标准RNN在处理长序列时出现的梯度消失/爆炸问题而设计的一种特殊循环神经网络结构。它的核心在于引入了门控机制和细胞状态,使得网络能够有选择地记住或忘记信息。
核心思想:解决长期依赖问题
-
标准RNN的问题: RNN通过循环隐藏层处理序列。计算梯度时(如通过BPTT),梯度会随着时间步长呈指数级衰减(消失)或增长(爆炸),导致网络难以学习到序列中远距离元素之间的依赖关系。
-
LSTM的解决方案:
-
细胞状态: 引入一条贯穿整个序列的“信息高速公路”,称为细胞状态。这个状态的设计使得信息可以在其中相对无损地流动较长的距离。
-
门控机制: 使用三个“门”(由Sigmoid神经网络层和逐点乘法操作组成)来精细调控细胞状态:
-
遗忘门: 决定从细胞状态中丢弃哪些旧信息。
-
输入门: 决定将哪些新信息写入细胞状态。
-
输出门: 决定基于当前的细胞状态输出什么信息到隐藏状态。
-
-
LSTM单元的内部结构与计算流程(关键!)
想象一个LSTM单元在时间步 t
的处理过程。它接收三个输入:
-
当前时间步的输入:
x_t
(维度input_dim
) -
前一时间步的隐藏状态:
h_{t-1}
(维度hidden_dim
) -
前一时间步的细胞状态:
C_{t-1}
(维度hidden_dim
)
它产生两个输出:
-
当前时间步的隐藏状态:
h_t
(维度hidden_dim
) -
当前时间步的细胞状态:
C_t
(维度hidden_dim
)
单元内部的计算涉及以下步骤:
-
遗忘门:
-
计算遗忘因子:
f_t = σ(W_f · [h_{t-1}, x_t] + b_f)
-
σ
是 Sigmoid 激活函数(输出 0 到 1)。 -
W_f
是权重矩阵(维度hidden_dim x (hidden_dim + input_dim)
)。 -
[h_{t-1}, x_t]
表示将h_{t-1}
和x_t
拼接成一个向量(维度hidden_dim + input_dim
)。 -
b_f
是偏置向量(维度hidden_dim
)。 -
f_t
的每个元素在 0(完全忘记)到 1(完全保留)之间,决定了C_{t-1}
中每个对应分量被保留的程度。
-
-
输入门 & 候选值:
-
输入门:
i_t = σ(W_i · [h_{t-1}, x_t] + b_i)
-
计算哪些新值需要更新到细胞状态。
i_t
在 0(不更新)到 1(完全更新)之间。
-
-
候选细胞状态:
g_t = tanh(W_g · [h_{t-1}, x_t] + b_g)
-
计算一个由当前输入和前一个隐藏状态生成的新的候选值向量,这些值是可能要加入到细胞状态中的。
-
tanh
激活函数将值压缩到 -1 到 1 之间。
-
-
W_i
,W_g
是各自的权重矩阵(维度同上),b_i
,b_g
是偏置向量。
-
-
更新细胞状态:
-
C_t = f_t * C_{t-1} + i_t * g_t
-
*
表示逐元素乘法。 -
这是LSTM的核心操作:
-
首先,用遗忘门
f_t
控制性地遗忘旧细胞状态C_{t-1}
的一部分。 -
然后,用输入门
i_t
控制性地添加候选值g_t
的一部分。 -
结果就是新的细胞状态
C_t
。这个操作(加法和乘法)允许梯度在C_t
上相对稳定地流动。
-
-
-
输出门:
-
o_t = σ(W_o · [h_{t-1}, x_t] + b_o)
-
计算基于细胞状态
C_t
应该输出哪些部分到隐藏状态h_t
。o_t
在 0(不输出)到 1(完全输出)之间。
-
-
W_o
是权重矩阵,b_o
是偏置向量。
-
-
计算当前隐藏状态:
-
h_t = o_t * tanh(C_t)
-
首先,将新的细胞状态
C_t
通过tanh
激活(将其值规范到 -1 到 1 之间)。 -
然后,用输出门
o_t
控制性地输出tanh(C_t)
的一部分。这个h_t
就是当前时间步的输出(如果需要预测,比如y_t
,通常会对h_t
应用一个额外的全连接层W_y * h_t + b_y
),同时也是下一个时间步的输入之一。
-
可视化表示(简化)
LSTM的内部参数详解
从上面的计算过程可以看出,一个标准的LSTM单元包含以下参数:
-
权重矩阵 (Weights): 共有 4 组,分别对应遗忘门、输入门、候选值、输出门。
-
W_f
: 遗忘门的权重矩阵 (维度:hidden_dim x (hidden_dim + input_dim)
) -
W_i
: 输入门的权重矩阵 (维度:hidden_dim x (hidden_dim + input_dim)
) -
W_g
: 候选细胞状态的权重矩阵 (维度:hidden_dim x (hidden_dim + input_dim)
) -
W_o
: 输出门的权重矩阵 (维度:hidden_dim x (hidden_dim + input_dim)
)
-
-
偏置向量 (Biases): 共有 4 组,与权重矩阵一一对应。
-
b_f
: 遗忘门的偏置向量 (维度:hidden_dim
) -
b_i
: 输入门的偏置向量 (维度:hidden_dim
) -
b_g
: 候选细胞状态的偏置向量 (维度:hidden_dim
) -
b_o
: 输出门的偏置向量 (维度:hidden_dim
)
-
重要说明
-
参数共享: 同一个LSTM层中的所有时间步
t
共享同一套参数 (W_f
,W_i
,W_g
,W_o
,b_f
,b_i
,b_g
,b_o
)。这是RNN/LSTM的关键特性,使得模型能够处理任意长度的序列,并且大大减少了参数量(相比于为每个时间步都设置独立参数)。 -
参数总量计算: 对于一个LSTM层:
-
总参数量 =
4 * [hidden_dim * (hidden_dim + input_dim) + hidden_dim]
-
简化:
4 * (hidden_dim * hidden_dim + hidden_dim * input_dim + hidden_dim) = 4 * (hidden_dim^2 + hidden_dim * input_dim + hidden_dim)
-
例如:
input_dim=100
,hidden_dim=256
, 则参数量 =4 * (256*256 + 256*100 + 256) = 4 * (65536 + 25600 + 256) = 4 * 91392 = 365, 568
。可见,参数量主要受hidden_dim
的平方影响。
-
-
输入维度:
input_dim
是你的输入数据x_t
的特征维度。 -
隐藏层维度:
hidden_dim
是一个超参数,决定了:-
细胞状态
C_t
和隐藏状态h_t
的维度。 -
每个门(
f_t
,i_t
,o_t
)和候选值(g_t
)向量的维度。 -
模型的容量(表示能力)。更大的
hidden_dim
通常能学习更复杂的模式,但也需要更多计算资源和数据,更容易过拟合。
-
-
激活函数:
-
门(f, i, o): 使用 Sigmoid (
σ
),因为它输出 0-1,完美模拟“开关”或“比例控制器”的概念。 -
候选值(g)和 细胞状态输出: 使用 tanh,因为它输出 -1 到 1,有助于稳定梯度流(中心化在0附近),且能表示正负信息。
-
-
细胞状态 vs 隐藏状态:
-
细胞状态 (
C_t
):是LSTM的“记忆体”,承载着长期信息流。它主要受门控机制调控,其内部变换(加法和乘法)是梯度稳定流动的关键。 -
隐藏状态 (
h_t
):是LSTM在时间步t
的“输出表示”。它由输出门o_t
基于当前的细胞状态C_t
过滤后得到。h_t
是传递给下一个时间步(作为h_{t-1}
)和/或用于当前时间步预测的输出。
-
LSTM如何解决长期依赖问题?
-
细胞状态作为信息高速公路:
C_t = f_t * C_{t-1} + i_t * g_t
这个设计是核心。梯度可以通过C_t
直接流向C_{t-1}
(通过加法操作+
),而不会像标准RNN那样在每个时间步都经过压缩性的激活函数(如tanh
)导致指数级衰减。乘法操作f_t *
虽然也可能导致梯度消失,但f_t
是由网络学习的,它可以选择让某些维度的遗忘因子接近1(即完全保留),使得对应维度上的梯度可以几乎无损地流过很多时间步。 -
门控机制赋予选择性: 三个门让LSTM拥有强大的能力:
-
有选择地遗忘: 遗忘门
f_t
可以主动丢弃与当前任务无关的旧信息(例如,在分析一个新句子时,忘记前一个句子的主题)。 -
有选择地记忆: 输入门
i_t
可以决定哪些新信息是重要的,需要加入到长期记忆中(例如,记住当前句子中的关键实体)。 -
有选择地输出: 输出门
o_t
可以根据当前细胞状态和任务需求,决定输出哪些信息给隐藏状态(例如,在情感分析中,可能只需要输出与情感相关的特征)。
-
-
加法更新: 新细胞状态是通过 加法 (
+
) 来更新的,而不是像标准RNN那样通过函数 变换。加法操作在反向传播时梯度是常数1(d(C_t)/d(C_{t-1}) = f_t
,且f_t
可以通过学习接近1),这大大缓解了梯度消失问题。乘法操作(f_t *
,i_t *
)虽然会导致梯度消失/爆炸,但门控信号f_t
,i_t
本身是Sigmoid输出且受网络控制,网络可以学会让这些门在需要长期记忆的位置保持打开(值接近1)。
变体与改进
-
Peephole Connections: 一些LSTM变体让门 (
f_t
,i_t
,o_t
) 的计算不仅依赖[h_{t-1}, x_t]
,也直接依赖C_{t-1}
或C_t
(如i_t = σ(W_i · [C_{t-1}, h_{t-1}, x_t] + b_i)
)。这被认为能提供更精细的时序控制。 -
GRU (Gated Recurrent Unit): 一个更流行的LSTM简化变体。它将遗忘门和输入门合并为一个“更新门”,并合并了细胞状态和隐藏状态。GRU通常参数更少,计算更快,在很多任务上与LSTM性能相当。
-
Bidirectional LSTM (BiLSTM): 同时运行前向和后向两个LSTM层,并将它们的隐藏状态(通常在对应时间步拼接)作为最终输出。这允许模型利用序列的过去和未来上下文信息,对许多序列标注和理解任务非常有效。
-
Stacked LSTM: 堆叠多个LSTM层,将前一层的隐藏状态序列作为下一层的输入序列。这可以学习更复杂的、分层次的时序表示。
总结
LSTM通过精心设计的细胞状态和门控机制(遗忘门、输入门、输出门),有效地解决了标准RNN在处理长序列时的长期依赖问题。其内部参数主要包括四组权重矩阵(W_f
, W_i
, W_g
, W_o
)和对应的偏置向量(b_f
, b_i
, b_g
, b_o
),这些参数在层内所有时间步共享。关键的细胞状态更新公式 C_t = f_t * C_{t-1} + i_t * g_t
通过加法操作维持了梯度的稳定流动,而Sigmoid门则赋予了模型有选择地遗忘、记忆和输出信息的强大能力。理解这些内部结构和参数的作用,对于有效使用、调优LSTM模型以及在实践中诊断问题至关重要。虽然GRU等变体在某些场景下可能更受欢迎,但LSTM的设计思想和门控机制仍然是理解现代序列建模的基础。