门控循环单元 (GRU) 由 Cho 等人于2014年提出,它为处理序列数据提供了一种有效方法。尽管长短期记忆 (LSTM) 网络也以解决梯度消失问题和捕捉长距离依赖而闻名,但它们因其三个不同的门和独立的细胞状态而导致结构较为繁复。GRU 旨在实现类似的能力,但采用更简洁的架构。GRU 通过将遗忘门和输入门合并为一个“更新门”,并整合细胞状态和隐藏状态,从而简化了 LSTM 中发现的门控机制。这种单元只有两个门:重置门 ($r_t$):这个门决定了有多少先前的隐藏状态 ($h_{t-1}$) 应该与当前输入 ($x_t$) 结合,以计算一个候选隐藏状态。本质上,它决定了多少过去的信息与计算新的状态提议相关。如果重置门接近0,则在计算候选状态时,该单元会有效地“遗忘”先前的隐藏状态。更新门 ($z_t$):这个门控制了有多少来自先前的隐藏状态 ($h_{t-1}$) 的信息应该传递到当前的隐藏状态 ($h_t$)。它还决定了应该整合多少新计算的候选隐藏状态。如果更新门接近1,则先前状态大部分被传递;如果接近0,则新的候选状态占主导地位。GRU与LSTM的比较主要区别在于门控结构:LSTM:有三个门(输入、遗忘、输出),并与隐藏状态 ($h_t$) 一起维护一个独立的细胞状态 ($c_t$)。这使得对信息流和记忆有更精细的控制。GRU:有两个门(重置、更新),并将细胞状态和隐藏状态合并为一个单一的状态向量 ($h_t$)。GRU 中的这种简化导致其参数数量少于具有相同隐藏单元数量的 LSTM。这可以使 GRU 在计算上略微更高效(训练更快,内存占用更少),并且在较小数据集上可能更不容易过拟合。然而,LSTM 增加的复杂性可能会使其在某些任务中建模特别复杂的长距离依赖方面更具优势。在实践中,LSTM 和 GRU 之间的性能差异通常取决于具体任务,两者都没有普遍的优越性。通常会尝试两种架构,以查看哪种方案在特定问题上表现更好。GRU架构图以下是单个 GRU 单元内数据流的简化视图:digraph GRU_Cell { rankdir=LR; node [shape=rect, style=filled, fillcolor="#a5d8ff", fontname="helvetica"]; edge [fontname="helvetica"]; subgraph cluster_input { label = "输入"; style=filled; color="#e9ecef"; xt [label="x_t (当前输入)"]; ht_prev [label="h_{t-1} (上一隐藏状态)"]; } subgraph cluster_gates { label = "门"; style=filled; color="#b2f2bb"; rt [label="重置门 (r_t)\nσ"]; zt [label="更新门 (z_t)\nσ"]; } subgraph cluster_candidate { label = "候选状态"; style=filled; color="#ffec99"; ht_tilde [label="候选 h̃_t\ntanh"]; } subgraph cluster_output { label = "输出"; style=filled; color="#e9ecef"; ht [label="h_t (当前隐藏状态)"]; } xt -> rt; ht_prev -> rt; xt -> zt; ht_prev -> zt; xt -> ht_tilde; {rank=same; rt; ht_prev} -> ht_tilde [label=" 由 r_t 门控", style=dashed]; {rank=same; zt; ht_prev} -> ht [label=" (1-z_t) * h_{t-1}", style=dashed]; {rank=same; zt; ht_tilde} -> ht [label=" z_t * h̃_t", style=dashed]; }GRU 单元的简化表示。它呈现了重置门 ($r_t$) 如何影响候选隐藏状态 ($\tilde{h}t$) 的计算,以及更新门 ($z_t$) 如何在先前状态 ($h{t-1}$) 和候选状态之间进行平衡以生成最终隐藏状态 ($h_t$)。Sigmoid ($\sigma$) 和 tanh 激活函数通常分别用于门和候选状态。在 Keras 中使用 GRU在 Keras 中实现 GRU 层非常直接,并且与使用 SimpleRNN 或 LSTM 类似。您可以从 keras.layers 导入它。import keras from keras import layers # 示例:用于序列处理的堆叠 GRU 层 model = keras.Sequential([ layers.Embedding(input_dim=10000, output_dim=16, input_length=100), # 示例嵌入层 layers.GRU(units=32, return_sequences=True), # 第一个 GRU 层,返回完整序列 layers.GRU(units=32), # 第二个 GRU 层,只返回最后一个输出 layers.Dense(units=1, activation='sigmoid') # 用于二元分类的输出层 ]) model.summary()重要的参数,如 units(输出/隐藏状态的维度)、activation(默认通常为 tanh)、recurrent_activation(通常用于门控为 sigmoid)以及 return_sequences,其行为与 LSTM 层中的对应项类似。何时选择 GRU?GRU 是 LSTM 的有力替代方案,尤其是在以下情况:您正在寻求可能更快的训练时间以及更低的计算成本。您的数据集大小有限,减少参数数量可能有助于防止过拟合。您希望从一个稍微简单的循环架构开始。正如深度学习中的许多选择一样,建议进行实证验证。在您的特定序列建模任务(例如,文本分类、时间序列预测)上尝试 LSTM 和 GRU 两种架构,并在验证集上评估它们的性能,以确定最合适的选项。