LSTM(Long Short-Term Memory)模型的深度解析

在6.28号我发了一个博客《RNN(循环神经网络)与LSTM(长短期记忆网络)输出的详细对比分析》,但是我并未详细讲解LSTM,LSTM是循环神经网络中的一个模型,然而通过这篇博客给大家深度解析一下LSTM,重点关注其内部结构和参数。

LSTM是为了解决标准RNN在处理长序列时出现的梯度消失/爆炸问题而设计的一种特殊循环神经网络结构。它的核心在于引入了门控机制细胞状态,使得网络能够有选择地记住或忘记信息。

核心思想:解决长期依赖问题

  • 标准RNN的问题: RNN通过循环隐藏层处理序列。计算梯度时(如通过BPTT),梯度会随着时间步长呈指数级衰减(消失)或增长(爆炸),导致网络难以学习到序列中远距离元素之间的依赖关系。

  • LSTM的解决方案:

    • 细胞状态: 引入一条贯穿整个序列的“信息高速公路”,称为细胞状态。这个状态的设计使得信息可以在其中相对无损地流动较长的距离。

    • 门控机制: 使用三个“门”(由Sigmoid神经网络层和逐点乘法操作组成)来精细调控细胞状态:

      • 遗忘门: 决定从细胞状态中丢弃哪些旧信息。

      • 输入门: 决定将哪些新信息写入细胞状态。

      • 输出门: 决定基于当前的细胞状态输出什么信息到隐藏状态。

LSTM单元的内部结构与计算流程(关键!)

想象一个LSTM单元在时间步 t 的处理过程。它接收三个输入:

  1. 当前时间步的输入: x_t (维度 input_dim)

  2. 前一时间步的隐藏状态: h_{t-1} (维度 hidden_dim)

  3. 前一时间步的细胞状态: C_{t-1} (维度 hidden_dim)

它产生两个输出:

  1. 当前时间步的隐藏状态: h_t (维度 hidden_dim)

  2. 当前时间步的细胞状态: C_t (维度 hidden_dim)

单元内部的计算涉及以下步骤:

  1. 遗忘门:

    • 计算遗忘因子: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} 中每个对应分量被保留的程度。

  2. 输入门 & 候选值:

    • 输入门: 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_iW_g 是各自的权重矩阵(维度同上),b_ib_g 是偏置向量。

  3. 更新细胞状态:

    • 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 上相对稳定地流动。

  4. 输出门:

    • o_t = σ(W_o · [h_{t-1}, x_t] + b_o)

      • 计算基于细胞状态 C_t 应该输出哪些部分到隐藏状态 h_to_t 在 0(不输出)到 1(完全输出)之间。

    • W_o 是权重矩阵,b_o 是偏置向量。

  5. 计算当前隐藏状态:

    • 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(Long Short-Term Memory)模型的深度解析_第1张图片

LSTM的内部参数详解

从上面的计算过程可以看出,一个标准的LSTM单元包含以下参数:

  1. 权重矩阵 (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))

  2. 偏置向量 (Biases): 共有 4 组,与权重矩阵一一对应。

    • b_f: 遗忘门的偏置向量 (维度: hidden_dim)

    • b_i: 输入门的偏置向量 (维度: hidden_dim)

    • b_g: 候选细胞状态的偏置向量 (维度: hidden_dim)

    • b_o: 输出门的偏置向量 (维度: hidden_dim)

重要说明

  • 参数共享: 同一个LSTM层中的所有时间步 t 共享同一套参数 (W_fW_iW_gW_ob_fb_ib_gb_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=100hidden_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_ti_to_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如何解决长期依赖问题?

  1. 细胞状态作为信息高速公路: C_t = f_t * C_{t-1} + i_t * g_t 这个设计是核心。梯度可以通过 C_t 直接流向 C_{t-1}(通过加法操作 +),而不会像标准RNN那样在每个时间步都经过压缩性的激活函数(如 tanh)导致指数级衰减。乘法操作 f_t * 虽然也可能导致梯度消失,但 f_t 是由网络学习的,它可以选择让某些维度的遗忘因子接近1(即完全保留),使得对应维度上的梯度可以几乎无损地流过很多时间步。

  2. 门控机制赋予选择性: 三个门让LSTM拥有强大的能力:

    • 有选择地遗忘: 遗忘门 f_t 可以主动丢弃与当前任务无关的旧信息(例如,在分析一个新句子时,忘记前一个句子的主题)。

    • 有选择地记忆: 输入门 i_t 可以决定哪些新信息是重要的,需要加入到长期记忆中(例如,记住当前句子中的关键实体)。

    • 有选择地输出: 输出门 o_t 可以根据当前细胞状态和任务需求,决定输出哪些信息给隐藏状态(例如,在情感分析中,可能只需要输出与情感相关的特征)。

  3. 加法更新: 新细胞状态是通过 加法 (+) 来更新的,而不是像标准RNN那样通过函数 变换。加法操作在反向传播时梯度是常数1(d(C_t)/d(C_{t-1}) = f_t,且 f_t 可以通过学习接近1),这大大缓解了梯度消失问题。乘法操作(f_t *i_t *)虽然会导致梯度消失/爆炸,但门控信号 f_ti_t 本身是Sigmoid输出且受网络控制,网络可以学会让这些门在需要长期记忆的位置保持打开(值接近1)。

变体与改进

  • Peephole Connections: 一些LSTM变体让门 (f_ti_to_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_fW_iW_gW_o)和对应的偏置向量b_fb_ib_gb_o),这些参数在层内所有时间步共享。关键的细胞状态更新公式 C_t = f_t * C_{t-1} + i_t * g_t 通过加法操作维持了梯度的稳定流动,而Sigmoid门则赋予了模型有选择地遗忘、记忆和输出信息的强大能力。理解这些内部结构和参数的作用,对于有效使用、调优LSTM模型以及在实践中诊断问题至关重要。虽然GRU等变体在某些场景下可能更受欢迎,但LSTM的设计思想和门控机制仍然是理解现代序列建模的基础。

你可能感兴趣的:(lstm,rnn,深度学习)