深度学习原理与应用
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.6 误差反向传播算法

3.5.5节介绍了通过计算神经网络参数的梯度(严格地说是损失函数关于连接权重的梯度)来寻找最优解,这看起来已经非常完美地解决了参数的最优化问题。但是,人工神经网络,特别是深度神经网络的参数非常多,这种计算方法非常耗时。相比而言,误差反向传播算法就要高效得多。

误差反向传播算法早在20世纪60年代就已经提出,其思想就是根据实际输出值与期望值之间的误差大小来修正算法,这与人类习惯的学习校正方法是相通的。

如图3-21所示,多层神经网络的演算将结果从左到右逐层向前传递,这是“正向”学习过程。与此相反,比较实际输出与期望输出之间的误差的计算过程是反向的。“反向”就是从右到左,把误差从输出层开始,反方向逐层传播到前面各层,与此同时,通过逐层调整连接权重来减小误差。

图3-21 神经网络的误差反向传播

为了更好地理解误差反向传播算法,下面来推导连接权重调整公式。先以单层感知器为例,如图3-22所示。

图3-22 单层单输出感知器

设激活函数为λ=1的Sigmoid函数y=f(u),根据链式求导法则:

单层单输出感知器的权重调整值公式为:

注:单层感知器的损失函数为,单层单输出感知器的实际输出为

下面再来看有两个输出的单层感知器的情况,如图3-23所示。

图3-23 两个输出的单层感知器

两个输出的单层感知器的损失函数:

对损失函数求导

wij表示xiyj之间的连接权重。

上式右侧,结果只与yj相关,因此

与单个输出的感知器运算过程一样

两个输出的单层感知器的权重调整值公式为:

Δwij=η(rjyj)yj(1−yj)xi

由此可见,连接权重wij的调整值∆wij只与其相关的输入xi和输出yj有关。

最后看多层感知器的情况。

首先是只有一个输出单元,w1ij表示输入层与中间层之间的连接权重,w2j1表示中间层与输出层之间的连接权重。i表示输入层单元,j表示中间层单元,如图3-24所示。

图3-24 只有一个输出单元的多层感知器

先调整中间层与输出层之间的连接权重。

对损失函数Ew2j1的导数

与单层感知器一样,对损失函数E求导

zj是中间层的输出值,也是输出层的输入值。中间层与输出层连接权重调整值计算公式为

w2j1=η(ry)y(1−y)zj

同样的方式可以得到输入层与中间层之间的连接权重调整公式为:

w1ij=η(ry)y(1−y)w2j1zj(1−zj)xi

图3-25总结了只有一个输出的多层传感器的权重调整。

图3-25 只有一个输出单元的多层感知器的权重调整

对于有多个输出单元的多层感知器,公式的推导类似,连接权重调整公式为:

有多个输出单元的多层感知器如图3-26所示。

图3-26 有多个输出单元的多层感知器

同样用一幅图片总结一下有多个输出的多层传感器的权重调整,如图3-27所示。与单输出单元权重调整的不同之处:输入层与中间层之间的权重调整值是相关单元在中间层与输出层之间的权重调整值的总和。

图3-27 有多个输出单元的多层感知器的权重调整

前面推导中使用的激活函数是λ=1的sigmoid函数。这个函数虽然是可导的,但还有缺点。

从图3-28中可以看出,当u→∞时,即时,y→0;u→−∞1−y→0,这样导致,,因此无法调整连接权重。这是因为梯度值过小,出现了所谓的“梯度消失”问题。

另外一方面,当u→0时,梯度值又过大,出现了“梯度爆炸”问题,如图3-28所示。

图3-28 梯度消失和爆炸图示

造成梯度消失和梯度爆炸的原因:

(1)隐藏层的层数过多;

(2)采用了不合适的激活函数;

(3)权重初始化值过大。

为了防止梯度消失和爆炸,可以采用以下方法:

(1)精选初始化参数,如He初始化;

(2)使用ReLU、Leaky-ReLU、PReLU、Maxout等激活函数替代sigmoid函数;

(3)使用数据规范化处理,通过对每一层的输出规范为均值和方差一致的方法,消除了权重参数放大缩小带来的影响,进而解决梯度消失和爆炸的问题;

(4)LSTM的结构设计也可以改善RNN中的梯度消失问题。

前面用数学公式介绍了误差反向传递算法。这样做虽然很严谨,但不易获得感性认识。还有一种基于计算图(computational graph)的形式,非常便于直观地理解误差反向算法。计算图将计算过程用图形表示出来,图中每个节点表示一个函数,节点之间的连接直线称为边,用来表示输入/输出变量,变量可以是标量、向量、矩阵、张量甚至是另一类型的变量,如图3-29所示。

图3-29 计算图示例

计算图是正向表示运算顺序,反向可以直观地表示出误差的传递过程,如图3-30所示,误差分析传播是将误差值E乘以该节点的偏导数,然后传递给上一个节点。

图3-30 误差反向传播图示

下面用sigmoid函数作为例子来看计算图是如何完成误差反向传播的。其中,值假定是后面的节点传递过来的,如图3-31所示。

图3-31 sigmoid函数正向计算和误差反向传播图示

再看一个带有数值的、含有加法和乘法的例子,重点看误差反向传播在加法和乘法运算时的误差反向传播所乘数值大小的差别。

有人在超市里购买了2个苹果、3个橘子,苹果一个100元,橘子一个150元,另收消费税10%,一共需要支付多少钱?其正向计算和误差反向传播如图3-32所示。

图3-32 购物费正向计算和误差反向传播图示

设支付金额为L,苹果个数为x1,苹果单价为x2,苹果总价为u,橘子单价为x3,橘子个数为x4,橘子总价为v,税率为r,货物总价为:

L=(u+vr=(x1×x2+x3×x4r

注意,加法节点反向传播所乘的偏导数为1,所以输入的误差值会原封不动地传向前一个节点。乘法节点的偏导数正好是另一个乘数,所以误差传播会将原误差值乘以另一个乘数。