读书笔记:神经网络是如何训练的

(本文是根据 neuralnetworksanddeeplearning 这本书的第二章How the backpropagation algorithm works整理而成的读书笔记,根据个人口味做了删减)

在上一章的学习中,我们介绍了神经网络可以用梯度下降法来训练,但梯度的计算方法却没有给出。在本章中,我们将学习一种计算神经网络梯度的方法——后向传播算法(backpropagation)。

backpropagation 算法起源于上个世纪 70 年代,但一直到 Hinton 等人在 1986 年发表的这篇著名论文后才开始受到关注。BP 算法使得神经网络的训练速度快速提升,因此它是学习神经网络的重中之重。

热身:一种基于矩阵的快速计算神经网络输出的方法

在开始讨论 BP 算法之前,我们先回顾一种基于矩阵形式的计算神经网络输出的方法。

首先,引入几个符号表示。

假设 wjkl 表示从第 l-1 层的第 k 个神经元到第 l 层的第 j 个神经元的权值,如下图所示。

假设 bjl 表示 l 层第 j 个神经元的偏差,ajl 表示 l 层第 j 个神经元的激活层,如下图所示:

有了这些标记,第 l 层的第 j 个神经元的激活层 ajl 就可以和 l-1 层的激活层关联起来:

(23)ajl=σ(kwjklakl1+bjl)

其中,σ() 是一个激活函数,例如 sigmoid 函数之类的。

现在,为了方便书写,我们为每一层定义一个权值矩阵 Wl,矩阵的每个元素对应上面提到的 wjkl。类似地,我们为每一层定义一个偏差向量 bl 以及一个激活层向量 al

然后,我们将公式 (23) 表示成矩阵的形式:

(25)al=σ(Wlal1+bl)

注意,这里我们对 σ() 函数做了点延伸,当输入参数是向量时,σ() 会逐个作用到向量的每个元素上(elementwise)。

在 (25) 式中,有时为了书写的方便,我们会用 zl 来表示 Wlal1+bl。下文中,zl 将会频繁出现。

代价函数的两个前提假设

BP 算法的目标是要计算偏导数 C/wC/b,要让 BP 算法起作用,我们需要两个前提假设:

  1. 代价函数可以表示成 C=1nxCx,其中 Cx 是每个训练样本 x 的代价函数。
  2. 代价函数用神经网络的输出作为函数的输入:

BP 算法背后的四个基本公式

BP 算法本质上是为了计算出 C / wjklC / bjl。为了计算这两个导数,我们引入一个中间变量 δjl,这个中间变量表示第 l 层第 j 个神经元的误差。BP 算法会计算出这个误差,然后用它来计算C / wjklC / bjl

δjl 被定义为:

(29)δjl=Czjl

这个定义来源于这样一个事实:代价函数 C 可以看作是关于 z 的函数,而 zWb 的线性组合(考虑到代价函数的两个前提假设,C 是关于网络输出 a 的函数,而 a 又是 z 的函数,所以 C 也可以看作是 z 的函数)。其实,我们也可以将它定义为:δjl=Cajla 是神经网络某一层的输出),但这样会导致之后的计算十分复杂,所以,我们还是保留原先的定义。

BP 算法基于 4 个基本公式,这些公式会告诉我们如何计算 δl 和代价函数的梯度。

输出层误差 δL的计算公式

(BP1)δjL=CzjL=CajLσ(zjL)

这个公式是最直接的,只需要知道 aL=σ(zL),然后根据链式法则即可得到。

为了更好地运用矩阵运算,我们改变一下上面式子的形式:

(BP1a)δL=aCσ(zL).

其中, 表示 elementwise 运算,而 aC 可以看作是 C/ajL 组成的向量。

举个例子,假设 C=12j(yjajL)2,则 C/ajL=[C/a0lC/a1lC/anl]=(ajLyj)=[a0ly0a1ly1anlyl],那么公式(BP1)可以表示成:δL=(aLy)σ(zL)

δLδL+1的计算公式

(BP2)δL=((wl+1)Tδl+1)σ(zl)

前面公式 (BP1) 可以让我们计算出最后输出层 δL 的值,而 (BP2) 这个公式可以依据最后一层的误差,逐步向前传递计算前面输出层的 δL 值。

bias 的导数计算公式

(BP3)Cbjl=δjl

这个公式表明,第 l 层偏差 bias 的导数和第 l 层的误差值相等。

权重 W 的导数计算公式

(BP4)Cwjkl=akl1δjl

同理,这个公式揭露出权重 W 的导数和误差以及网络输出之间的关系。用一种更简洁的方式表示为:

(32)Cw=ainδout

其中,ain 是权重 W 的输入,而 δout 是权重 W 对应的 z 的误差。用一幅图表示如下:

公式 (32) 一个很好的效果是:当 ain0 时,梯度公式的值会很小,换句话说,当权重 W 的输入 ain,也就是上一层激活层的输出接近 0 时,那么这个激活层对网络的影响就变得很小,W 的学习也会变得很慢。

一些启发(insights)

根据上面四个公式,可以发现,当最后输出层的导数 σ(zL) 变的很小时(即网络本身已经接近收敛),权重 W 和偏差 b 会逐渐停止学习(因为误差 δ 逐渐趋于 0)。

当然,不单单是最后一层会影响学习速度,根据公式 (BP2),当中间层的导数 σ(zl) 也开始趋于 0 时,那么上一层的误差 δl 也会趋于 0,从而导致上一层权重 W 和偏差 b 的学习也会开始停止。

总之,当 W 的输入 a 变的很小或者输出层 σ(zl) 收敛时,网络权值的训练将会变得很慢。

需要注意的一点是,这四个公式的推导适用于任何激活函数。因此,我们完全可以用其他函数来取代 sigmoid()。比如,我们可以设计一个函数 σ(),这个函数的导数 σ() 永远为正,且 σ() 函数值永远不会接近 0,那么就可以避免上面提到的学习停止的问题。

最后,总结一下 BP 的 4 个基本公式:

个人对于误差以及 BP 的理解

根据误差 δ 的定义,不难发现,它其实就是代价函数关于参数 Wb 的间接导数,这一点跟第一章中对梯度的定义是一致的。当 δ 越大时,证明网络还远没有收敛,即网络的「误差」还很大,因此需要学习更多,反之,则证明网络的「误差」比较小,学习可以停止了。

网络中每一层的误差都需要借助前一层的误差进行计算,这个过程其实是一个导数的叠加过程,可以感性地认为,整个神经网络其实是由一个个函数复合在一起形成的,因此,导数的计算其实就是链式法则的不断应用,前面层神经元的导数需要后面层神经元导数不断叠加,这个过程就构成了后向传播算法。

公式证明

BP1

公式 (BP1) 的证明是十分简单的,不过需要习惯向量或矩阵的 elementwise 的求导形式。

我们假设 C=f(σ(zL))=f(σ(z0L),σ(z1L),,σ(znL)),根据定义 δjL=CzjL,由于 zjL 只跟 ajL 相关,于是我们用链式法则可以得到(可以画个网络图帮助理解):

(38)δjL=fσ(zjL)σ(zjL)zjL=CajLajLzjL

其中,ajL=σ(zjL),我们也可以将它表示成另一种形式:

(39)δjL=CajLσ(zjL)

上式就是 BP1 的形式了。

BP2

BP2 需要用到后一层计算出来的 δl+1,因此,我们先根据 BP1 得出:δkl+1=Czkl+1

δkl=CzklC=f(σ(z0L),σ(z1L),,σ(znL)) 可以得到:

δjl=Cz0l+1z0l+1zjl++Cznl+1znl+1zjl=kCzkl+1zkl+1zjj(42)=kδkl+1zkl+1zjl

我们还要进一步找出 zkl+1zkl 之间的关系。根据前向传播,可以得到:

(43)zkl+1=jwkjl+1ajl+bkl+1=jwkjl+1σ(zjl)+bkl+1

进而可以得到:

(44)zkl+1zjl=wkjl+1σ(zjl)

将式 (44) 代入 (42) 得:

(45)δjl=kwkjl+1σ(zjl)δkl+1=σ(zjl)kwkjl+1δkl+1

表示成矩阵的形式就是:

δL=((wl+1)Tδl+1)σ(zl)

即 BP2 的公式,注意矩阵的转置运算。

BP3

zjl=kWjklakl1+bjl

zjlbjl=1

Cbjl=Czjlzjlbjl=Czjl=δjl

BP4

证明过程同 BP3:

zjl=kWjklakl1+bjl

zjlWjkl=akl1

CWjkl=CzjlzjlWjkl=Czjlakl1=δjlakl1

后向传播算法(BP)

  1. Input x: Set the corresponding activation a1 for the input layer.
  2. **Feedforward: ** For each l = 2, 3, …, L compute zl=wlal1+bl and al=σ(zl).
  3. **Output error **δL: Compute the vector δL=aCσ(zL).
  4. **Backpropagate the error: **For each l = L-1, L-2, …, 2 compute δl=((Wl+1)Tδl+1)σ(zl).
  5. **Output: **The gradient of the cost function is given by Cwjkl=akl1δjl and Cbjl=δjl.

以上算法是针对一个训练样本进行的,实际操作中,通常是用随机梯度下降算法,用几个样本进行训练,因此我们将算法略微修改如下:

  1. Input a set of training examples
  2. **For each training example **x: Set the corresponding input activation ax,1, and perform the following steps:
    • **Feedforward: **For each l = 2, 3, …, L compute zx,l=wlax,l1+bl and ax,l=σ(zx,l).
    • **Output error **δx,L: Compute the vector δx,L=aCxσ(zx,L).
    • **Backpropagate the error: **For each l = L-1, L-2, …, 2 compute δx,l=((Wl+1)Tδx,l+1)σ(zx,l).
  3. **Gradient descent: **For each l = L, L-1, …, 2 update the weights according to the rule WlWlηmxδx,l(ax,l1)T, and the biases according to the rule blblηmxδx,l.

参考

posted @   大白话AI  阅读(656)  评论(0编辑  收藏  举报
编辑推荐:
· 从 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的设计差异
点击右上角即可分享
微信分享提示