十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

《神经网络与深度学习》:反向传播算法快速指南,如何在 10 分钟手算出一个小网络的全部 9 个梯度

《神经网络与深度学习》:反向传播算法快速指南,如何在 10 分钟手算出一个小网络的全部 9 个梯度 《神经网络与深度学习》反向传播算法快速指南如何在 10 分钟手算出一个小网络的全部 9 个梯度【免费下载链接】nndl邱锡鹏《神经网络与深度学习》第二版与通识版电子书、章节目录、学习资源与勘误。项目地址: https://gitcode.com/GitHub_Trending/nn/nndl有个反直觉的现象一个上亿参数的模型每次训练步都要产出上亿个偏导数可反向这一趟的计算量却和正向几乎一样。邱锡鹏《神经网络与深度学习》重点讲解的反向传播算法Backpropagation就是靠链式法则Chain Rule把全局求导压缩成逐层局部相乘——这是神经网络里最值得手算一遍的部分。接下来 20 分钟你会完成三件事在 10 分钟内手算完一个 2-2-1 网络的全部 9 个梯度值并用代码核对到相对误差小于 1e-8读懂不超过 30 行的反向传播循环指得出哪一行在做转置、哪一行在做逐元素乘用 4 个典型故障现象1 分钟判断loss 不降是出在反向实现还是超参数反向传播的全景链路梯度从哪里来、到哪里去先建立完整的心智模型再碰公式。前馈网络的训练可以拆成三段数据往前走误差往回走正向: X ─→ z1 ─→ a1 ─→ z2 ─→ a2 ─→ L 每步把 z 和 a 缓存下来 反向: L ─→ δ2 ─→ δ1 上游误差 × 本地斜率逐层回传 梯度: dW δ · a_prevᵀ, db δ 误差 × 缓存中间值 参数梯度三类符号各管一件事z 是激活前的线性值a 是激活后的非线性值δ 是这一层对损失负多少责。δ 一定义好整个反向过程就不存在加减法了——它只做乘法权重转置把误差送回去激活函数的导数把误差缩小误差与上一层输出的外积给出权重梯度。这也是反向传播和正向传播耗时相近的原因正向算一遍并把中间值缓存起来反向只是读缓存、做乘法。机制拆解误差项的定义、回传公式与转置为何出现拆成三层看先定是什么再写怎么算最后问为什么这样设计。误差项是什么输出层的本地责任把 δ 定义为 ∂L/∂z 而不是 ∂L/∂a乍看别扭动机很实际z 是出现在 W 梯度里的直接变量因为 z Wa bz 对 W 的导数恰好是 a而 a 只是 z 的激活后形态。对着 z 定义 δ输出层的量就能一步写出δ2 (a2 - Y) ⊙ σ(z2) # 输出层误差损失对激活前量的梯度 dW2 δ2 · a1ᵀ # 权重梯度误差与上一层输出的外积 db2 δ2 # 偏置梯度误差本身⊙ 表示逐元素相乘。用平方损失时 σ(z2) 1δ2 退化成 a2 − Y即误差等于残差的特例换成交叉熵配 softmax 时两项同样抵消——这正是分类任务偏爱这一组合的原因。隐藏层误差的逐层回传公式转置矩阵的那一步隐藏层看不到损失只能从上层接收压力。压力的交接公式是δ1 (W2ᵀ · δ2) ⊙ σ(z1) # 隐藏层误差 回传压力 × 本地斜率 dW1 δ1 · Xᵀ # 与输出层同构直接套用 db1 δ1(W2ᵀ·δ2) 的读法W2 的每个元素记录着对应的隐藏神经元对下一层贡献了多少把上游压力 δ2 沿 W2ᵀ 传回去等于给每个隐藏神经元发问——你制造了多少上游误差乘以你的贡献权重。这就是压力回传矩阵转置把整段求和压成了一行。为什么是 (Wᵀδ)⊙σ(z)链式法则的拆读法用链式法则拆开只有两步第1步 ∂L/∂z1_i Σ_j (∂L/∂z2_j) · (∂z2_j/∂z1_i) Σ_j δ2_j · W2_ji ← 这个求和正是 W2ᵀ·δ2 的第 i 个元素 第2步 ∂L/∂z1_i (回传压力) · σ(z1_i) ← 激活函数自己的本地斜率第 1 步是全局的只依赖网络结构权重第 2 步是本地的只依赖激活函数。这种拆分就是反向传播的设计本质全局部分正向时算好并缓存反向时复用每层只付自己那份本地导数的代价。它同时解释了两件事——换激活函数只影响第 2 步改网络结构只影响第 1 步的权重。手撕验证一个 2-2-1 网络的全部 9 个梯度 算一个具体例子输入 X [0.5, 1.0]真实值 Y 0两个隐藏神经元、一个输出激活函数全用 sigmoid。参数刻意选了一组不常见的数方便你和书上的示例交叉核对W1 [[0.3, 0.1], [0.8, 0.2]] b1 [0.4, -0.2] W2 [0.6, -0.4] b2 0.1手算路径z1 [0.65, 0.40]a1 ≈ [0.657, 0.599]z2 ≈ 0.255a2 ≈ 0.563。于是 δ2 (a2 − Y)·a2(1 − a2) ≈ 0.139回传隐藏层压力 W2ᵀδ2 ≈ [0.083, −0.056]再乘本地斜率 a1(1 − a1) ≈ [0.225, 0.240]得 δ1 ≈ [0.019, −0.013]。到这一步dW1、db1、dW2、db2 四组梯度全部能写出来全程不超过 10 分钟纸笔计算。同样的计算十行代码验证import numpy as np sig lambda z: 1/(1np.exp(-z)) X, Y np.array([0.5, 1.0]), 0.0 # 输入与真实值 W1, b1 np.array([[0.3, 0.1],[0.8, 0.2]]), np.array([0.4, -0.2]) W2, b2 np.array([0.6, -0.4]), 0.1 z1 W1X b1; a1 sig(z1) # 前向并缓存 z2 W2a1 b2; a2 sig(z2) dL (a2 - Y) * a2 * (1 - a2) # 输出层误差 δ2 dW2, db2 dL * a1, dL dL1 (W2 * dL) * a1 * (1 - a1) # 隐藏层误差 δ1 dW1, db1 np.outer(dL1, X), dL1 print(dW1, db1, dW2, db2)再对每个参数做 1e-6 微扰、用中心差分求数值梯度对比两边相对误差应在 1e-8 以内——这是判断反向传播实现正确的最经济手段。容易踩的四个坑现象、原因与解法 ⚠️真正的坑通常不是推不出而是推对了但实现跑偏。四个典型现象都按现象 → 原因 → 解法列出梯度检查对不上 1e-3。手算/数值梯度和解析梯度差到第三位小数。原因多为 float32 精度不够或 eps 1e-5 太小导致差商被浮点噪声吞掉。解法换 float64eps 取 1e-6 的中心差分并按相对误差 |a−b|/(|a||b|1e-8) 比对。loss 降得极慢且早早停滞。原因sigmoid 导数峰值只有 0.25每回传一层最多缩为 1/4逐层连乘呈指数衰减梯度消失。解法换 tanh 或 ReLU并把权重初始化按层宽度缩放Xavier / He让 z 落在 0 附近。前几步正常随后出现 NaN。原因多半是学习率过大导致参数发散或损失里出现 log(0)softmax 输出恰好为 0。解法先用 1e-4 的学习率跑通 1 步确认流水线log 概率前加一个小常数。loss 在降偏置却恒为 0。调试时发现偏置向量全程不动。原因反向循环里只算了 dW漏了 db δ 这一项。解法把偏置看作输入恒为 1 的权重重新推导一遍它的梯度就是 δ 本身。梯度与更新的直观关系可以看仓库里的可视化资源不同优化器在三维损失面上走出很不一样的路径但方向都来自同一份反向传播出的梯度。延伸入口算完梯度之后往哪走三个由浅入深的入口优化轨迹可视化viz/optimizers.md 对比 SGD / Momentum / Adam 在三维损失面上的轨迹是反向传播之后的自然下一步框架实现对照nndl-practice/index.md 是实践篇含 PyTorch 代码可与本文手撕的 2-2-1 互相印证选书与章节索引nndl-v2/index.md 有第二版完整目录与勘误入口reading-path/index.md 给出四本书的组合建议反向传播从来不是要背的公式而是读缓存、做乘法的流程——把 2-2-1 这一个例子亲手跑通后面所有变体都能从这里推出来。【免费下载链接】nndl邱锡鹏《神经网络与深度学习》第二版与通识版电子书、章节目录、学习资源与勘误。项目地址: https://gitcode.com/GitHub_Trending/nn/nndl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表