SilverIce Toolbox
Back to course

Stage 3 / Chapter 10

第10章:深度学习概论与浅层网络 | Chapter 10: Deep Learning Basics & Shallow Networks

阶段定位 | Stage: 第三阶段 — 深度学习核心 预计学时 | Duration: 4~5 小时

---

学习目标 | Learning Objectives

中文:

  • 理解深度学习兴起的三大驱动力:数据、算力、算法
  • 掌握浅层神经网络的完整前向传播与维度追踪
  • 理解计算图的概念及反向传播的链式法则本质
  • 能独立写出带批处理的向量化前向传播代码
  • 建立"深层网络 = 多层非线性变换"的核心直觉

English:

  • Understand the three drivers of deep learning: data, compute, algorithms
  • Master complete forward propagation and dimension tracking for shallow networks
  • Understand computation graphs and the chain rule essence of backpropagation
  • Implement vectorized forward propagation with batch processing independently
  • Build the core intuition: deep network = multiple nonlinear transformations

---

10.1 为什么深度学习兴起 | Why Deep Learning Now?

中文解释

三个驱动力

驱动力变化影响
数据量互联网产生海量数据大数据 → 复杂模型才能充分利用
计算力GPU/TPU 并行计算深度网络训练从"月"缩短到"天"
算法ReLU、Dropout、BatchNorm、ResNet解决了梯度消失、过拟合等核心难题

性能与数据量的关系

对于传统机器学习(SVM、逻辑回归):

数据量 ↑ → 性能 ↑ → 很快饱和(模型容量有限)

对于小型神经网络:

数据量 ↑ → 性能 ↑ → 中等水平饱和

对于大型深度学习模型:

数据量 ↑ → 性能持续 ↑(只要模型足够大)
关键洞察:大型神经网络的性能上限远高于传统方法,但前提是有足够的数据和算力来训练。

English Explanation

Three Drivers:

  1. Data: Internet-scale datasets enable complex models
  2. Compute: GPUs reduce training from months to days
  3. Algorithms: ReLU, Dropout, BatchNorm, ResNet solved core problems

Performance vs Data:

  • Traditional ML: saturates quickly
  • Small NN: medium saturation
  • Large DL: keeps improving with more data

---

10.2 计算图与反向传播 | Computation Graphs & Backpropagation

中文解释

计算图

把复杂的计算分解成简单的操作节点,每个节点只知道自己的输入和输出:

X ──→ Linear ──→ ReLU ──→ Linear ──→ Sigmoid ──→ L (Loss)
         ↑ W1,b1              ↑ W2,b2

链式法则

如果 L = f(g(h(x))),那么:

dL/dx = dL/df · df/dg · dg/dh · dh/dx

反向传播就是沿着计算图从右向左,逐节点应用链式法则,把梯度传回去。

一个具体例子

Z = W·X + b
A = ReLU(Z)
L = -[y·log(A) + (1-y)·log(1-A)]

反向传播步骤:

dL/dA = -y/A + (1-y)/(1-A)           ← 从损失开始
dL/dZ = dL/dA · dA/dZ = dL/dA · 1(Z>0)  ← ReLU 的导数
dL/dW = dL/dZ · X.T                   ← 传给 W
dL/db = sum(dL/dZ)                    ← 传给 b

关键洞察

反向传播的高效性来自于局部计算:每个节点只需要知道:

  1. 自己的输出值(前向时保存)
  2. 从右边传过来的梯度
  3. 自己对输入的局部导数

不需要知道整个网络的结构!

English Explanation

Chain Rule:

dL/dx = dL/df · df/dg · dg/dh · dh/dx

Backpropagation efficiency: each node only needs:

  1. Its own output (saved during forward pass)
  2. Gradient flowing from the right
  3. Local derivative with respect to inputs

No need to know the entire network structure!

---

10.3 完整前向传播 | Complete Forward Propagation

代码案例

python
import numpy as np

np.random.seed(1)

# ========== 1. 定义激活函数 ==========
def relu(z):
    return np.maximum(0, z)

def sigmoid(z):
    return 1 / (1 + np.exp(-np.clip(z, -500, 500)))

# ========== 2. 网络结构 ==========
# 输入: 3 维
# 隐藏层: 4 个神经元 (ReLU)
# 输出层: 1 个神经元 (Sigmoid)
n_x, n_h, n_y = 3, 4, 1
m = 5  # batch size

# 参数初始化
W1 = np.random.randn(n_h, n_x) * 0.01
b1 = np.zeros((n_h, 1))
W2 = np.random.randn(n_y, n_h) * 0.01
b2 = np.zeros((n_y, 1))

# 数据
X = np.random.randn(n_x, m)
Y = np.random.randint(0, 2, (1, m))

print("=" * 50)
print("网络维度追踪 | Dimension Tracking")
print("=" * 50)
print(f"  X:    {X.shape}  ← 输入 (n_x={n_x}, m={m})")
print(f"  W1:   {W1.shape}  ← (n_h, n_x)")
print(f"  b1:   {b1.shape}  ← (n_h, 1)")
print(f"  W2:   {W2.shape}  ← (n_y, n_h)")
print(f"  b2:   {b2.shape}  ← (n_y, 1)")
print(f"  Y:    {Y.shape}  ← 标签 (n_y, m)")

# ========== 3. 前向传播 ==========
# Layer 1: 线性 + ReLU
Z1 = np.dot(W1, X) + b1    # (4, 3) @ (3, 5) + (4, 1) = (4, 5)
A1 = relu(Z1)               # (4, 5)

# Layer 2: 线性 + Sigmoid
Z2 = np.dot(W2, A1) + b2   # (1, 4) @ (4, 5) + (1, 1) = (1, 5)
A2 = sigmoid(Z2)            # (1, 5)

print("\n" + "=" * 50)
print("前向传播 | Forward Propagation")
print("=" * 50)
print(f"  Z1 = W1·X + b1:  {Z1.shape}")
print(f"  A1 = ReLU(Z1):   {A1.shape}")
print(f"  Z2 = W2·A1 + b2: {Z2.shape}")
print(f"  A2 = σ(Z2):      {A2.shape}  ← 输出概率")

# ========== 4. 损失计算 ==========
# 交叉熵损失
loss = -np.mean(Y * np.log(A2 + 1e-8) + (1 - Y) * np.log(1 - A2 + 1e-8))
print(f"\n交叉熵损失: {loss:.4f}")

# ========== 5. 反向传播(简要版) ==========
print("\n" + "=" * 50)
print("反向传播 | Backward Propagation")
print("=" * 50)

# dL/dA2
dA2 = -(np.divide(Y, A2 + 1e-8) - np.divide(1 - Y, 1 - A2 + 1e-8))
print(f"  dA2: {dA2.shape}")

# dL/dZ2 = dL/dA2 * g'(Z2)
dZ2 = dA2 * (A2 * (1 - A2))  # sigmoid 导数
print(f"  dZ2: {dZ2.shape}")

# dL/dW2 = dZ2 · A1.T / m
dW2 = (1/m) * np.dot(dZ2, A1.T)
db2 = (1/m) * np.sum(dZ2, axis=1, keepdims=True)
print(f"  dW2: {dW2.shape}, db2: {db2.shape}")

# dL/dA1 = W2.T · dZ2
dA1 = np.dot(W2.T, dZ2)
print(f"  dA1: {dA1.shape}")

# dL/dZ1 = dL/dA1 * g'(Z1)
dZ1 = dA1 * (Z1 > 0).astype(float)  # ReLU 导数
print(f"  dZ1: {dZ1.shape}")

# dL/dW1 = dZ1 · X.T / m
dW1 = (1/m) * np.dot(dZ1, X.T)
db1 = (1/m) * np.sum(dZ1, axis=1, keepdims=True)
print(f"  dW1: {dW1.shape}, db1: {db1.shape}")

print("\n✓ 所有梯度维度与参数维度匹配,可执行参数更新")

输出验证:

==================================================
网络维度追踪 | Dimension Tracking
==================================================
  X:    (3, 5)  ← 输入 (n_x=3, m=5)
  W1:   (4, 3)  ← (n_h, n_x)
  b1:   (4, 1)  ← (n_h, 1)
  W2:   (1, 4)  ← (n_y, n_h)
  b2:   (1, 1)  ← (n_y, 1)
  Y:    (1, 5)  ← 标签 (n_y, m)

==================================================
前向传播 | Forward Propagation
==================================================
  Z1 = W1·X + b1:  (4, 5)
  A1 = ReLU(Z1):   (4, 5)
  Z2 = W2·A1 + b2: (1, 5)
  A2 = σ(Z2):      (1, 5)  ← 输出概率

交叉熵损失: 0.6931

==================================================
反向传播 | Backward Propagation
==================================================
  dA2: (1, 5)
  dZ2: (1, 5)
  dW2: (1, 4), db2: (1, 1)
  dA1: (4, 5)
  dZ1: (4, 5)
  dW1: (4, 3), db1: (4, 1)

✓ 所有梯度维度与参数维度匹配,可执行参数更新
维度检查是神经网络调试中最基础也最重要的技能。每写一步矩阵运算,就写出它的 shape。

---

10.4 常见误区 | Common Pitfalls

1. 忘记保存前向传播的中间值

反向传播需要 Z1, A1, Z2, A2 等中间值。如果前向时没保存,反向时就得重新计算,浪费算力。

2. 矩阵乘法维度错误

最常见的 bug:np.dot(W, X) 写成了 np.dot(X, W)。养成习惯:先写预期 shape,再验证实际 shape。

3. 激活函数导数错误

  • ReLU 在 z=0 处不可导,实践中通常定义为 0 或 1,不影响训练
  • Sigmoid 导数 A*(1-A),不是 1/(1+e^-z) 本身

---

本章总结 | Chapter Summary

中文:

  • 深度学习兴起 = 大数据 + GPU算力 + 算法突破
  • 大型神经网络的数据效率曲线优于传统方法
  • 计算图把复杂运算分解为简单节点,反向传播沿图应用链式法则
  • 反向传播的高效性来自局部计算,每个节点只需局部信息
  • 维度追踪是神经网络代码调试的第一技能
  • 前向保存中间值,反向复用,避免重复计算

English:

  • Deep learning rise = big data + GPU compute + algorithmic breakthroughs
  • Large neural networks scale better with data than traditional methods
  • Computation graphs decompose complex operations into simple nodes
  • Backpropagation's efficiency comes from local computation
  • Dimension tracking is the #1 debugging skill for neural networks
  • Save intermediate values during forward pass for reuse in backward pass

---

课后练习 | Homework

  1. 手动反向传播:给定 X=(2,1), W1=(2,2), b1=(2,1), W2=(1,2), b2=(1,1), y=1,手动计算前向传播和反向传播的所有中间值和梯度。
  1. 维度追踪练习:设计一个网络:输入 10 维 → 隐藏层 1(20 神经元)→ 隐藏层 2(15 神经元)→ 输出 3 维。写出每一层前向和反向的完整维度变化。
  1. 计算图可视化:用 graphviz 或 ASCII 画出 L = (wx+b-y)² 的计算图,标注每个节点的局部导数。
  1. 批量大小实验:对同一网络,分别用 m=1, 16, 128, 1024 运行前向+反向传播。对比运行时间和梯度方差。
  1. 链式法则扩展:如果网络有 3 个隐藏层,写出从 dL/dA4dL/dW1 的完整链式法则展开式。