WARNING
🧪 Beta公测版本提示:教程主体已完成,正在优化细节,欢迎大家提Issue反馈问题或建议。
s05 前向传播与计算图 — exercise.py 练习指南
练习目标
通过实现三个核心模块——单层全连接前向传播、GELU 激活函数、计算图追踪,从代码层面深入理解神经网络前向传播的完整流程和计算图的概念。
预备知识
在开始练习前,确保你已经理解了以下概念(参见 demo.py 代码详解 中的详细解释):
- 线性变换
的矩阵维度规则 - ReLU、Sigmoid、Tanh 三种激活函数的定义和实现
- 中间值缓存(cache)的概念:存储
、 、 、 供反向传播使用 - GELU 的数学定义:
,其中 是标准正态 CDF - 计算图的概念:将复杂表达式分解为基本运算节点的有向无环图
任务清单
任务1:实现单层全连接层的前向传播 dense_layer_forward(A_prev, W, b, activation)
- 用到的公式:
- 线性变换:
- ReLU:
- Sigmoid:
- Tanh:
- 线性变换:
- 实现步骤:
- 计算
(矩阵乘法 + 广播加法) - 根据
activation参数选择激活函数:"relu":np.maximum(0, Z)"sigmoid":1.0 / (1.0 + np.exp(-Z))(注意数值稳定:可先用np.clip(Z, -500, 500))"tanh":np.tanh(Z)(NumPy 内置)"none":(恒等映射,无激活)
- 创建 cache 字典,包含
{Z: 线性输出, A_prev: 上一层激活, W: 权重矩阵, b: 偏置向量}
- 计算
- 需要调用的函数:
@运算符(矩阵乘法)、np.maximum()、np.exp()、np.tanh()、np.clip() - 返回:
(Z, A, cache)三元组 - 期望输出:
Z.shape为(n_curr, m),A.shape也为(n_curr, m),cache 包含四个键
任务2:实现 GELU 激活函数 gelu_exact(z) 与 gelu_derivative(z)
GELU 的精确数学定义:
其中
是标准正态分布的累积分布函数(CDF): 是误差函数(error function)。 GELU 的近似实现(如果需要避免引入 scipy):
GELU 导数的精确形式:
其中
是标准正态分布的概率密度函数(PDF): 实现提示:
- 如果使用 scipy:
from scipy.special import erf, - 如果不想引入 scipy:使用 tanh 近似公式
- 导数实现:需要同时用到
和
- 如果使用 scipy:
验证:
, ( 大时行为接近 ReLU),
任务3:手动追踪计算图 trace_computational_graph(X)
给定表达式:
其中
任务:把这个复合函数分解为 7 个基本运算节点,每个节点执行一个简单操作(加减乘除、Sigmoid)
计算图的节点链:
节点 计算 操作类型 输入 u1multiply , u2multiply , u3add , u4add , u5multiply , u6add , u7sigmoid 实现:对每个节点,计算并记录到
graph_nodes字典中每个节点的记录格式:
pythongraph_nodes["u1"] = { "value": 计算结果, "inputs": ["x1", "w1"], "op": "multiply" }Sigmoid 实现提示:
,可使用 np.exp()。为了防止数值溢出,建议先 clip 输入核心理解:这个练习让你手动体验 PyTorch/TensorFlow 底层在做什么——自动将复杂的数学表达式分解为计算图上的基本操作节点,每个节点只需要知道自己的局部操作和链式法则导数规则。
验证标准
运行 python exercise.py:
- TODO 1:对 4 种激活函数(relu, sigmoid, tanh, none)都应输出正确的
Z.shape和的范围 - TODO 2:
, for (如 时约等于 ) - TODO 3:打印出 7 个节点的计算图,最终输出
u7是一个在之间的值(因为经过了 Sigmoid)
源码位置
clone 后打开(相对仓库根目录):
docs/nn-decision/dl/forward-graph/code/exercise.py