四. 神经网络与误差反向传播

1. 人工神经网络的架构

1.1 什么是神经网络
  • 神经网络:大量(结构简单,功能接近的)神经元节点按一定体系架构连接成的网状结构
  • 神经网络的作用:分类、模式识别、连续值预测,建立输入与输出的映射关系
1.2 人工神经元

如图所示:

openc bp神经网络 opencv 神经网络_深度学习

每个神经元都是一个结构相似的独立单元,它接受前一层传来的数据,并将这些数据的加权和输入非线性作用函数中,最后将非线性作用函数的输出结果传递给后一层。

非线性函数openc bp神经网络 opencv 神经网络_神经网络_02,称为激活函数:
openc bp神经网络 opencv 神经网络_深度学习_03

1.3 激活函数

三个常见的激活函数

  1. Sigmoid

openc bp神经网络 opencv 神经网络_神经网络_04

openc bp神经网络 opencv 神经网络_openc bp神经网络_05

  1. Tanh(x)

openc bp神经网络 opencv 神经网络_opencv_06

openc bp神经网络 opencv 神经网络_opencv_07

  1. Relu

openc bp神经网络 opencv 神经网络_openc bp神经网络_08

1.4 简单的求导基础

链式求导:

openc bp神经网络 opencv 神经网络_opencv_09

写成另一种形式:

openc bp神经网络 opencv 神经网络_深度学习_10

openc bp神经网络 opencv 神经网络_神经网络_11

1.5 人工神经网络
  • 基础神经网络
  • 神经元
  • 输入向量openc bp神经网络 opencv 神经网络_激活函数_12
  • 权重向量openc bp神经网络 opencv 神经网络_openc bp神经网络_13
  • 偏置标量openc bp神经网络 opencv 神经网络_深度学习_14
  • 激活函数
  • 浅网络
  • 3~5层
  • 梯度下降
  • BP后向传播

openc bp神经网络 opencv 神经网络_opencv_15

1.6 层的理解

层实现了输入控件到输出空间的线性或非线性变换。

我们举个例子,假设输入是碳原子和氧原子,我们输出三个变量。我们可以通过改变权重的值获得若干个不同物质。

openc bp神经网络 opencv 神经网络_openc bp神经网络_16

openc bp神经网络 opencv 神经网络_深度学习_17

右侧的节点数决定了想要获得多少种不同的新物质。

1.7 前向(前馈)神经网络

FNN (Feedforward Neural Networks)

  • 前馈神经网络是人工神经网络的一种,各神经元从输入层开始,接收前一级的输出,并输出到下一级,直至输出层。整个神经网络中无反馈,可用一个有向无环图表示。
  • 前馈神经网络采用一种单项多层结构。其中每一层包含若干个神经元,同一层的神经元之间没有互相连接,层间信息的传送只沿一个方向进行。
  • 第一层为输入层,第二层为隐藏层,最后一层为输出层。其中隐藏层可以是一层也可以是多层。

2. 目标函数与梯度下降

2.1 目标函数

前面介绍了前馈神经网络,那我们的前馈神经网络的目标是什么呢?

  • 对于一系列训练样本openc bp神经网络 opencv 神经网络_激活函数_18
  • 期望输出openc bp神经网络 opencv 神经网络_opencv_19,网络实际输出openc bp神经网络 opencv 神经网络_opencv_20

那此时我们的目标函数就是:
openc bp神经网络 opencv 神经网络_openc bp神经网络_21
那我们如何计算目标函数的最小值呢?

2.2 Delta学习规则

Delta学习规则是一种有监督学习算法,该算法根据神经元的实际输出与期望输出差别来调整连接权,其数学表达式如下:
openc bp神经网络 opencv 神经网络_openc bp神经网络_22
其中:

  • openc bp神经网络 opencv 神经网络_openc bp神经网络_23表示神经元openc bp神经网络 opencv 神经网络_神经网络_24到神经元openc bp神经网络 opencv 神经网络_激活函数_25的连接权重增量
  • openc bp神经网络 opencv 神经网络_深度学习_26是神经元openc bp神经网络 opencv 神经网络_激活函数_25的期望输出
  • openc bp神经网络 opencv 神经网络_深度学习_28是神经元openc bp神经网络 opencv 神经网络_激活函数_25的实际输出
  • openc bp神经网络 opencv 神经网络_opencv_30表示神经元openc bp神经网络 opencv 神经网络_神经网络_24的状态
  • openc bp神经网络 opencv 神经网络_opencv_32表示学习速度的常数
2.3 梯度下降

大多数机器学习算法和深度学习算法都涉及到的优化,优化是指通过改变openc bp神经网络 opencv 神经网络_激活函数_33来使某个函数openc bp神经网络 opencv 神经网络_深度学习_34最大化或者最小化,通常以最小化openc bp神经网络 opencv 神经网络_深度学习_34指代大多数问题。

我们把需要最大化或者最小化的函数称为目标函数或准则。当我们要将其最小化时,我们把它称为代价函数,损失函数或误差函数。

我们假设一个损失函数用于举例说明。
openc bp神经网络 opencv 神经网络_激活函数_36
其中:
openc bp神经网络 opencv 神经网络_opencv_37
然后使它最小化。

在高维的情况下,损失函数求导之后等于0,这个方程组太难求解,也有可能不可解,所以一般情况不使用这个方法

我们知道曲面上方向导数的最大值方向就代表了梯度的方向

方向导数:
openc bp神经网络 opencv 神经网络_深度学习_38

openc bp神经网络 opencv 神经网络_神经网络_39

那我们应该沿着梯度的反方向进行权重的更新,可以有效地找到全局的最优解,openc bp神经网络 opencv 神经网络_激活函数_40的更新过程可以描述为:
openc bp神经网络 opencv 神经网络_opencv_41

openc bp神经网络 opencv 神经网络_神经网络_42

换一个角度来想,损失函数中一般有两种参数,一种是控制输入信号量的权重openc bp神经网络 opencv 神经网络_神经网络_43,另一种是调整函数与真实值距离的偏差openc bp神经网络 opencv 神经网络_opencv_44,那我们要做的就是通过梯度下降的方法,不断地调整openc bp神经网络 opencv 神经网络_神经网络_43openc bp神经网络 opencv 神经网络_opencv_44,使得损失函数值越来越小。

通过计算梯度我们可以知道openc bp神经网络 opencv 神经网络_神经网络_43的移动方向,那我们接下来就要知道应该前进多少,这里我们用到学习率(Learning Rate)这个概念,通过学习率可以计算前进的距离。

我们用openc bp神经网络 opencv 神经网络_激活函数_48表示初始权重,openc bp神经网络 opencv 神经网络_opencv_49表示更新后的权重,openc bp神经网络 opencv 神经网络_神经网络_50表示学习率。
openc bp神经网络 opencv 神经网络_神经网络_51
梯度下降中重复此式,直至损失函数收敛不变,在这里openc bp神经网络 opencv 神经网络_神经网络_50值过大,有可能会错过损失函数最小值,openc bp神经网络 opencv 神经网络_神经网络_50过小,会导致迭代次数过多,耗费过多时间。以下是全部过程。

  1. for i=0 openc bp神经网络 opencv 神经网络_激活函数_54
  1. 计算第i个训练数据的权重openc bp神经网络 opencv 神经网络_深度学习_55和偏差openc bp神经网络 opencv 神经网络_opencv_56相对于损失函数的梯度。在这里得到每一个训练数据的权重和偏差的梯度值。
  2. 计算所有训练数据权重openc bp神经网络 opencv 神经网络_深度学习_55的梯度总和
  3. 计算所有训练数据偏差openc bp神经网络 opencv 神经网络_opencv_56的梯度总和
  1. 上面的计算结束之后
  1. 使用上面2,3的值计算所有样本openc bp神经网络 opencv 神经网络_openc bp神经网络_59的梯度的平均值
  2. 使用下面的式子,更新每个样本的openc bp神经网络 opencv 神经网络_深度学习_55openc bp神经网络 opencv 神经网络_opencv_56

openc bp神经网络 opencv 神经网络_神经网络_62

  1. 重复上面的步骤直至损失函数收敛不变
2.4 梯度下降的衍生
  1. 小批量样本梯度下降(Mini Batch GD)

这个算法在每次梯度下降的过程中,只选取一部分的样本数据进行梯度计算,比如整体样本百分之一的数据。在数据量较大的项目中,可以明显地减少梯度计算的时间。

  1. 随机梯度下降(Stochastic GD)

随机梯度下降算法之随机抽取一个样本进行梯度计算,由于每次梯度下降迭代只计算一个样本的梯度,因此运算时间会比MGD还少很多,但由于训练数据量太小,因此下降路径容易受到训练数据自身噪音的影响。

3. 误差反向传播

我们先来回顾一下梯度下降。

下图是一个表示参数openc bp神经网络 opencv 神经网络_神经网络_43与目标函数openc bp神经网络 opencv 神经网络_openc bp神经网络_64的关系图,红色部分是表示openc bp神经网络 opencv 神经网络_openc bp神经网络_64有着比较高的取值,需要能够让openc bp神经网络 opencv 神经网络_openc bp神经网络_64的值尽量的低。也就是深蓝色的部分。openc bp神经网络 opencv 神经网络_激活函数_67表示openc bp神经网络 opencv 神经网络_神经网络_43向量的两个维度。

先确定一个初始点,将openc bp神经网络 opencv 神经网络_神经网络_43按照梯度下降的方向进行调整,这样就会使得openc bp神经网络 opencv 神经网络_openc bp神经网络_64向着更低的方向进行变化,如图所示,算法的结束将是在openc bp神经网络 opencv 神经网络_神经网络_43下降到无法继续下降为止(不一定是无法下降,有时候也会停止在局部最低点或是其他情况)。

根据前面的介绍,式子如下:

openc bp神经网络 opencv 神经网络_openc bp神经网络_72

openc bp神经网络 opencv 神经网络_openc bp神经网络_73

3.1 输出层权重改变量

输出层的权重改变量其实就是一个偏导数的表达:
openc bp神经网络 opencv 神经网络_神经网络_74
那么这里的openc bp神经网络 opencv 神经网络_openc bp神经网络_75如何理解呢?

openc bp神经网络 opencv 神经网络_深度学习_76是隐藏层到输出层的权重,那么目标函数对openc bp神经网络 opencv 神经网络_深度学习_76的偏导也就是隐藏层权重的改变量,这里先不考虑学习率也就是步长,就先直接将这个偏导数当作改变量。

这里:
openc bp神经网络 opencv 神经网络_神经网络_78
openc bp神经网络 opencv 神经网络_深度学习_76在这里表示的并不是很明显,那我们就考虑通过一个中间函数使用链式求导法则将其关联起来。隐藏层与输出层的图示如下:

openc bp神经网络 opencv 神经网络_opencv_80

其中输出层的总输入为openc bp神经网络 opencv 神经网络_深度学习_81
openc bp神经网络 opencv 神经网络_opencv_82
那么:
openc bp神经网络 opencv 神经网络_opencv_83
我们知道了其中的一部分,那我们继续来看另外一部分,目标函数对openc bp神经网络 opencv 神经网络_深度学习_81求偏导,关系还不是很直观,我们再使用输出将其链接起来。输出层的输入为openc bp神经网络 opencv 神经网络_深度学习_81,输出为openc bp神经网络 opencv 神经网络_openc bp神经网络_86,他们两个的关系就是一个激活函数,所以通过输出层的输出可以很好的将目标函数与输出层的输入链接起来。
openc bp神经网络 opencv 神经网络_神经网络_87
令:openc bp神经网络 opencv 神经网络_opencv_88
openc bp神经网络 opencv 神经网络_神经网络_89
在这里openc bp神经网络 opencv 神经网络_openc bp神经网络_90就是输出层产生的残差。

3.2 隐藏层权重改变量

openc bp神经网络 opencv 神经网络_神经网络_91

隐藏层的权重改变量自然就是目标函数对于隐藏层的输入的偏导了。
openc bp神经网络 opencv 神经网络_神经网络_92
其中openc bp神经网络 opencv 神经网络_深度学习_93为隐藏层单元输出,openc bp神经网络 opencv 神经网络_激活函数_94为隐藏层单元总输入。
openc bp神经网络 opencv 神经网络_openc bp神经网络_95
那隐藏层单元输出与隐藏层单元总输入之间的关系其实就是加上了一层激活函数,如下:
openc bp神经网络 opencv 神经网络_深度学习_96
最后一项隐藏层单元总输入与权重的关系可以在表达式中很明显地表达出来,如下:
openc bp神经网络 opencv 神经网络_深度学习_97
因为第一项目标函数与隐藏层单元输出的关系比较复杂所以放到最后来计算。
openc bp神经网络 opencv 神经网络_深度学习_98

openc bp神经网络 opencv 神经网络_openc bp神经网络_99

那么:
openc bp神经网络 opencv 神经网络_激活函数_100
这里我们令:
openc bp神经网络 opencv 神经网络_激活函数_101
那么:
openc bp神经网络 opencv 神经网络_深度学习_102
输出层与隐藏层的误差反向传播总结一下,如下图所示:

输出层:

openc bp神经网络 opencv 神经网络_opencv_103

隐藏层:

openc bp神经网络 opencv 神经网络_激活函数_104

3.3 误差传播迭代公式

输出层与隐藏层的误差传播公式可以统一为:

  1. 权重增量 = -1 openc bp神经网络 opencv 神经网络_神经网络_105学习步长openc bp神经网络 opencv 神经网络_神经网络_105目标函数对权重的偏导
  2. 目标函数对权重的偏导数 = -1 openc bp神经网络 opencv 神经网络_神经网络_105残差openc bp神经网络 opencv 神经网络_神经网络_105当前层的输入
  3. 残差=当前层激活函数的导数openc bp神经网络 opencv 神经网络_神经网络_105上层反传来的误差
  4. 上层反传来的误差= 上层残差的加权和

隐藏层的误差反向传播总结一下,如下图所示:

输出层:

[外链图片转存中…(img-oPPeWMR2-1665628829586)]

隐藏层:

[外链图片转存中…(img-4cxYHaj0-1665628829586)]

3.3 误差传播迭代公式

输出层与隐藏层的误差传播公式可以统一为:

  1. 权重增量 = -1 openc bp神经网络 opencv 神经网络_神经网络_105学习步长openc bp神经网络 opencv 神经网络_神经网络_105目标函数对权重的偏导
  2. 目标函数对权重的偏导数 = -1 openc bp神经网络 opencv 神经网络_神经网络_105残差openc bp神经网络 opencv 神经网络_神经网络_105当前层的输入
  3. 残差=当前层激活函数的导数openc bp神经网络 opencv 神经网络_神经网络_105上层反传来的误差
  4. 上层反传来的误差= 上层残差的加权和