反向传播算法 BackPropagation ,简称BP算法。常用于训练多层神经网络,那么它到底传播了个啥?又是怎么传播的呢?

我们知道,对于一个机器学习算法,其最终预测出的值与实际值一般会存在差异,那么我们定义这个差异为误差E。算法中有若干参数需要学习,那么怎么学习呢?以什么策略去变化参数,使得预测值更接近真实值呢?

这就是采用BP算法的初衷,我们知道预测值是由所有参数与相连的输入运算后得到的,也就是说预测值与真实值之间的误差E其实是与每个参数相关的,可以认为误差是由每个参数造成的,因此我们试图将误差进行反向传播,计算每个参数引起的误差大小,以此为依据来更新参数,使得重新进行前向传播计算出的预测值越来越接近真实值,由此起到训练的作用。

从西瓜书中摘取示例网络的图片来计算BP的过程:

BP算法Python代码示例 bp算法介绍_反向传播

注:该图示中输入层在最下面,输出层在最上面。我们可能更习惯输入层在左侧,输出层在右侧。如下图所示。


BP算法Python代码示例 bp算法介绍_权重_02

给定以上含一层隐层的神经网络,有 𝑑 个输入神经元、𝑞 个隐层神经元、𝑙个输出神经元。
给定:
训练集 BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_03,即输入由 𝑑 个属性描述(𝑑 个𝑥),输出 𝑙 维实值向量(𝑙个𝑦)。
其中:
输出层第 𝑗 个神经元的阈值(偏置)用BP算法Python代码示例 bp算法介绍_权重_04表示,
隐层第 ℎ 个神经元的阈值用BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_05 表示。
输入层第 𝑖 个神经元与隐层第 ℎ 个神经元之间的连接权重为BP算法Python代码示例 bp算法介绍_深度学习_06
隐层第 ℎ 个神经元与输出层第 𝑗 个神经元之间的连接权重为BP算法Python代码示例 bp算法介绍_权重_07
记隐层第 ℎ 个神经元接收到的输入为BP算法Python代码示例 bp算法介绍_反向传播_08
输出层第 𝑗 个神经元接收到的输入为BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_09
其中BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_10为隐层第 ℎ 个神经元的输出,即BP算法Python代码示例 bp算法介绍_神经网络_11
假设隐层和输出层的激活函数为Sigmoid函数(注:Sigmoid函数求导特性良好,见公式6)。

对训练集BP算法Python代码示例 bp算法介绍_神经网络_12,假定神经网络的输出为BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_13
即:
BP算法Python代码示例 bp算法介绍_神经网络_14
则网络在BP算法Python代码示例 bp算法介绍_神经网络_12上的均方误差为BP算法Python代码示例 bp算法介绍_反向传播_16
(注:加BP算法Python代码示例 bp算法介绍_神经网络_17是为了约掉平方求导得到的2。)

网络中需要更新的参数个数为BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_18个:输入层到隐层的BP算法Python代码示例 bp算法介绍_深度学习_19个权值、隐层到输出层的BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_20个权值、 𝑞 个隐层神经元的阈值, 𝑙 个输出层神经元的阈值。

BP是一个迭代学习算法,在迭代的每一轮中,采用广义的感知机学习规则对参数进行更新估计。

对任意参数 𝑣 的更新公式为 BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_21

BP算法基于梯度下降策略,以目标的负梯度方向对参数进行调整,对式子(2)的 BP算法Python代码示例 bp算法介绍_反向传播_22,给定学习率 𝜂 ,有

BP算法Python代码示例 bp算法介绍_深度学习_23

注意到, BP算法Python代码示例 bp算法介绍_神经网络_24先影响到第 𝑗 个输出层神经元的输入值 BP算法Python代码示例 bp算法介绍_神经网络_25,再影响到其输出值 BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_26,然后影响到 BP算法Python代码示例 bp算法介绍_反向传播_22,有

BP算法Python代码示例 bp算法介绍_权重_28

根据 BP算法Python代码示例 bp算法介绍_神经网络_25定义,有:

BP算法Python代码示例 bp算法介绍_反向传播_30

Sigmoid函数的导数为:

BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_31

于是根据式子(1)和(2),取出式(4)中的前两项并取负后设为BP算法Python代码示例 bp算法介绍_反向传播_32(注:此处设为BP算法Python代码示例 bp算法介绍_反向传播_32是为了后面继续往前一层求导时复用此结果值,见式12第三行),有

BP算法Python代码示例 bp算法介绍_权重_34
将式(5)、(7)代入式子(4),再代入式(3)得到BP算法中关于BP算法Python代码示例 bp算法介绍_神经网络_24的更新公式:

BP算法Python代码示例 bp算法介绍_反向传播_36

根据BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_37可以看出偏置BP算法Python代码示例 bp算法介绍_权重_04更新公式的计算方法与BP算法Python代码示例 bp算法介绍_神经网络_24类似,只需要特别注意相比BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_40的式子(8)少了BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_10而多了一个负号(BP算法Python代码示例 bp算法介绍_深度学习_42中的BP算法Python代码示例 bp算法介绍_反向传播_43),即:
BP算法Python代码示例 bp算法介绍_深度学习_44
又有:
BP算法Python代码示例 bp算法介绍_权重_45
其中:
BP算法Python代码示例 bp算法介绍_反向传播_46

注:BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_47是因为输出层的各个元素都与BP算法Python代码示例 bp算法介绍_神经网络_48相连,需要综合影响。这也是式子(7)中设BP算法Python代码示例 bp算法介绍_深度学习_49的原因,保存中间值,加速上一层的计算,避免重复计算。另外,BP算法Python代码示例 bp算法介绍_权重_50

将式子(11)中的部分值抽出来设为:
BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_51
则得到BP算法Python代码示例 bp算法介绍_神经网络_52
BP算法Python代码示例 bp算法介绍_权重_53
同理得到,
BP算法Python代码示例 bp算法介绍_BP算法Python代码示例_54

注:需要特别注意的就是运算过程中的符号,是否需要BP算法Python代码示例 bp算法介绍_神经网络_55,中间结果的保存。

对于每一个训练样本,BP算法执行的步骤为:先将输入样本提供给输入层神经元,然后逐层将信号前传,指导产生输出层的结果;然后计算出输出层的误差,再将误差逆向传播到隐层神经元,最后根据隐层神经元的误差来对连接权重和阈值(偏量)进行调整。该过程为循环进行,直到满足某一过程为止。

如果直接能推理懂西瓜书中的内容,那就最好了。不过由于这个官方配图其实不太符合习惯而且没有标明偏置,所以我自己重新画了一遍并将原推理过程中省略的部分加上了,避免过程跳跃太快带来疑惑。

BP算法Python代码示例 bp算法介绍_深度学习_56

参考:

[1] 周志华, 机器学习, 北京: 清华大学出版社, 2016年1月.