GRU

门控循环单元(Gated Recurrent Unit,GRU)由 Cho 等(2014)在神经机器翻译的 RNN 编码器-解码器框架中提出,是 LSTM 的简化门控变体。它将细胞状态隐藏状态合并为单一的 $\mathbf{h}_t$,用更新门重置门两个门控替代 LSTM 的三门结构,在多数任务上与 LSTM 性能相当,同时参数量更少、训练更快。

段末注释GRU 可理解为在 $\mathbf{h}_t$ 上做凸组合:$\mathbf{h}_t = (1-\mathbf{z}t)\odot \mathbf{h}{t-1} + \mathbf{z}_t \odot \tilde{\mathbf{h}}_t$,更新门 $\mathbf{z}_t$ 决定”保留旧记忆”与”写入新内容”的比例。

读前说明:配图位于同名目录 2104.神经网络-循环神经网络-GRU/。本文独立成篇;对比 LSTM 可参阅 2104.神经网络-循环神经网络-LSTM,基础 RNN 见 2104.神经网络-循环神经网络-RNN


1. 从何处来:演进脉络

图 1 从 LSTM 到 GRU 的简化演进(科普示意)

1.1 前驱:vanilla RNN 与 LSTM

循环神经网络(Recurrent Neural Network,RNN)通过隐藏状态 $\mathbf{h}_t$ 传递序列信息,但面临梯度消失/爆炸长期依赖难题。长短期记忆网络(Long Short-Term Memory,LSTM)引入独立细胞状态 $\mathbf{C}_t$ 与输入/遗忘/输出三门,以加法更新缓解梯度衰减。

LSTM 有效,但结构较重:4 组门控仿射变换 + 独立 $\mathbf{C}_t$,参数量约为 vanilla RNN 的 4 倍,推理与训练开销较大。

1.2 GRU 的提出动机

Cho 等(2014)在 Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation 中提出 GRU,核心动机:

动机 说明
简化结构 去掉独立 $\mathbf{C}_t$,减少一组状态变量
减少参数 2 门替代 3 门,参数量约为 LSTM 的 75%
保持门控能力 仍通过 sigmoid 门控制信息流动
工程效率 更快训练,更易在 seq2seq 中堆叠

1.3 后续发展

年份 里程碑 要点
2014 Cho 等,GRU 与 LSTM 并列成为 RNN 门控标配
2014–2016 seq2seq + attention GRU/LSTM 编码器 + Bahdanau 注意力
2015 Chung 等系统对比 多数据集上 GRU 与 LSTM 互有胜负
2017+ Transformer 循环结构让位于自注意力;GRU 仍用于轻量时序任务
2020s 边缘/实时场景 语音唤醒、传感器流式建模等仍可选 GRU

段末注释Minimal GRUQRNN 等进一步简化 RNN 的尝试存在,但 GRU 仍是工业界最常用 LSTM 替代之一。


2. 要解决什么问题

2.1 与 LSTM 共享的核心问题

GRU 与 LSTM 面向同一类问题:对序列 $\mathbf{x}1, \ldots, \mathbf{x}T$ 建模 $P(y_t \mid \mathbf{x}{\le t})$,并在 $\tau \gg 1$ 时仍能有效利用 $\mathbf{x}{t-\tau}$ 的信息。

vanilla RNN 的瓶颈(梯度连乘、信息覆盖)在 LSTM 文档 中已详述;GRU 同样通过门控插值更新缓解这些问题。

2.2 GRU 相对 LSTM 的额外诉求

在保持长期记忆能力的前提下,进一步解决:

  • 参数效率:小数据集或移动端部署时,更少参数 → 更低过拟合风险;
  • 计算效率:少一门 → 每步少一次大矩阵乘;
  • 实现简洁:仅维护 $\mathbf{h}_t$,无需同时传递 $(\mathbf{h}_t, \mathbf{C}_t)$。

2.3 设计思路:插值式记忆更新

GRU 将 LSTM 的”遗忘 + 输入”合并为更新门 $\mathbf{z}_t$:

$$
\mathbf{h}_t = (1 - \mathbf{z}t) \odot \mathbf{h}{t-1} + \mathbf{z}_t \odot \tilde{\mathbf{h}}_t
$$

  • $\mathbf{z}t \approx 0$:几乎完全保留 $\mathbf{h}{t-1}$(类似 LSTM 中 $\mathbf{f}_t \approx 1, \mathbf{i}_t \approx 0$);
  • $\mathbf{z}_t \approx 1$:几乎完全替换为候选 $\tilde{\mathbf{h}}_t$;
  • 重置门 $\mathbf{r}_t$ 控制计算 $\tilde{\mathbf{h}}t$ 时”多大程度忽略” $\mathbf{h}{t-1}$。

3. 模型架构与原理

图 2 GRU 单元结构:更新门与重置门(科普示意)

3.1 符号约定

符号 含义 典型维度
$\mathbf{x}_t$ 时刻 $t$ 的输入 $\mathbb{R}^{d_x}$
$\mathbf{h}_{t-1}, \mathbf{h}_t$ 隐藏状态(兼作记忆) $\mathbb{R}^{d_h}$
$\mathbf{z}_t$ 更新门(update gate) $\mathbb{R}^{d_h}$
$\mathbf{r}_t$ 重置门(reset gate) $\mathbb{R}^{d_h}$
$\tilde{\mathbf{h}}_t$ 候选隐藏状态 $\mathbb{R}^{d_h}$
$\sigma$ sigmoid 逐元素
$\odot$ Hadamard 积

拼接向量 $[\mathbf{h}_{t-1}; \mathbf{x}_t] \in \mathbb{R}^{d_h + d_x}$。

3.2 前向传播(标准 GRU)

Step 1 — 两门

$$
\begin{aligned}
\mathbf{z}_t &= \sigma!\left(\mathbf{W}z,[\mathbf{h}{t-1}; \mathbf{x}_t] + \mathbf{b}_z\right) & \text{(更新门:新/旧混合比例)} \
\mathbf{r}_t &= \sigma!\left(\mathbf{W}r,[\mathbf{h}{t-1}; \mathbf{x}_t] + \mathbf{b}_r\right) & \text{(重置门:计算候选时是否”清零”旧状态)}
\end{aligned}
$$

Step 2 — 候选隐藏状态

$$
\tilde{\mathbf{h}}_t = \tanh!\left(\mathbf{W}_h,[\mathbf{r}t \odot \mathbf{h}{t-1}; \mathbf{x}_t] + \mathbf{b}_h\right)
$$

注意:$\mathbf{r}t$ 仅作用于 $\mathbf{h}{t-1}$ 再拼接,而非直接作用于 $\mathbf{x}_t$。

Step 3 — 更新隐藏状态(核心)

$$
\mathbf{h}_t = (1 - \mathbf{z}t) \odot \mathbf{h}{t-1} + \mathbf{z}_t \odot \tilde{\mathbf{h}}_t
$$

Step 4 — 任务头

$$
\hat{\mathbf{y}}t = \mathbf{W}{hy},\mathbf{h}_t + \mathbf{b}y \quad\text{或}\quad \mathrm{softmax}(\mathbf{W}{hy},\mathbf{h}_t + \mathbf{b}_y)
$$

3.3 门控直觉

模式 条件 效果
长期持有 $\mathbf{z}_t \approx 0$ $\mathbf{h}t \approx \mathbf{h}{t-1}$,信息跨步传递
完全刷新 $\mathbf{z}_t \approx 1$ $\mathbf{h}_t \approx \tilde{\mathbf{h}}_t$,写入新内容
忽略历史算候选 $\mathbf{r}_t \approx 0$ 候选 $\tilde{\mathbf{h}}_t$ 主要依赖 $\mathbf{x}_t$
正常递归 $\mathbf{r}_t \approx 1$ 候选同时看 $\mathbf{h}_{t-1}$ 与 $\mathbf{x}_t$

3.4 GRU 与 LSTM 的结构对应(非严格等价)

LSTM 组件 GRU 中的近似角色
遗忘门 $\mathbf{f}_t$ + 输入门 $\mathbf{i}_t$ 更新门 $\mathbf{z}_t$(耦合控制)
细胞状态 $\mathbf{C}_t$ 合并入 $\mathbf{h}_t$
输出门 $\mathbf{o}_t$ 无独立输出门;$\mathbf{h}_t$ 直接对外
候选 $\tilde{\mathbf{C}}_t$ 候选 $\tilde{\mathbf{h}}_t$,受重置门调制

3.5 多层与双向扩展

与 LSTM 相同:

  • 堆叠 GRU:层间以上一层 $\mathbf{h}_t^{(l-1)}$ 为输入;
  • BiGRU:前向 + 后向,拼接 $[\overrightarrow{\mathbf{h}}_t; \overleftarrow{\mathbf{h}}_t]$ 用于编码任务。

3.6 三者对比

维度 Vanilla RNN LSTM GRU
状态变量 $\mathbf{h}_t$ $\mathbf{h}_t, \mathbf{C}_t$ $\mathbf{h}_t$
门数量 0 3 2
参数量(同 $d_h,d_x$) $1\times$ $\approx 4\times$ $\approx 3\times$
长期依赖 强(任务相关)
训练速度 中等

4. 训练哪些参数

4.1 单个 GRU 单元的可学习参数

参数 形状 作用
$\mathbf{W}_z, \mathbf{b}_z$ $\mathbb{R}^{d_h \times (d_h + d_x)}$ 更新门
$\mathbf{W}_r, \mathbf{b}_r$ 同上 重置门
$\mathbf{W}_h, \mathbf{b}_h$ 同上 候选隐藏状态
$\mathbf{W}_{hy}, \mathbf{b}_y$ $\mathbb{R}^{d_y \times d_h}$ 输出头

参数量估算(单层、单方向):

$$
|\Theta|_{\mathrm{GRU}} \approx 3 \cdot d_h ,(d_h + d_x + 1) + d_y(d_h + 1)
$$

对比 LSTM 的 $4 \cdot d_c(d_h + d_x + 1)$,当 $d_h = d_c = d_x = 256$ 时,GRU 核心约 394K vs LSTM 525K,约为 75%

权重共享:$\mathbf{W}_z, \mathbf{W}_r, \mathbf{W}_h$ 在所有时间步共享。

4.2 完整模型通常还包括

  • 输入嵌入 $\mathbf{E}$;
  • Dropout(推荐加在 $\mathbf{h}_t$ 输出或层间);
  • LayerNorm(可选);
  • 重置门偏置初始化:部分实现将 $\mathbf{b}_r$ 初始化为负值,使训练初期更倾向”保留历史”。

5. 如何训练

图 3 GRU 训练:BPTT 与参数更新(科普示意)

5.1 数据与展开

与 LSTM 相同:序列 batch 化 → 按 $t=1,\ldots,T$ 递推 $\mathbf{h}_t$ → 初始 $\mathbf{h}_0 = \mathbf{0}$ 或可学习。

GRU 仅返回 $(\mathbf{h}_t)$,无独立 $\mathbf{C}_t$,接口更简洁。

5.2 损失函数

与 LSTM 完全一致,依任务选择:

  • 序列标注:逐步交叉熵;
  • 序列分类:末步交叉熵;
  • 回归:MSE/MAE;
  • 语言建模:next-token 负对数似然。

5.3 反向传播:BPTT

随时间反向传播(Backpropagation Through Time,BPTT)对 GRU 同样适用。对 $\mathbf{h}_t$ 的梯度递推含 $(1-\mathbf{z}_t)$ 项:

$$
\frac{\partial \mathcal{L}}{\partial \mathbf{h}_{t-1}} = \frac{\partial \mathcal{L}}{\partial \mathbf{h}_t} \odot (1 - \mathbf{z}_t) + \cdots
$$

当 $\mathbf{z}_t \approx 0$ 时,梯度可沿 $\mathbf{h}$ 路径较完整回传——机制类似 LSTM 的 $\mathbf{f}_t \approx 1$。

Truncated BPTT:与 LSTM 相同,每 $K$ 步截断以节省显存。

5.4 优化实践

技巧 说明
梯度裁剪 必备,尤其深层堆叠时
Adam / AdamW 默认选择
Dropout 沿时间共享 mask(Variational Dropout)
GRU vs LSTM 选型 数据少、要快 → 先试 GRU;任务极长依赖 → 可试 LSTM

5.5 PyTorch 最小示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import torch
import torch.nn as nn

class GRUClassifier(nn.Module):
"""序列分类:输入 (batch, seq_len, d_x),输出 (batch, num_classes)"""

def __init__(self, d_x: int, d_h: int, num_classes: int, num_layers: int = 1):
super().__init__()
self.gru = nn.GRU(
input_size=d_x,
hidden_size=d_h,
num_layers=num_layers,
batch_first=True,
)
self.head = nn.Linear(d_h, num_classes)

def forward(self, x: torch.Tensor) -> torch.Tensor:
output, h_n = self.gru(x) # GRU 无 cell state,仅返回 h_n
return self.head(h_n[-1])

6. 应用与局限

图 4 GRU 的典型局限(科普示意)

6.1 典型应用场景

场景 说明
神经机器翻译(历史) 2014–2016 seq2seq 默认编码器/解码器
文本分类/序列标注 与 BiLSTM 并列,GRU 常更快
时序预测 中等长度窗口,资源受限
语音/对话 流式解码,低延迟
小样本学习 参数少于 LSTM,略抗过拟合

6.2 主要局限性

(1)与 LSTM 一样,超长依赖仍有限

门控缓解梯度消失,但 $\tau \gg 500$ 时仍不如 Self-Attention / Transformer 直接建模任意距离。

(2)无法时间步并行

与所有 RNN 相同,$t$ 依赖 $t-1$,GPU 并行度低于 Transformer。

(3)更新门与重置门耦合

LSTM 的遗忘/输入可独立调节;GRU 的 $\mathbf{z}_t$ 同时控制”保留”与”写入”,表达力在理论上略弱于 LSTM(实践中差距常很小)。

(4)任务相关的选型不确定性

Chung 等(2014)表明两者互有胜负,无 universally better;需实验对比。

(5)重置门饱和风险

$\mathbf{r}_t \approx 0$ 时候选几乎不看历史,若长期饱和可能导致部分路径梯度仍衰减。

(6)已被 Transformer 取代的主流 NLP 地位

大规模预训练领域 GRU 已非主流;但在轻量、流式、边缘场景仍有价值。

6.3 GRU vs LSTM 选型建议

优先选 GRU 优先选 LSTM
训练速度/参数量敏感 序列极长、依赖极远
中小规模数据 需要独立细胞状态做精细门控分析
快速 baseline 历史复现/与旧模型对齐

7. 小结

主题 要点
由来 2014 Cho 等,在 LSTM 之后简化门控 RNN
解决什么 长期依赖 + 比 LSTM 更省参数/更快
架构 更新门 $\mathbf{z}_t$ + 重置门 $\mathbf{r}_t$,插值更新 $\mathbf{h}_t$
训练参数 $\mathbf{W}_z, \mathbf{W}_r, \mathbf{W}_h$ 及偏置,约为 LSTM 的 75%
训练方式 BPTT + 与 LSTM 相同的损失与优化技巧
局限 超长依赖、串行、与 LSTM 难分高下、NLP 主流已让位 Transformer

参考文献

  1. Cho, K., van Merriënboer, B., Gulcehre, C., et al. (2014). Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation. EMNLP.
  2. Chung, J., Gulcehre, C., Cho, K., & Bengio, Y. (2014). Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling. NIPS Workshop.
  3. Hochreiter, S., & Schmidhuber, J. (1997). Long Short-Term Memory. Neural Computation.
  4. Goodfellow, I., Bengio, Y., & Courville, A. (2016). Deep Learning. MIT Press, Chapter 10.
-------------本文结束感谢您的阅读-------------