# 第 4 章　前馈神经网络

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

## 学习目标

<div class="goals">

- 理解人工神经元的计算方式，掌握 Logistic、Tanh、ReLU 及其变体、Swish、GELU 等激活函数的形式、导数与优缺点；
- 能写出前馈神经网络逐层的前向计算公式，理解“神经网络 = 复合函数”；
- 理解通用近似定理的含义与局限；
- **能够独立推导反向传播算法**，理解误差项 $\delta^{(l)}$ 的递推关系；
- 理解计算图与自动微分（前向模式 / 反向模式），区分静态图与动态图；
- 了解神经网络优化的主要困难：非凸优化与梯度消失。

</div>

## 课件幻灯片

> 本章课件共 47 页，可在网页中逐页浏览：https://deeplearning.bnuai.com/chapters/04-feedforward；PDF 下载：https://deeplearning.bnuai.com/pdf/nndl-ch04.pdf

## 讲义

### 4.1 从生物神经元到人工神经元

20 世纪 80 年代后期流行的连接主义模型——**并行分布式处理**（PDP）网络有三个特点：信息表示是分布式的；知识存储在单元之间的连接上；通过逐渐改变连接强度来学习新知识。现代神经网络继承了这些思想，并借助误差反向传播获得了强大的学习能力。[幻灯片 4](#slide-4)

生物神经元通过树突接收信号、在细胞体中整合，并在兴奋时通过轴突向其他神经元发放信号。**人工神经元**（简称神经元）是对它的极简抽象：接收输入 $\boldsymbol{x}=[x_1;\cdots;x_D]$，先计算加权和得到**净输入**（net input）

$$
z=\sum_{d=1}^{D} w_d x_d + b = \boldsymbol{w}^\top \boldsymbol{x} + b ,
$$

再经过一个非线性函数 $f(\cdot)$ 得到**活性值**（activation）$a=f(z)$。其中 $\boldsymbol w$ 是权重向量，$b$ 是偏置，$f$ 称为**激活函数**。去掉激活函数，神经元就是一个线性模型。[幻灯片 7](#slide-7)

### 4.2 激活函数

激活函数决定了网络的表达能力与可训练性。一个好的激活函数应当：[幻灯片 8](#slide-8)

1. **连续且（几乎处处）可导**，这样才能用基于梯度的方法学习参数；
2. **函数及其导数尽可能简单**，以提高计算效率；
3. **导数的值域处在合适的区间**，太大或太小都会影响训练的稳定性和效率。

**Sigmoid 型函数**。Logistic 函数和 Tanh 函数都是两端饱和的 S 型曲线：[幻灯片 9](#slide-9)

$$
\sigma(x)=\frac{1}{1+\exp(-x)},\qquad
\tanh(x)=\frac{\exp(x)-\exp(-x)}{\exp(x)+\exp(-x)} = 2\sigma(2x)-1 .
$$

它们的导数分别为 $\sigma'(x)=\sigma(x)\big(1-\sigma(x)\big)\le 0.25$ 与 $\tanh'(x)=1-\tanh^2(x)\le 1$。Logistic 函数的输出恒大于 0，是**非零中心化**的，会使后一层神经元的输入产生**偏置偏移**（bias shift），减慢梯度下降的收敛；Tanh 函数是零中心化的，通常收敛更快。两者共同的问题是**饱和**：$|x|$ 较大时导数接近 0。

**ReLU 及其变体**。修正线性单元（Rectified Linear Unit）是目前最常用的激活函数：[幻灯片 10](#slide-10)

$$
\mathrm{ReLU}(x)=\max(0,x)=\begin{cases}x & x\ge 0\\ 0 & x<0\end{cases}
$$

它的优点是：只需比较与赋值，计算高效；具有生物学上的**单侧抑制、宽兴奋边界**特性；在 $x>0$ 时导数恒为 1，在一定程度上缓解了梯度消失。缺点是输出非零中心化，并且存在**死亡 ReLU 问题**（Dying ReLU）：若某个神经元在所有训练样本上净输入都为负，它的梯度永远为 0，参数将不再更新。为此有多种改进：

- **带泄露的 ReLU**（Leaky ReLU）：$\mathrm{LeakyReLU}(x)=\max(x,\gamma x)$，$\gamma$ 为很小的常数（如 0.01）；若 $\gamma$ 作为可学习参数，则称为 **PReLU**；
- **ELU**：$x\ge0$ 时为 $x$，$x<0$ 时为 $\gamma(\exp(x)-1)$，近似零中心化；
- **Softplus**：$\log(1+\exp(x))$，可视为 ReLU 的平滑版本，其导数恰为 Logistic 函数。

**Swish 函数**是一种自门控（self-gated）激活函数：[幻灯片 11](#slide-11)

$$
\mathrm{swish}(x)=x\,\sigma(\beta x),
$$

$\sigma(\beta x)$ 像一个“软门”，控制 $x$ 通过的比例。$\beta=0$ 时退化为线性函数 $x/2$；$\beta\to\infty$ 时趋近 ReLU。

**GELU**（高斯误差线性单元）与 Swish 类似，用高斯分布的累积分布函数作为门控：[幻灯片 12](#slide-12)

$$
\mathrm{GELU}(x)=x\,P(X\le x),\quad X\sim\mathcal N(0,1),
$$

实际中常用近似 $\mathrm{GELU}(x)\approx 0.5x\left(1+\tanh\!\left(\sqrt{2/\pi}\,(x+0.044715x^3)\right)\right)$ 或 $x\,\sigma(1.702x)$。GELU 被 BERT、GPT 等 Transformer 模型广泛采用。

下面的交互图可以直观比较这些函数和它们的导数（勾选“显示导数”）：

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

### 4.3 网络结构

单个神经元能力有限，神经网络由大量神经元按一定的**拓扑结构**连接而成。设计一个神经网络需要考虑三方面：神经元的激活规则、网络的拓扑结构、学习算法。[幻灯片 14](#slide-14) 常见的拓扑有三类：[幻灯片 15](#slide-15)

- **前馈网络**：各神经元按层排列，信息单向传播，可以用有向无环图表示，如全连接前馈网络、卷积网络；
- **记忆网络**（反馈网络）：神经元可以接收自己的历史信息，具有记忆能力，如循环神经网络、Hopfield 网络；
- **图网络**：定义在图结构数据上，每个节点由一个或一组神经元构成，是前两者的推广。

### 4.4 前馈神经网络

**前馈神经网络**（Feedforward Neural Network, FNN），也常被称为**多层感知器**（MLP），其中：各神经元分属不同的层，层内无连接；相邻两层的神经元两两全连接；整个网络无反馈。[幻灯片 17](#slide-17)

记号约定：$L$ 为层数（不计输入层）；$M_l$ 为第 $l$ 层神经元个数；$f_l(\cdot)$ 为第 $l$ 层激活函数；$\boldsymbol W^{(l)}\in\mathbb R^{M_l\times M_{l-1}}$、$\boldsymbol b^{(l)}\in\mathbb R^{M_l}$ 为第 $l-1$ 层到第 $l$ 层的权重矩阵与偏置；$\boldsymbol z^{(l)}$、$\boldsymbol a^{(l)}$ 分别是第 $l$ 层的净输入与输出。[幻灯片 18](#slide-18)

令 $\boldsymbol a^{(0)}=\boldsymbol x$，前馈网络逐层计算：[幻灯片 19](#slide-19)

$$
\boldsymbol z^{(l)}=\boldsymbol W^{(l)}\boldsymbol a^{(l-1)}+\boldsymbol b^{(l)},\qquad
\boldsymbol a^{(l)}=f_l\big(\boldsymbol z^{(l)}\big).
$$

于是整个网络可以写成一个复合函数

$$
\boldsymbol x=\boldsymbol a^{(0)}\rightarrow\boldsymbol z^{(1)}\rightarrow\boldsymbol a^{(1)}\rightarrow\boldsymbol z^{(2)}\rightarrow\cdots\rightarrow\boldsymbol a^{(L-1)}\rightarrow\boldsymbol z^{(L)}\rightarrow\boldsymbol a^{(L)}=\phi(\boldsymbol x;\boldsymbol W,\boldsymbol b).
$$

```mermaid
flowchart LR
  X["输入 x = a⁽⁰⁾"] --> Z1["z⁽¹⁾ = W⁽¹⁾a⁽⁰⁾ + b⁽¹⁾"] --> A1["a⁽¹⁾ = f₁(z⁽¹⁾)"] --> D["⋯"] --> ZL["z⁽ᴸ⁾"] --> AL["ŷ = a⁽ᴸ⁾"] --> Loss["损失 𝓛(y, ŷ)"]
```

**通用近似定理**。设 $\phi(\cdot)$ 是一个非常数、有界、单调递增的连续函数，$\mathcal I_D$ 是 $D$ 维单位超立方体 $[0,1]^D$，$C(\mathcal I_D)$ 是定义在其上的连续函数集合。对任意 $f\in C(\mathcal I_D)$ 和 $\epsilon>0$，存在整数 $M$、实数 $v_m,b_m$ 与向量 $\boldsymbol w_m$，使得

$$
F(\boldsymbol x)=\sum_{m=1}^{M}v_m\,\phi\big(\boldsymbol w_m^\top\boldsymbol x+b_m\big)
$$

满足 $|F(\boldsymbol x)-f(\boldsymbol x)|<\epsilon,\ \forall\boldsymbol x\in\mathcal I_D$。[幻灯片 21](#slide-21)

也就是说，**只要隐藏层神经元足够多，一个带“挤压”型激活函数的两层网络就能以任意精度逼近有界闭集上的连续函数**；该结论对 ReLU 等激活函数同样成立。但定理只保证“存在”，并没有告诉我们需要多少神经元、能否通过学习找到这组参数，以及能否泛化——这正是后续章节要解决的问题。

**作为分类器**。把神经网络看作特征变换 $\phi(\boldsymbol x)$，在其后接一个分类器 $g(\cdot)$ 即可完成分类。[幻灯片 22](#slide-22) 对多分类问题，常在最后一层放置 $C$ 个神经元并接 Softmax：$\hat{\boldsymbol y}=\mathrm{softmax}(\boldsymbol z^{(L)})$，采用交叉熵损失 [幻灯片 24](#slide-24)

$$
\mathcal L(\boldsymbol y,\hat{\boldsymbol y})=-\boldsymbol y^\top\log\hat{\boldsymbol y}.
$$

下面的“训练场”在浏览器里实时训练一个前馈神经网络。增删隐藏层、改变激活函数，观察网络能拟合的分类边界：

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

<p class="demo-link">在单独页面中打开：<a href="/demos/mlp-playground">前馈网络训练场</a></p>

### 4.5 参数学习

给定训练集 $\mathcal D=\{(\boldsymbol x^{(n)},\boldsymbol y^{(n)})\}_{n=1}^N$，结构化风险函数为 [幻灯片 25](#slide-25)

$$
\mathcal R(\boldsymbol W,\boldsymbol b)=\frac1N\sum_{n=1}^{N}\mathcal L\big(\boldsymbol y^{(n)},\hat{\boldsymbol y}^{(n)}\big)+\frac12\lambda\|\boldsymbol W\|_F^2,
$$

其中 $\|\boldsymbol W\|_F^2=\sum_{l=1}^{L}\sum_{i=1}^{M_l}\sum_{j=1}^{M_{l-1}}\big(w^{(l)}_{ij}\big)^2$ 是 Frobenius 范数正则项。用梯度下降更新参数：

$$
\boldsymbol W^{(l)}\leftarrow\boldsymbol W^{(l)}-\alpha\frac{\partial\mathcal R}{\partial\boldsymbol W^{(l)}}
=\boldsymbol W^{(l)}-\alpha\Big(\frac1N\sum_{n=1}^N\frac{\partial\mathcal L(\boldsymbol y^{(n)},\hat{\boldsymbol y}^{(n)})}{\partial\boldsymbol W^{(l)}}+\lambda\boldsymbol W^{(l)}\Big),\qquad
\boldsymbol b^{(l)}\leftarrow\boldsymbol b^{(l)}-\alpha\frac1N\sum_{n=1}^N\frac{\partial\mathcal L}{\partial\boldsymbol b^{(l)}}.
$$

问题归结为：**如何高效地计算损失对每一层参数的梯度？** 神经网络是一个复杂的复合函数，逐个参数用链式法则求导会有大量重复计算。两种高效方案是专为前馈网络设计的**反向传播算法**，以及更通用的**自动微分**。[幻灯片 27](#slide-27)

### 4.6 反向传播算法

**矩阵微积分**。本书采用**分母布局**：标量 $y$ 对向量 $\boldsymbol x\in\mathbb R^M$ 的偏导数是 $M$ 维列向量 $\frac{\partial y}{\partial \boldsymbol x}=\big[\frac{\partial y}{\partial x_1},\cdots,\frac{\partial y}{\partial x_M}\big]^\top$；向量 $\boldsymbol y\in\mathbb R^N$ 对向量 $\boldsymbol x\in\mathbb R^M$ 的偏导数是 $M\times N$ 矩阵，第 $(i,j)$ 个元素为 $\frac{\partial y_j}{\partial x_i}$。在这一布局下，若 $\boldsymbol x\to\boldsymbol y\to z$，则链式法则写作 $\frac{\partial z}{\partial\boldsymbol x}=\frac{\partial\boldsymbol y}{\partial\boldsymbol x}\frac{\partial z}{\partial\boldsymbol y}$。[幻灯片 28](#slide-28) [幻灯片 29](#slide-29)

以单个样本的损失 $\mathcal L(\boldsymbol y,\hat{\boldsymbol y})$ 为例。由 $\boldsymbol z^{(l)}=\boldsymbol W^{(l)}\boldsymbol a^{(l-1)}+\boldsymbol b^{(l)}$，根据链式法则

$$
\frac{\partial\mathcal L}{\partial w^{(l)}_{ij}}=\frac{\partial\boldsymbol z^{(l)}}{\partial w^{(l)}_{ij}}\frac{\partial\mathcal L}{\partial\boldsymbol z^{(l)}},\qquad
\frac{\partial\mathcal L}{\partial\boldsymbol b^{(l)}}=\frac{\partial\boldsymbol z^{(l)}}{\partial\boldsymbol b^{(l)}}\frac{\partial\mathcal L}{\partial\boldsymbol z^{(l)}}.
$$

第一个因子很好算：$\frac{\partial\boldsymbol z^{(l)}}{\partial w^{(l)}_{ij}}$ 只有第 $i$ 个分量非零，等于 $a^{(l-1)}_j$；$\frac{\partial\boldsymbol z^{(l)}}{\partial\boldsymbol b^{(l)}}=\boldsymbol I_{M_l}$。关键是第二个因子，我们把它定义为第 $l$ 层的**误差项**：[幻灯片 30](#slide-30)

$$
\boldsymbol\delta^{(l)}\triangleq\frac{\partial\mathcal L(\boldsymbol y,\hat{\boldsymbol y})}{\partial\boldsymbol z^{(l)}}\in\mathbb R^{M_l}.
$$

误差项反映了第 $l$ 层神经元对最终损失的“贡献”（敏感程度）。由于 $\boldsymbol z^{(l+1)}=\boldsymbol W^{(l+1)}\boldsymbol a^{(l)}+\boldsymbol b^{(l+1)}$、$\boldsymbol a^{(l)}=f_l(\boldsymbol z^{(l)})$，有 $\frac{\partial\boldsymbol z^{(l+1)}}{\partial\boldsymbol a^{(l)}}=(\boldsymbol W^{(l+1)})^\top$，$\frac{\partial\boldsymbol a^{(l)}}{\partial\boldsymbol z^{(l)}}=\mathrm{diag}\big(f_l'(\boldsymbol z^{(l)})\big)$，于是 [幻灯片 31](#slide-31)

$$
\boldsymbol\delta^{(l)}=\frac{\partial\boldsymbol a^{(l)}}{\partial\boldsymbol z^{(l)}}\frac{\partial\boldsymbol z^{(l+1)}}{\partial\boldsymbol a^{(l)}}\frac{\partial\mathcal L}{\partial\boldsymbol z^{(l+1)}}
=\mathrm{diag}\big(f_l'(\boldsymbol z^{(l)})\big)(\boldsymbol W^{(l+1)})^\top\boldsymbol\delta^{(l+1)}
=f_l'(\boldsymbol z^{(l)})\odot\Big((\boldsymbol W^{(l+1)})^\top\boldsymbol\delta^{(l+1)}\Big).
$$

这就是**误差的反向传播**：第 $l$ 层的误差项可以由第 $l+1$ 层的误差项乘以权重矩阵的转置、再逐元素乘以激活函数的导数得到。有了误差项，梯度立即可得：[幻灯片 32](#slide-32)

$$
\frac{\partial\mathcal L}{\partial\boldsymbol W^{(l)}}=\boldsymbol\delta^{(l)}\big(\boldsymbol a^{(l-1)}\big)^\top\in\mathbb R^{M_l\times M_{l-1}},\qquad
\frac{\partial\mathcal L}{\partial\boldsymbol b^{(l)}}=\boldsymbol\delta^{(l)}.
$$

对于 Softmax 输出 + 交叉熵损失，最后一层的误差项有非常简洁的形式 $\boldsymbol\delta^{(L)}=\hat{\boldsymbol y}-\boldsymbol y$（见习题 3）。

**算法 4.1　使用反向传播的随机梯度下降**

输入：训练集 $\mathcal D$，学习率 $\alpha$，正则化系数 $\lambda$，网络层数 $L$。

1. 随机初始化 $\boldsymbol W,\boldsymbol b$；
2. **重复**：对训练集随机排序；对每个样本 $(\boldsymbol x^{(n)},\boldsymbol y^{(n)})$：
   1. **前向计算**每一层的净输入 $\boldsymbol z^{(l)}$ 和激活值 $\boldsymbol a^{(l)}$，直到最后一层；
   2. **反向传播**计算每一层的误差项 $\boldsymbol\delta^{(l)}$（从 $l=L$ 到 $1$）；
   3. 计算梯度 $\frac{\partial\mathcal L}{\partial\boldsymbol W^{(l)}}=\boldsymbol\delta^{(l)}(\boldsymbol a^{(l-1)})^\top$、$\frac{\partial\mathcal L}{\partial\boldsymbol b^{(l)}}=\boldsymbol\delta^{(l)}$；
   4. **更新参数** $\boldsymbol W^{(l)}\leftarrow\boldsymbol W^{(l)}-\alpha\big(\boldsymbol\delta^{(l)}(\boldsymbol a^{(l-1)})^\top+\lambda\boldsymbol W^{(l)}\big)$，$\boldsymbol b^{(l)}\leftarrow\boldsymbol b^{(l)}-\alpha\boldsymbol\delta^{(l)}$；
3. **直到**模型在验证集上的错误率不再下降。

逐步执行一个 2-2-1 网络的前向传播与反向传播，所有数值都是实时计算的，可以和上面的公式一一对照：

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

<p class="demo-link">在单独页面中打开：<a href="/demos/backprop">反向传播逐步演示</a></p>

### 4.7 计算图与自动微分

**自动微分**（Automatic Differentiation, AD）把复合函数分解为一系列基本运算（加、乘、指数、对数等），构成**计算图**，再沿图应用链式法则自动求梯度。[幻灯片 34](#slide-34) 以 $f(x;w,b)=\dfrac{1}{\exp(-(wx+b))+1}$ 为例，可以分解为：

| 中间变量 | 函数 | 局部导数 |
| --- | --- | --- |
| $h_1=x\times w$ | 乘法 | $\partial h_1/\partial w=x$ |
| $h_2=h_1+b$ | 加法 | $\partial h_2/\partial h_1=1,\ \partial h_2/\partial b=1$ |
| $h_3=h_2\times(-1)$ | 取负 | $\partial h_3/\partial h_2=-1$ |
| $h_4=\exp(h_3)$ | 指数 | $\partial h_4/\partial h_3=\exp(h_3)$ |
| $h_5=h_4+1$ | 加法 | $\partial h_5/\partial h_4=1$ |
| $h_6=1/h_5$ | 倒数 | $\partial h_6/\partial h_5=-1/h_5^2$ |

当 $x=1,w=0,b=0$ 时，沿路径相乘得 [幻灯片 35](#slide-35)

$$
\frac{\partial f}{\partial w}=\frac{\partial h_6}{\partial h_5}\frac{\partial h_5}{\partial h_4}\frac{\partial h_4}{\partial h_3}\frac{\partial h_3}{\partial h_2}\frac{\partial h_2}{\partial h_1}\frac{\partial h_1}{\partial w}=(-0.25)\times1\times1\times(-1)\times1\times1=0.25 .
$$

若函数与参数之间有多条路径，把各条路径上的导数相加即可。[幻灯片 36](#slide-36) 按计算导数的顺序，自动微分分为两种模式：

- **前向模式**：沿计算图从输入到输出，计算每个中间变量对某个输入的导数；对 $f:\mathbb R^N\to\mathbb R^M$，需要 $N$ 遍前向计算；
- **反向模式**：沿计算图从输出到输入，计算输出对每个中间变量的导数；需要 $M$ 遍反向计算。

神经网络的损失是标量（$M=1$）而参数数量 $N$ 极大，因此反向模式效率最高——**反向传播算法正是自动微分反向模式在前馈网络上的特例**。[幻灯片 37](#slide-37)

**静态图与动态图**。静态计算图（Theano、早期 TensorFlow）在编译时构建，运行时不能改变，便于优化和并行，但灵活性差；动态计算图（PyTorch、Chainer、DyNet）在程序运行时动态构建，便于调试和处理可变结构的输入，但优化难度较大。[幻灯片 38](#slide-38) 现代框架（如 PyTorch 2.x 的 `torch.compile`、JAX 的 `jit`）则试图兼顾两者。

有了自动微分，“深度学习三步走”变得非常简单：**定义网络 → 定义损失 → 选择优化器并训练**。[幻灯片 41](#slide-41)

### 4.8 优化问题

神经网络的参数学习比线性模型困难得多：[幻灯片 43](#slide-43)

- **非凸优化**：即使是一个只有一个隐藏层的简单网络，损失函数关于参数也是非凸的，存在大量局部极值点和鞍点；[幻灯片 44](#slide-44)
- **梯度消失**：误差项反向传播时每经过一层都要乘以 $f_l'(\boldsymbol z^{(l)})$。Sigmoid 型函数的导数 $\sigma'(x)\le0.25$、$\tanh'(x)\le1$，在饱和区更是接近 0，误差经过多层传递后会不断衰减，底层参数几乎得不到更新，这就是**梯度消失问题**。[幻灯片 45](#slide-45) 缓解方法包括使用 ReLU 等导数较大的激活函数、更好的参数初始化、归一化与残差连接（见第 5、7 章）。

此外还有参数多、需要大量数据和计算资源、可解释性差等问题。第 7 章将系统介绍网络优化与正则化的方法。

## 本章小结

- 人工神经元 = 线性加权求和 + 非线性激活；激活函数需可导、简单、导数范围合适。ReLU 是默认选择，Transformer 中常用 GELU / Swish。
- 前馈网络逐层计算 $\boldsymbol z^{(l)}=\boldsymbol W^{(l)}\boldsymbol a^{(l-1)}+\boldsymbol b^{(l)}$，$\boldsymbol a^{(l)}=f_l(\boldsymbol z^{(l)})$，整体是一个复合函数。
- 通用近似定理说明了网络的表达能力，但不保证可学习与可泛化。
- 反向传播的核心是误差项递推 $\boldsymbol\delta^{(l)}=f_l'(\boldsymbol z^{(l)})\odot(\boldsymbol W^{(l+1)})^\top\boldsymbol\delta^{(l+1)}$，梯度为 $\boldsymbol\delta^{(l)}(\boldsymbol a^{(l-1)})^\top$。
- 自动微分在计算图上自动求导，反向模式适合“参数多、输出为标量”的神经网络训练。
- 主要优化困难：非凸、梯度消失。

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

<div class="exercise-list">

1. **（推导）** 证明 $\sigma'(x)=\sigma(x)(1-\sigma(x))$、$\tanh'(x)=1-\tanh^2(x)$，以及 $\tanh(x)=2\sigma(2x)-1$。
2. **（概念）** 如果把一个前馈网络所有隐藏层的激活函数都换成恒等函数 $f(x)=x$，网络的表达能力会发生什么变化？为什么？
3. **（推导）** 设输出层 $\hat{\boldsymbol y}=\mathrm{softmax}(\boldsymbol z^{(L)})$，损失 $\mathcal L=-\boldsymbol y^\top\log\hat{\boldsymbol y}$（$\boldsymbol y$ 为 one-hot 向量），证明 $\boldsymbol\delta^{(L)}=\hat{\boldsymbol y}-\boldsymbol y$。
4. **（计算）** 一个 784–256–128–10 的全连接网络（含偏置）共有多少个参数？若输入改为 3×224×224 的彩色图像，第一层参数量会变成多少？这说明了全连接网络的什么问题？
5. **（计算图）** 对 4.7 节的函数 $f(x;w,b)$，取 $x=2,w=1,b=-1$，用反向模式分别计算 $\partial f/\partial w$ 与 $\partial f/\partial b$，并用数值差分验证。
6. **（分析）** 解释为什么 ReLU 能缓解梯度消失，什么情况下会出现“死亡 ReLU”？列举两种缓解办法。
7. **（编程）** 只用 NumPy 实现一个两层前馈网络（含前向、反向传播与 SGD），在 XOR 数据或 $y=\sin x$ 的拟合任务上训练，并用自动微分框架（如 PyTorch）的梯度对照检查你的实现。

</div>

**部分提示**

- 第 2 题：多个线性变换的复合仍是线性变换，整个网络退化为线性模型。
- 第 3 题：先求 $\frac{\partial\hat{\boldsymbol y}}{\partial\boldsymbol z}=\mathrm{diag}(\hat{\boldsymbol y})-\hat{\boldsymbol y}\hat{\boldsymbol y}^\top$，再利用 $\boldsymbol 1^\top\boldsymbol y=1$。
- 第 4 题：$784\times256+256+256\times128+128+128\times10+10=235{,}146$；第一层若输入 $3\times224\times224=150{,}528$ 维，仅第一层就约有 $3.85\times10^7$ 个参数。
- 第 5 题：$\partial f/\partial w=x\,\sigma(wx+b)(1-\sigma(wx+b))$，代入得 $2\sigma(1)(1-\sigma(1))\approx0.393$。

## 延伸阅读

- 教材：邱锡鹏《神经网络与深度学习》第 4 章「前馈神经网络」及附录 B「数学基础」中的矩阵微积分。
- 实践：[nndl-practice](https://github.com/nndl/nndl-practice) 第 4 章（前馈神经网络，PyTorch 实现）。
- 交互：[激活函数可视化](https://deeplearning.bnuai.com/demos/activation)；[前馈网络训练场](https://deeplearning.bnuai.com/demos/mlp-playground)；[反向传播逐步演示](https://deeplearning.bnuai.com/demos/backprop)；TensorFlow Playground（playground.tensorflow.org）可直观观察隐藏层与激活函数的作用。
- 第二版对应章节：第 4 章「前馈神经网络」。
