吴恩达深度学习课程五:自然语言处理 第一周:循环神经网络 (五)门控循环单元 GRU

此分类用于记录吴恩达深度学习课程的学习笔记。
课程相关信息链接如下:

  1. 原课程视频链接:[双语字幕]吴恩达深度学习deeplearning.ai
  2. github课程资料,含课件与笔记:吴恩达深度学习教学资料
  3. 课程配套练习(中英)与答案:吴恩达深度学习课后习题与答案

本篇为第五课的第一周内容,1.9的内容以及一些相关基础的补充。


本周为第五课的第一周内容,与 CV 相对应的,这一课所有内容的中心只有一个:自然语言处理(Natural Language Processing,NLP)
应用在深度学习里,它是专门用来进行文本与序列信息建模的模型和技术,本质上是在全连接网络与统计语言模型基础上的一次“结构化特化”,也是人工智能中最贴近人类思维表达方式的重要研究方向之一。
这一整节课同样涉及大量需要反复消化的内容,横跨机器学习、概率统计、线性代数以及语言学直觉。
语言不像图像那样“直观可见”,更多是抽象符号与上下文关系的组合,因此理解门槛反而更高
因此,我同样会尽量补足必要的背景知识,尽可能用比喻和实例降低理解难度。
本篇的内容关于门控循环单元 GRU,它通过改变 RNN 的隐藏层,来缓解 RNN 的梯度消失问题。

1. 什么是 GRU(Gated Recurrent Unit)?

前面的内容里中我们已经提到过:RNN 的核心机制,是把历史信息压缩进一个不断传递的隐藏状态中
结果就是我们已经分析过的结论:信息一旦隔得太远,就会在反复的线性变换和非线性映射中被不断稀释
在反向传播时就体现为梯度越来越小,最终几乎传不回去,导致“开头被遗忘”,这就是 RNN 的长距离依赖问题
显然,这并不是改善训练技巧可以解决的问题,而是 RNN 本身的结构造成的限制,自然而然地就引出了 NLP 领域的新问题 :如何缓解 RNN 的长距离依赖问题? 即如何让模型“记得更久一些”?

于是,在 2014 年发表的一篇论文: On the Properties of Neural Machine Translation: Encoder–Decoder Approaches 中,提出了一种带有门控机制的循环单元结构,即后来被称为 GRU(Gated Recurrent Unit) 的模型。
该工作首次在 Encoder–Decoder 框架下系统性地引入 “更新门”和“重置门”,通过对隐藏状态的信息流进行选择性控制,从结构层面缓解了传统 RNN 在长序列建模中面临的困难。
同年的另一篇论文:Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling 对其实际效果进行了系统评估。实验结果证明了其优越的性能,这也使其迅速成为实际 NLP 系统中广泛采用的基础循环单元之一。

出现了很多没见过的名词,别担心,下面我们就来详细展开。

1.1 GRU 的解题思路

首先,面对”如何让模型记得更久一些”的问题,GRU给出的答案是:

既然记不住全部,那我能不能只记重要的?

这是什么意思?回忆一下 普通 RNN 是如何进行记忆的:

\[新输入来了\rightarrow旧状态所有信息参与计算\rightarrow得到一个带有新输入信息的新隐藏状态 \]

我们已经很熟悉这个过程了:
image.png

但是,实际上,在真实语言中,我们并不是这样处理信息的。
举个例子:

“我昨天去北京出差,
在路上遇到了一个多年未见的朋友,
现在在……”

当你看到“他”的时候:

  • 不需要记住“北京”,“昨天”。
  • 但你必须记住“朋友”。
  • 换句话说,当前时刻的理解,并不依赖于全部历史内容,而只依赖于与当前判断相关的信息。

再概括来讲,人脑在处理序列信息时,隐含着一个非常重要的能力:选择性记忆
而 GRU 的设计,正是将这种“取舍能力”,通过门控结构的形式,显式地引入到 RNN 的隐藏层更新过程中
简单展开一下,GRU 并没有改变 RNN 的整体框架:

  • 仍然是时间步 \(t = 1, 2, \dots\)
  • 仍然有输入 \(x^{<t>}\)
  • 仍然有隐藏状态 \(a^{<t>}\)

它真正改变的,只有一件事:在“旧状态 → 新状态”的过程中,加了两道可学习的“门”。 就是我们下面要说的 “更新门”和“重置门”
image.png

1.2 GRU 的更新门(Update Gate)

第一道门,叫 更新门(Update Gate)
它负责回答的问题是:

“当前这一步,我要保留多少过去的记忆?”

也就是说:

  • 更新门开得越大 → 旧状态保留得越多
  • 更新门关得越紧 → 当前输入对隐藏状态的影响越大

总结来说,更新门衡量的是:“这条历史信息,值不值得继续往后传?”
这一设计直接解决了 RNN 的一个问题:普通 RNN 每一步都会用新输入强行覆盖旧隐藏状态,
长期信息容易被逐步稀释,而更新门让模型可以选择性保留重要历史信息

我们回到之前的例子:

“我昨天去北京出差,
在路上遇到了一个多年未见的朋友,
现在在……”

在生成“他”对应的隐藏状态时:

  • 更新门会让模型保留“朋友”这个关键信息,因为它对理解代词至关重要
  • 同时,更新门会削弱“昨天”“北京”等不相关信息的影响

于是,通过更新门,模型可以自动判断哪些历史值得继续传递,哪些可以淡化。
image.png
其实,这种思路和我们之前在优化算法部分介绍的 指数加权平均 很相似:旧状态像过去的平均值,更新门控制“平均时的新权重”,让重要信息得到保留。

1.3 GRU 的重置门(Reset Gate)

第二道门,叫 重置门(Reset Gate)
它关心的不是“保留多少旧信息”,而是:

“在生成新信息时,我要参考多少过去的历史?”

可以把它想象成 选择记忆开关

  • 当历史信息相关 → 重置门值接近 1 → 历史参与计算
  • 当历史信息不相关 → 重置门值接近 0 → 模型“暂时忘掉过去”

这个设计是为了应对语言序列中的一类常见情况:句子突然换话题、上下文跳转很大等前面的内容对当前判断几乎没帮助的情况。

还是这个例子:

“我昨天去北京出差,
在路上遇到了一个多年未见的朋友,
现在在……”

当生成“他”对应的新隐藏状态时:

  • 重置门会让模型只关注“朋友”这个历史信息
  • 忽略“昨天”、“北京”等与当前代词关系不大的信息
    image.png
    只看概念和例子, 你可能会觉得:更新门和重置门好像是一个作用啊?
    实际上,这绝非冗余设计,我们展开看看:

1.4 更新门和重置门

实际上,更新门关注的是 “旧状态在下一步隐藏状态中保留多少”,它是一种全局记忆控制,关注的是“以后”。
而重置门关注的是 “在生成当前新隐藏状态时,历史信息是否被参考”,它是一种局部选择性,关注的是“现在”。

功能 控制对象 比喻
更新门 记忆持续 上一隐藏状态整体传递 决定哪些历史要带到下一步,就像水龙头调节水流量
重置门 记忆使用 当前候选隐藏状态计算 决定本步是否参考历史,就像选择性翻阅笔记

最终,更新门负责“信息能延续多远” ,重置门负责“信息在当前是否参与生成”。
两道门结合,使 GRU 能够在长序列中保留重要历史信息,同时在必要时灵活忘掉无关历史,实现“更好、更有用的记忆”。

现在,了解了 GRU 的基本原理后,我们来看看如何实现 GRU 吧。

2. 如何实现 GRU ?

这里需要提前说明一点,如果你看了原视频,会发现吴恩达老师并没有过多提及重置门,而是用一个新概念:“记忆细胞” 来进行讲解。实际上,记忆细胞是之后的 LSTM 中的概念,因为 GRU 可以看作是 LSTM 的简化形式,因此同样可以使用,但个人感觉不正式引入的前提下并不好理解,最终还是选择使用 GRU 本身的概念来进行这部分内容,在下一篇 LSTM 的介绍中再正式引入记忆细胞。

在理解了 GRU 的核心思想和两道门的作用之后,我们可以进一步探讨如何在实际模型中实现 GRU。实现上,其实并不复杂,本质上仍是对普通 RNN 的隐藏状态更新增加了门控计算。下面我们按逻辑逐步展开。

2.1 计算重置门

在 GRU 的实现逻辑中,对于当前步新隐藏状态的计算,第一步是计算重置门
重置门 \(r^{\langle t \rangle}\) 决定了历史隐藏状态 \(a^{\langle t-1 \rangle}\) 在生成当前候选隐藏状态 \(\tilde{a}^{\langle t \rangle}\) 时被参考的比例。
来具体演示一下这个过程:
image.png
计算公式为:

\[r^{\langle t \rangle} = sigmoid\big( W_{xr} x^{\langle t \rangle} + W_{ar} a^{\langle t-1 \rangle} + b_r \big) \]

你可以比较明显的发现,实际上重置门就是一个使用 \(sigmoid\) 激活函数的全连接层,最终的激活值,也就是重置门值会被 \(sigmoid\) 压缩到 \(0\sim1\) 之间。用来表示一种权重

  • \(r^{\langle t \rangle} \approx 1\) 时,第 \(i\) 个隐藏单元会充分参考历史信息
  • \(r^{\langle t \rangle} \approx 0\) 时,第 \(i\) 个隐藏单元会 “忘掉”历史信息,只依赖当前输入生成候选隐藏状态

什么叫候选隐藏状态?这就是我们的下一步内容。

2.2 计算候选隐藏状态

在计算完重置门 \(r^{\langle t \rangle}\) 后,下一步是生成 候选隐藏状态 \(\tilde{a}^{\langle t \rangle}\),它表示当前步的新信息,结合了当前输入 \(x^{\langle t \rangle}\) 和经过重置门处理后的历史隐藏状态 \(a^{\langle t-1 \rangle}\)
同样,我们在上一步的基础上进行演示:
image.png

摆出公式如下:

\[\tilde{a}^{\langle t \rangle} = \tanh\Big( W_{xa} x^{\langle t \rangle} + W_{aa} ( r^{\langle t \rangle} \odot a^{\langle t-1 \rangle} ) + b_a \Big) \]

其中\(r^{\langle t \rangle} \odot a^{\langle t-1 \rangle}\)是指逐元素乘,这是将重置门作用于历史隐藏状态。
你会发现,这时我们得到的候选隐藏状态 \(\tilde{a}^{\langle t \rangle}\) 就是是当前步的“新记忆”,它既包含当前输入信息 \(x^{\langle t \rangle}\),也包含经过选择性过滤的历史信息 \(r^{\langle t \rangle} \odot a^{\langle t-1 \rangle}\)

到这里,你可能觉得已经实现一些优化了,但 GRU 告诉你:这还不够好

2.3 计算更新门

在生成候选隐藏状态 \(\tilde{a}^{\langle t \rangle}\) 后,下一步是计算 更新门 \(z^{\langle t \rangle}\)
而更新门的作用是:决定历史隐藏状态 \(a^{\langle t-1 \rangle}\) 与候选隐藏状态 \(\tilde{a}^{\langle t \rangle}\) 在最终隐藏状态 \(a^{\langle t \rangle}\) 中的融合比例
我们继续进行演示:
image.png
看完演示,我想一个问题已经呼之欲出了:更新门和重置门看起来就是把一个东西算了两遍啊?这么做的意义是什么?我直接把重置门值拿来用不行吗?
这就涉及到二者在模型中所承担的语义作用

  • 更新门用来记录全局中的重要记忆,它直接影响最终输出,同样梯度也直接影响它。
  • 重置门用来保存局部记忆,确保使用信息符合当前步需求,它通过候选状态间接影响最终输出,因此梯度对它的作用就没有那么“长期”。

image.png
因此:二者不能参数共享,而是一定要有独立的参数,以此通过反向传播实现二者的语义作用。
同时要说明的是,我们这里演示的是逻辑上的计算顺序,你会发现二者的计算并不存在先后限制,因此在实际应用中可以同步计算二者。
公式表示为:

\[z^{\langle t \rangle} = sigmoid\big( W_{xz} x^{\langle t \rangle} + W_{az} a^{\langle t-1 \rangle} + b_z \big) \]

其中,\(sigmoid\) 函数将输出压缩到 \([0,1]\),表示融合比例:

  • \(z^{\langle t \rangle}_i \approx 1\) 时,第 \(i\) 个隐藏单元会更多保留历史信息
  • \(z^{\langle t \rangle}_i \approx 0\) 时,第 \(i\) 个隐藏单元会更多采纳候选隐藏状态 \(\tilde{a}^{\langle t \rangle}\) 的新信息

最后,我们将用更新门将历史隐藏状态与候选隐藏状态融合,得到最终隐藏状态 \(a^{\langle t \rangle}\)

2.4 计算最终隐藏状态

在前面的步骤中,我们已经得到了三样关键量:

  • 上一时刻的隐藏状态 \(a^{\langle t-1 \rangle}\)历史记忆
  • 当前步生成的候选隐藏状态 \(\tilde{a}^{\langle t \rangle}\)新记忆
  • 控制二者融合比例的更新门 \(z^{\langle t \rangle}\)

现在,GRU 要做的最后一件事,就是将“历史记忆”和“新记忆”按更新门的指示进行融合,从而得到当前时刻的最终隐藏状态 \(a^{\langle t \rangle}\),就像这样:
image.png
最终的计算公式为:

\[a^{\langle t \rangle} = z^{\langle t \rangle} \odot a^{\langle t-1 \rangle} + (1 - z^{\langle t \rangle}) \odot \tilde{a}^{\langle t \rangle} \]

同样其中 \(\odot\) 表示逐元素乘
这个公式本身就非常直观,它表达的正是更新门的语义含义:

  • \(z^{\langle t \rangle}\) 决定了历史信息保留的比例
  • \(1 - z^{\langle t \rangle}\) 决定了新信息写入的比例

也就是说:

  • \(z^{\langle t \rangle}_i \approx 1\) 时, 第 \(i\) 个隐藏单元几乎直接复制上一时刻的状态,信息得以长期延续。
  • \(z^{\langle t \rangle}_i \approx 0\) 时, 第 \(i\) 个隐藏单元主要采用当前步生成的新信息

2.5 小结

至此,一个 GRU 单元在时间步 \(t\) 的完整计算流程就结束了,完整顺序是这样的:

  1. 计算重置门 \(r^{\langle t \rangle}\) → 用于调节历史隐藏状态在生成候选隐藏状态 \(\tilde{a}^{\langle t \rangle}\) 时的参考程度:

\[ r^{\langle t \rangle} = sigmoid(W_{xr} x^{\langle t \rangle} + W_{ar} a^{\langle t-1 \rangle} + b_r) \]

  1. 计算候选隐藏状态 \(\tilde{a}^{\langle t \rangle}\) → 使用当前输入 \(x^{\langle t \rangle}\) 和重置门调节后的历史信息 :

\[ \tilde{a}^{\langle t \rangle} = \tanh(W_{x\tilde{a}} x^{\langle t \rangle} + W_{a\tilde{a}} (r^{\langle t \rangle} \odot a^{\langle t-1 \rangle}) + b_{\tilde{a}}) \]

  1. 计算更新门 \(z^{\langle t \rangle}\) → 决定历史信息与新候选状态在最终隐藏状态中的融合比例:

\[ z^{\langle t \rangle} = sigmoid(W_{xz} x^{\langle t \rangle} + W_{az} a^{\langle t-1 \rangle} + b_z) \]

  1. 计算最终隐藏状态 \(a^{\langle t \rangle}\) → 使用更新门进行加权融合:

\[ a^{\langle t \rangle} = z^{\langle t \rangle} \odot a^{\langle t-1 \rangle} + (1 - z^{\langle t \rangle}) \odot \tilde{a}^{\langle t \rangle} \]

综合来看,GRU 缓解长距离依赖问题的方式可以概括为一句话:通过更新门建立“可复制的长期记忆通路”,通过重置门实现“按需使用的局部历史选择”,从结构上同时保护了信息和梯度的长期传递。
它并不是“记忆更强”,而是更聪明地决定什么时候记、什么时候用、什么时候不动
而且,你会发现 RGU 中同样有残差的思想:
从结构视角看,GRU 的更新门在时间维度上实现了一种“可学习的残差连接”:当更新门接近 1 时,隐藏状态几乎被原样复制,使信息与梯度能够跨越多个时间步稳定传播,这与 ResNet 通过恒等映射缓解深层网络退化问题在思想上是一致的。

3. 总结

概念 原理 比喻
GRU 的核心思想 不再“全部记住”,而是通过门控机制选择性地记忆与使用历史信息 记笔记时只标重点,而不是全文背诵
更新门(Update Gate) 控制上一时刻隐藏状态在当前隐藏状态中保留的比例,直接决定最终输出 水龙头:决定旧记忆“流”到下一步的多少
重置门(Reset Gate) 控制历史信息在生成当前候选隐藏状态时是否被参考 翻笔记:这一步要不要看以前的内容
候选隐藏状态 在重置门调节下,由当前输入与部分历史信息生成的新记忆 当前这一步新写下的草稿想法
最终隐藏状态 使用更新门在旧隐藏状态与候选隐藏状态之间进行加权融合 在“照抄旧稿”和“采用新稿”之间做权衡
更新门 vs 重置门 更新门决定信息能“走多远”,重置门决定信息“现在用不用” 一个管未来,一个管当下
门不共享参数的原因 二者承担不同语义角色,通过反向传播分别学习“长期保留”和“局部使用”的策略 长期计划和临时决策不能用同一套标准
梯度传播机制 更新门接近 1 时,隐藏状态近似复制,梯度可跨时间步稳定传播 给梯度修了一条高速公路
GRU 与残差思想 在时间维度上引入“可学习的恒等映射”,避免每一步都强制更新 ResNet 的 skip connection,沿时间轴展开
posted @ 2026-01-09 21:45  哥布林学者  阅读(35)  评论(0)    收藏  举报