读书笔记:神经网络是如何训练的
(本文是根据 neuralnetworksanddeeplearning 这本书的第二章How the backpropagation algorithm works整理而成的读书笔记,根据个人口味做了删减)
在上一章的学习中,我们介绍了神经网络可以用梯度下降法来训练,但梯度的计算方法却没有给出。在本章中,我们将学习一种计算神经网络梯度的方法——后向传播算法(backpropagation)。
backpropagation 算法起源于上个世纪 70 年代,但一直到 Hinton 等人在 1986 年发表的这篇著名论文后才开始受到关注。BP 算法使得神经网络的训练速度快速提升,因此它是学习神经网络的重中之重。
热身:一种基于矩阵的快速计算神经网络输出的方法
在开始讨论 BP 算法之前,我们先回顾一种基于矩阵形式的计算神经网络输出的方法。
首先,引入几个符号表示。
假设 表示从第 l-1 层的第 k 个神经元到第 l 层的第 j 个神经元的权值,如下图所示。
假设 表示 l 层第 j 个神经元的偏差, 表示 l 层第 j 个神经元的激活层,如下图所示:
有了这些标记,第 l 层的第 j 个神经元的激活层 就可以和 l-1 层的激活层关联起来:
其中, 是一个激活函数,例如 sigmoid 函数之类的。
现在,为了方便书写,我们为每一层定义一个权值矩阵 ,矩阵的每个元素对应上面提到的 。类似地,我们为每一层定义一个偏差向量 以及一个激活层向量 。
然后,我们将公式 (23) 表示成矩阵的形式:
注意,这里我们对 函数做了点延伸,当输入参数是向量时, 会逐个作用到向量的每个元素上(elementwise)。
在 (25) 式中,有时为了书写的方便,我们会用 来表示 。下文中, 将会频繁出现。
代价函数的两个前提假设
BP 算法的目标是要计算偏导数 / 和 /,要让 BP 算法起作用,我们需要两个前提假设:
- 代价函数可以表示成 ,其中 是每个训练样本 x 的代价函数。
- 代价函数用神经网络的输出作为函数的输入:
BP 算法背后的四个基本公式
BP 算法本质上是为了计算出 / 和 / 。为了计算这两个导数,我们引入一个中间变量 ,这个中间变量表示第 l 层第 j 个神经元的误差。BP 算法会计算出这个误差,然后用它来计算 / 和 / 。
被定义为:
这个定义来源于这样一个事实:代价函数 可以看作是关于 的函数,而 是 和 的线性组合(考虑到代价函数的两个前提假设, 是关于网络输出 的函数,而 又是 的函数,所以 也可以看作是 的函数)。其实,我们也可以将它定义为:( 是神经网络某一层的输出),但这样会导致之后的计算十分复杂,所以,我们还是保留原先的定义。
BP 算法基于 4 个基本公式,这些公式会告诉我们如何计算 和代价函数的梯度。
输出层误差 的计算公式
这个公式是最直接的,只需要知道 ,然后根据链式法则即可得到。
为了更好地运用矩阵运算,我们改变一下上面式子的形式:
其中, 表示 elementwise 运算,而 可以看作是 组成的向量。
举个例子,假设 ,则 ,那么公式(BP1)可以表示成:。
与的计算公式
前面公式 (BP1) 可以让我们计算出最后输出层 的值,而 (BP2) 这个公式可以依据最后一层的误差,逐步向前传递计算前面输出层的 值。
bias 的导数计算公式
这个公式表明,第 l 层偏差 bias 的导数和第 l 层的误差值相等。
权重 W 的导数计算公式
同理,这个公式揭露出权重 W 的导数和误差以及网络输出之间的关系。用一种更简洁的方式表示为:
其中, 是权重 的输入,而 是权重 对应的 的误差。用一幅图表示如下:
公式 (32) 一个很好的效果是:当 时,梯度公式的值会很小,换句话说,当权重 的输入 ,也就是上一层激活层的输出接近 0 时,那么这个激活层对网络的影响就变得很小, 的学习也会变得很慢。
一些启发(insights)
根据上面四个公式,可以发现,当最后输出层的导数 变的很小时(即网络本身已经接近收敛),权重 和偏差 会逐渐停止学习(因为误差 逐渐趋于 0)。
当然,不单单是最后一层会影响学习速度,根据公式 (BP2),当中间层的导数 也开始趋于 0 时,那么上一层的误差 也会趋于 0,从而导致上一层权重 和偏差 的学习也会开始停止。
总之,当 的输入 变的很小或者输出层 收敛时,网络权值的训练将会变得很慢。
需要注意的一点是,这四个公式的推导适用于任何激活函数。因此,我们完全可以用其他函数来取代 。比如,我们可以设计一个函数 ,这个函数的导数 永远为正,且 函数值永远不会接近 0,那么就可以避免上面提到的学习停止的问题。
最后,总结一下 BP 的 4 个基本公式:
个人对于误差以及 BP 的理解
根据误差 的定义,不难发现,它其实就是代价函数关于参数 和 的间接导数,这一点跟第一章中对梯度的定义是一致的。当 越大时,证明网络还远没有收敛,即网络的「误差」还很大,因此需要学习更多,反之,则证明网络的「误差」比较小,学习可以停止了。
网络中每一层的误差都需要借助前一层的误差进行计算,这个过程其实是一个导数的叠加过程,可以感性地认为,整个神经网络其实是由一个个函数复合在一起形成的,因此,导数的计算其实就是链式法则的不断应用,前面层神经元的导数需要后面层神经元导数不断叠加,这个过程就构成了后向传播算法。
公式证明
BP1
公式 (BP1) 的证明是十分简单的,不过需要习惯向量或矩阵的 elementwise 的求导形式。
我们假设 ,根据定义 ,由于 只跟 相关,于是我们用链式法则可以得到(可以画个网络图帮助理解):
其中,,我们也可以将它表示成另一种形式:
上式就是 BP1 的形式了。
BP2
BP2 需要用到后一层计算出来的 ,因此,我们先根据 BP1 得出:。
由 和 可以得到:
我们还要进一步找出 和 之间的关系。根据前向传播,可以得到:
进而可以得到:
将式 (44) 代入 (42) 得:
表示成矩阵的形式就是:
即 BP2 的公式,注意矩阵的转置运算。
BP3
BP4
证明过程同 BP3:
后向传播算法(BP)
- Input x: Set the corresponding activation for the input layer.
- **Feedforward: ** For each l = 2, 3, …, L compute and .
- **Output error **: Compute the vector .
- **Backpropagate the error: **For each l = L-1, L-2, …, 2 compute .
- **Output: **The gradient of the cost function is given by and .
以上算法是针对一个训练样本进行的,实际操作中,通常是用随机梯度下降算法,用几个样本进行训练,因此我们将算法略微修改如下:
- Input a set of training examples
- **For each training example **x: Set the corresponding input activation , and perform the following steps:
- **Feedforward: **For each l = 2, 3, …, L compute and .
- **Output error **: Compute the vector .
- **Backpropagate the error: **For each l = L-1, L-2, …, 2 compute .
- **Gradient descent: **For each l = L, L-1, …, 2 update the weights according to the rule , and the biases according to the rule .
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异