# 第 8 章　注意力机制与外部记忆

> 来源：https://deeplearning.bnuai.com/chapters/08-attention-memory ｜ 作者：唐志清（北京师范大学） ｜ 更新：2026-11-01 ｜ 内容依据邱锡鹏《神经网络与深度学习》（https://nndl.ai/）及作者公开课件

## 学习目标

<div class="goals">

- 理解从“网络容量”角度引入注意力机制和外部记忆的动机；
- 掌握注意力的计算流程：打分函数 → 注意力分布 → 加权平均，熟悉加性、点积、缩放点积、双线性等打分函数；
- 理解键值对注意力、多头注意力、硬注意力与指针网络；
- 掌握**自注意力**的 QKV 计算及 **Transformer** 的整体结构与复杂度；
- 了解记忆网络与神经图灵机的读写机制；
- 理解 Hopfield 网络的能量函数、检索过程与 Hebbian 存储规则。

</div>

## 课件幻灯片

> 本章课件共 66 页，可在网页中逐页浏览：https://deeplearning.bnuai.com/chapters/08-attention-memory；PDF 下载：https://deeplearning.bnuai.com/pdf/nndl-ch08.pdf

## 讲义

### 8.1 网络容量与注意力

神经网络中可以存储的信息量称为**网络容量**。一般来说，存储的信息越多，神经元数量就越多，网络就越复杂。在计算能力有限的情况下，如何用有限的资源处理过载的信息？大脑给出的答案是**注意力**和**记忆**。[幻灯片 4](#slide-4)

以阅读理解为例：给定一篇文章和一个问题，模型需要从长文中找到与问题相关的少量信息。如果把整篇文章编码成一个定长向量，信息必然有损——根据通用近似定理，前馈网络和循环网络虽然有很强的能力，但在复杂任务上需要“巨大”的网络才能把信息都装下。[幻灯片 6](#slide-6) [幻灯片 8](#slide-8)

人脑中的注意力分为两种：[幻灯片 9](#slide-9)

- **自上而下的有意识的注意力**，称为**聚焦式注意力**：有预定目的、依赖任务，主动有意识地聚焦于某一对象；
- **自下而上的无意识的注意力**，称为**基于显著性的注意力**：由外界刺激驱动，如“鸡尾酒会效应”中突然听到自己的名字。

神经网络中的**最大汇聚**、**门控**机制可以近似看作自下而上的注意力；本章讨论的注意力主要指聚焦式注意力。

### 8.2 注意力机制

给定 $N$ 个输入向量 $\boldsymbol X=[\boldsymbol x_1,\cdots,\boldsymbol x_N]$ 和一个与任务相关的**查询向量** $\boldsymbol q$，注意力机制分两步：先在所有输入上计算**注意力分布**，再按分布计算输入的加权平均。[幻灯片 16](#slide-16)

$$
\alpha_n=p(z=n\mid\boldsymbol X,\boldsymbol q)=\mathrm{softmax}\big(s(\boldsymbol x_n,\boldsymbol q)\big)=\frac{\exp\big(s(\boldsymbol x_n,\boldsymbol q)\big)}{\sum_{j=1}^{N}\exp\big(s(\boldsymbol x_j,\boldsymbol q)\big)},\qquad
\mathrm{att}(\boldsymbol X,\boldsymbol q)=\sum_{n=1}^{N}\alpha_n\boldsymbol x_n .
$$

这里 $z$ 是表示“选择了第几个输入”的注意力变量，$\alpha_n$ 称为注意力分布，加权平均称为**软性注意力**。常见的**打分函数** $s(\boldsymbol x,\boldsymbol q)$ 有：[幻灯片 18](#slide-18)

| 模型 | 打分函数 | 特点 |
| --- | --- | --- |
| 加性模型 | $\boldsymbol v^\top\tanh(\boldsymbol W\boldsymbol x+\boldsymbol U\boldsymbol q)$ | 最早用于机器翻译（Bahdanau） |
| 点积模型 | $\boldsymbol x^\top\boldsymbol q$ | 计算效率高，可用矩阵乘法 |
| 缩放点积模型 | $\dfrac{\boldsymbol x^\top\boldsymbol q}{\sqrt D}$ | 维度 $D$ 较高时点积方差大，softmax 梯度小，需缩放 |
| 双线性模型 | $\boldsymbol x^\top\boldsymbol W\boldsymbol q$ | 引入非对称性 |

**应用：机器翻译与看图说话**。在基于 RNN 的编码器-解码器翻译模型中，解码器的每一步以当前隐状态为查询，对编码器所有时刻的隐状态计算注意力，得到上下文向量，从而不必把整句压缩成一个向量；注意力权重矩阵还能可视化源语言与目标语言的“软对齐”。[幻灯片 21](#slide-21) [幻灯片 24](#slide-24) 在图像描述生成中，模型生成每个词时会“看向”图像的不同区域。[幻灯片 25](#slide-25)

**注意力机制的变体**：[幻灯片 28](#slide-28) [幻灯片 29](#slide-29)

- **硬性注意力**：只关注某一个输入，如选取注意力最大的 $\hat{\boldsymbol x}=\boldsymbol x_{\hat n}$，$\hat n=\arg\max_n\alpha_n$，或按注意力分布随机采样。缺点是损失函数与注意力分布之间不可导，通常需要强化学习训练。
- **键值对注意力**：用键 $\boldsymbol K$ 计算注意力分布，用值 $\boldsymbol V$ 计算聚合信息：$\mathrm{att}\big((\boldsymbol K,\boldsymbol V),\boldsymbol q\big)=\sum_{n=1}^{N}\mathrm{softmax}\big(s(\boldsymbol k_n,\boldsymbol q)\big)\boldsymbol v_n$。当 $\boldsymbol K=\boldsymbol V$ 时退化为普通注意力。
- **多头注意力**：用多个查询 $\boldsymbol Q=[\boldsymbol q_1,\cdots,\boldsymbol q_M]$ 并行地从输入中选取多组信息，每个注意力头关注输入的不同部分：$\mathrm{att}\big((\boldsymbol K,\boldsymbol V),\boldsymbol Q\big)=\mathrm{att}\big((\boldsymbol K,\boldsymbol V),\boldsymbol q_1\big)\oplus\cdots\oplus\mathrm{att}\big((\boldsymbol K,\boldsymbol V),\boldsymbol q_M\big)$，$\oplus$ 表示向量拼接。

**指针网络**：只利用注意力的第一步，把注意力分布作为一个“软性指针”指向输入序列中的某个元素，用于输出是输入序列下标的任务（如对一组数排序、凸包问题）：[幻灯片 30](#slide-30)

$$
p(c_{1:M}\mid\boldsymbol x_{1:N})=\prod_{m=1}^{M}p(c_m\mid c_{1:m-1},\boldsymbol x_{1:N}),\qquad
p(c_m\mid\cdot)=\mathrm{softmax}(s_{m,n}),\ \ s_{m,n}=\boldsymbol v^\top\tanh(\boldsymbol W\boldsymbol x_n+\boldsymbol U\boldsymbol h_m).
$$

### 8.3 自注意力模型

处理变长序列时，卷积网络和循环网络只能建模**局部**依赖（循环网络虽然理论上能建模长程依赖，但受信息传递容量和梯度消失的限制）。全连接网络能建模长程依赖，却无法处理变长输入。**自注意力模型**可以“动态”地生成不同连接的权重，用注意力机制实现变长序列上的“全连接”。[幻灯片 31](#slide-31) [幻灯片 32](#slide-32)

**QKV 模式**。输入序列 $\boldsymbol X\in\mathbb R^{N\times D_x}$（每行一个词向量），分别线性映射到查询、键、值：[幻灯片 35](#slide-35) [幻灯片 36](#slide-36)

$$
\boldsymbol Q=\boldsymbol X\boldsymbol W_q,\qquad \boldsymbol K=\boldsymbol X\boldsymbol W_k,\qquad \boldsymbol V=\boldsymbol X\boldsymbol W_v,
$$

$$
\boldsymbol H=\mathrm{softmax}\Big(\frac{\boldsymbol Q\boldsymbol K^\top}{\sqrt{D_k}}\Big)\boldsymbol V .
$$

softmax 按行进行；第 $n$ 个输出 $\boldsymbol h_n$ 是所有值向量的加权平均，权重由第 $n$ 个查询与各个键的相似度决定。（教材采用列向量记号，公式写作 $\boldsymbol H=\boldsymbol V\,\mathrm{softmax}\big(\frac{\boldsymbol K^\top\boldsymbol Q}{\sqrt{D_k}}\big)$，两者等价。）自注意力的权重随输入动态变化，因此能处理变长序列；但它本身与位置无关，需要额外加入**位置编码**。

**多头自注意力**：用 $M$ 组不同的投影矩阵并行计算自注意力，再拼接并线性变换：[幻灯片 37](#slide-37)

$$
\mathrm{MultiHead}(\boldsymbol X)=\big(\boldsymbol H_1\oplus\cdots\oplus\boldsymbol H_M\big)\boldsymbol W_o,\qquad
\boldsymbol H_m=\mathrm{softmax}\Big(\frac{\boldsymbol X\boldsymbol W_q^m(\boldsymbol X\boldsymbol W_k^m)^\top}{\sqrt{D_k}}\Big)\boldsymbol X\boldsymbol W_v^m .
$$

**Transformer**。Transformer 编码器的每一层由“多头自注意力 + 逐位置前馈网络”组成，每个子层都带有**残差连接**和**层归一化**；输入为词嵌入加位置编码。解码器在此基础上增加**掩码自注意力**（只能看到已生成的位置）和**编码器-解码器注意力**（查询来自解码器，键和值来自编码器输出）。[幻灯片 38](#slide-38) [幻灯片 39](#slide-39)

```mermaid
flowchart BT
  X["输入词嵌入 + 位置编码"] --> A["多头自注意力"]
  A --> N1["残差连接 + 层归一化"]
  N1 --> F["逐位置前馈网络 FFN"]
  F --> N2["残差连接 + 层归一化"]
  N2 --> O["输出（堆叠 N 层）"]
  X -. 残差 .-> N1
  N1 -. 残差 .-> N2
```

**复杂度分析**。设序列长度为 $N$、表示维度为 $D$：[幻灯片 40](#slide-40)

| 层类型 | 每层复杂度 | 顺序操作数 | 最大路径长度 |
| --- | --- | --- | --- |
| 自注意力 | $O(N^2D)$ | $O(1)$ | $O(1)$ |
| 循环层 | $O(ND^2)$ | $O(N)$ | $O(N)$ |
| 卷积层（核大小 $K$） | $O(KND^2)$ | $O(1)$ | $O(\log_K N)$ |

自注意力任意两个位置之间的路径长度为 1，并且可以完全并行；代价是对序列长度的平方复杂度——这也是后来各种高效 Transformer 研究的出发点。Transformer 已成为 BERT、GPT 等预训练语言模型的基础架构。[幻灯片 41](#slide-41) [幻灯片 42](#slide-42)

拖动查询与键向量观察缩放点积注意力，并在自注意力矩阵中比较不同的头与因果掩码：

> （此处为交互演示，请在网页中使用：https://deeplearning.bnuai.com/chapters/08-attention-memory）

<p class="demo-link">在单独页面中打开：<a href="/demos/attention">注意力机制</a></p>

### 8.4 外部记忆

**大脑中的记忆**是分布式地存储在神经元之间的连接上的，具有周期性和联想性。[幻灯片 46](#slide-46) 类比到神经网络：[幻灯片 47](#slide-47)

| 记忆周期 | 计算机 | 人脑 | 神经网络 |
| --- | --- | --- | --- |
| 短期 | 寄存器 | 短期记忆 | 状态（神经元活性） |
| 中期 | 内存 | 工作记忆 | 外部记忆 |
| 长期 | 外存 | 长期记忆 | 可学习参数 |

为了在不显著增加参数的前提下提高网络容量，可以引入一个**外部记忆**单元，用来存储与任务相关的信息，需要时再读取。这种结构称为**记忆增强神经网络**，一般包括：主网络（控制器）、外部记忆单元、读取模块和写入模块。读取时用注意力机制根据查询向量 $\boldsymbol q$ 在记忆片段上“寻址”：$\boldsymbol r=\sum_{n=1}^N\alpha_n\boldsymbol m_n$，$\alpha_n=\mathrm{softmax}\big(s(\boldsymbol m_n,\boldsymbol q)\big)$。[幻灯片 49](#slide-49)

**端到端记忆网络**（MemN2N）：外部记忆是只读的。把输入 $\boldsymbol x_{1:N}$ 转换为两组记忆片段——用于寻址的 $\boldsymbol A=[\boldsymbol a_1,\cdots,\boldsymbol a_N]$ 和用于输出的 $\boldsymbol C=[\boldsymbol c_1,\cdots,\boldsymbol c_N]$，给定查询 $\boldsymbol q$：$\boldsymbol r=\sum_{n=1}^N\mathrm{softmax}(\boldsymbol a_n^\top\boldsymbol q)\,\boldsymbol c_n$，输出 $\boldsymbol y=f(\boldsymbol q+\boldsymbol r)$。为实现复杂推理，可以进行**多跳**操作：$\boldsymbol q^{(k)}=\boldsymbol r^{(k-1)}+\boldsymbol q^{(k-1)}$，反复读取记忆。[幻灯片 50](#slide-50) [幻灯片 52](#slide-52)

**神经图灵机**（NTM）：由控制器和一个可读写的外部记忆 $\boldsymbol M_t=[\boldsymbol m_{t,1},\cdots,\boldsymbol m_{t,N}]$ 组成。在每个时刻 $t$，控制器接收输入 $\boldsymbol x_t$、上一时刻的隐状态和读取向量 $\boldsymbol r_{t-1}$，产生查询 $\boldsymbol q_t$、删除向量 $\boldsymbol e_t$ 和增加向量 $\boldsymbol a_t$：[幻灯片 53](#slide-53) [幻灯片 54](#slide-54)

$$
\text{读：}\ \boldsymbol r_t=\sum_{n=1}^{N}\alpha_{t,n}\boldsymbol m_{t,n};\qquad
\text{写：}\ \boldsymbol m_{t+1,n}=\boldsymbol m_{t,n}\odot\big(\boldsymbol 1-\alpha_{t,n}\boldsymbol e_t\big)+\alpha_{t,n}\boldsymbol a_t .
$$

整个读写过程都是可微的，可以端到端训练，NTM 能学会复制、排序等简单算法。其后续工作**可微分神经计算机**（DNC）进一步引入动态内存分配和时序链接。[幻灯片 56](#slide-56)

### 8.5 基于神经动力学的联想记忆

前面的外部记忆是“按地址”或“按内容”寻址的结构化记忆。另一种思路是**联想记忆**：把记忆存储在神经网络的连接权重上，用一个不完整或带噪声的输入作为线索，通过网络的**动力学演化**收敛到存储的完整模式。这种基于内容寻址的记忆称为**自联想**（输入与输出模式在同一空间）或**异联想**。[幻灯片 57](#slide-57) [幻灯片 58](#slide-58)

**Hopfield 网络**是一种全连接的循环网络，所有神经元都相互连接，没有自连接 $w_{ii}=0$，且权重对称 $w_{ij}=w_{ji}$。离散 Hopfield 网络的神经元状态取 $\{+1,-1\}$，**异步**地更新：[幻灯片 60](#slide-60)

$$
s_i=\begin{cases}+1 & \text{若}\ \sum_{j=1}^{M}w_{ij}s_j+b_i\ge 0,\\ -1 & \text{否则.}\end{cases}
$$

**能量函数**：[幻灯片 61](#slide-61)

$$
E=-\frac12\sum_{i,j}w_{ij}s_is_j-\sum_i b_is_i .
$$

可以证明，在权重对称、无自连接、异步更新的条件下，每次更新都不会使能量增加，因此网络一定会收敛到某个局部最小点——称为**吸引点**。这些吸引点就是网络存储的模式。

**检索过程**：给定一个带噪声或不完整的输入作为初始状态，网络不断演化，最终收敛到离它最近的吸引点，从而“回忆”出完整的模式。[幻灯片 62](#slide-62)

**存储过程**：用 **Hebbian 规则**（“一起发放的神经元连在一起”）设置权重，把 $N$ 个模式 $\boldsymbol x^{(1)},\cdots,\boldsymbol x^{(N)}$ 存为吸引点：[幻灯片 63](#slide-63)

$$
w_{ij}=\frac1N\sum_{n=1}^{N}x_i^{(n)}x_j^{(n)} .
$$

$M$ 个二值神经元的 Hopfield 网络，可靠存储的模式数量约为 $0.14M$。改进的联想记忆模型（如稠密联想记忆、“现代 Hopfield 网络”）能显著提高容量，有趣的是，其更新规则与 Transformer 的注意力形式完全一致。联想记忆也可以作为外部记忆接入其他网络，以增加网络容量。[幻灯片 64](#slide-64)

## 本章小结

- 注意力 = 打分函数 + softmax 注意力分布 + 加权平均；变体包括硬注意力、键值对注意力、多头注意力、指针网络。
- 自注意力用 QKV 动态生成连接权重，Transformer = 多头自注意力 + FFN + 残差 + 层归一化 + 位置编码，复杂度 $O(N^2D)$ 但完全并行。
- 外部记忆提高网络容量：记忆网络（只读、多跳）、神经图灵机（可微读写）。
- Hopfield 网络通过能量下降收敛到吸引点，实现联想记忆；用 Hebbian 规则存储模式，容量约 $0.14M$。[幻灯片 65](#slide-65)

## 思考题与习题 {#exercises}

<div class="exercise-list">

1. **（分析）** 为什么缩放点积注意力要除以 $\sqrt{D_k}$？假设 $\boldsymbol q,\boldsymbol k$ 各维独立、均值 0、方差 1，计算 $\boldsymbol q^\top\boldsymbol k$ 的方差。
2. **（计算）** 设 $\boldsymbol q=[1,0]^\top$，键与值相同：$\boldsymbol x_1=[2,0]^\top,\ \boldsymbol x_2=[0,2]^\top,\ \boldsymbol x_3=[1,1]^\top$。用点积打分计算注意力分布和输出。
3. **（分析）** 自注意力模型中如果去掉位置编码，交换输入序列中两个词的位置，输出会怎样变化？
4. **（比较）** 从计算复杂度、并行性和长程依赖三个方面比较自注意力、循环网络与卷积网络。在什么序列长度下自注意力的计算量会超过循环层？
5. **（推导）** 证明离散 Hopfield 网络在异步更新时能量函数单调不增。
6. **（编程）** 用 NumPy 实现一个 Hopfield 网络，存储 3 个 $10\times10$ 的二值图案，测试在 10%、20%、30% 像素翻转噪声下的恢复效果。

</div>

**部分提示**

- 第 1 题：$\mathrm{var}(\boldsymbol q^\top\boldsymbol k)=D_k$，除以 $\sqrt{D_k}$ 后方差为 1，避免 softmax 进入饱和区。
- 第 2 题：打分 $[2,0,1]$，$\alpha\approx[0.665,0.090,0.245]$，输出约为 $[1.575,0.425]^\top$。
- 第 3 题：输出会做同样的置换——自注意力是置换等变的。
- 第 5 题：只更新第 $i$ 个神经元时，$\Delta E=-\Delta s_i\big(\sum_j w_{ij}s_j+b_i\big)\le0$。

## 延伸阅读

- 教材：邱锡鹏《神经网络与深度学习》第 8 章「注意力机制与外部记忆」。
- Bahdanau D, et al. Neural machine translation by jointly learning to align and translate, 2015；Vaswani A, et al. Attention is all you need, NeurIPS 2017。
- Sukhbaatar S, et al. End-to-end memory networks, 2015；Graves A, et al. Neural Turing machines, 2014；Hopfield J J. Neural networks and physical systems with emergent collective computational abilities, 1982。
- 实践：[nndl-practice](https://github.com/nndl/nndl-practice) 第 8 章「注意力机制」。
- 交互：[注意力机制](https://deeplearning.bnuai.com/demos/attention)。
- 第二版对应章节：第 8 章「注意力机制与 Transformer」。
