在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的设计思想和门控机制仍然是理解现代序列建模的基础。