神经网络与深度学习(三)——反向传播算法

1. 基于矩阵计算网络输出

首先给出网络中权重的清晰定义。使用这里写图片描述表示从这里写图片描述层的这里写图片描述个神经元到层的这里写图片描述个神经元的链接上的权重。如下图所示,给出了第2个隐藏层的第4个神经元到第3个隐藏层的第2个神经元的链接上的权重。


这里写图片描述

对网络偏差和激活值也使用类似的表示。显式地,使用 这里写图片描述表示在 个神经元的偏差,使用 这里写图片描述表示 这里写图片描述个神经元的激活值。如下图所示。

这里写图片描述

这样一来, 这里写图片描述层的 这里写图片描述个神经元的激活值 就与 这里写图片描述层的激活值关联起来了,如下式所示。

这里写图片描述

我们引入向量化函数来按照矩阵形式重写上述公式,由于我们对权值矩阵 这里写图片描述索引下标做出了定义,于是上式就转化为下面这种整洁的形式,避免了对权值矩阵做转置运算。

这里写图片描述

利用上述方程计算 这里写图片描述时,我们称中间量 这里写图片描述层的带权输入。则 这里写图片描述的每个元素是 ,即 个神经元的激活函数的带权输入。

2. 关于代价函数的两个假设

反向传播的目标是计算代价函数 分别关于 和 的偏导数这里写图片描述这里写图片描述。为了让反向传播可行,我们需要做出关于代价函数的两个主要假设。这里以二次代价函数为例。

这里写图片描述

其中n是训练样本的总数;求和是在所有的训练样本x上进行的;y=y(x)是对应的目标输出;L表示网络的层数; 这里写图片描述是当输入是x时的网络输出的激活值向量。
第一个假设就是代价函数可以被写成一个在每个训练样本x上的代价函数 这里写图片描述的均值 这里写图片描述 。这是关于二次代价函数的例子, 其中对每个独立的训练样本其代价是 这里写图片描述。需要这个假设的原因是反向传播实际上是对一个独立的训练样本计算了 这里写图片描述这里写图片描述。然后我们通过在所有训练样本上进行平均化获得 这里写图片描述这里写图片描述。实际上,有了这个假设,我们会认为训练样本x已经被固定住了,丢掉了其下标,将代价函数 这里写图片描述看做 这里写图片描述
第二个假设就是代价可以写成神经网络输出的函数:
这里写图片描述

例如,二次代价函数满足这个要求,因为对于一个单独的训练样本 其二次代价函数可以写作:
这里写图片描述

这是输出的激活值的函数。当然,这个代价函数同样还依赖于目标输出。输入的训练样本x是固定的,所以输出同样是一个固定的参数。所以说,并不是可以随意改变权重和偏差的,也就是说,这不是神经网络学习的对象。所以,将 这里写图片描述看成仅有输出激活值 这里写图片描述的函数才是合理的,而y仅仅是帮助定义函数的参数而已。

3. 反向传播的四个基本方程

1)Hadamard 乘积
反向传播基于一种叫做Hadamard 乘积的矩阵运算实现。特别地,假设s和t是两个同样维度的向量。那么我们使用这里写图片描述来表示按元素的乘积。所以这里写图片描述的元素就是这里写图片描述。给个例子,

这里写图片描述

2)四个基本方程
反向传播其实是对权重和偏差变化影响代价函数过程的理解。 最终极的含义其实就是计算偏导数 这里写图片描述这里写图片描述。但是为了计算这些值,我们首先引入一个中间量 这里写图片描述,这个我们称为在 这里写图片描述层第 这里写图片描述个神经元上的误差(error)。反向传播将给出计算误差 这里写图片描述的流程,然后将其关联到计算 这里写图片描述这里写图片描述上。
为了理解误差是如何定义的,假设在神经网络上有一个小精灵:
这里写图片描述

这个小精灵在 这里写图片描述层的第 这里写图片描述个神经元上。小精灵通过增加很小的变化 这里写图片描述,使得神经元输出由 变成 。这个变化向网络后面的层传播,最终导致整个代价函数产生 这里写图片描述的改变。为降低代价函数,小精灵可以通过选择与 这里写图片描述相反符号的 这里写图片描述。相反,若 这里写图片描述接近于0,则小精灵不能通过扰动带权输入z来改变太多代价函数。在小精灵看来,这时神经元已经接近最优了。
按照上面描述,我们定义 层的 这里写图片描述个神经元的误差 这里写图片描述为: 这里写图片描述
这里不加证明地给出反向传播的四个基本方程:
这里写图片描述

通过观察四个基本方程,可以得出以下结论:
(1)观察方程BP1,这里 这里写图片描述被定义成一个向量,其元素是偏导数 这里写图片描述。你可以将其看成 这里写图片描述关于输出激活值的改变速度。举个例子,在二次代价函数时,我们有 这里写图片描述,所以BP1就变成

这里写图片描述

回忆sigmoid函数,当函数值接近1或0时, 这里写图片描述接近于0。所以如果输出神经元处于或者低激活值或者高激活值时,最终层的权重学习缓慢。这样的情形,我们常常称输出神经元已经饱和了,并且,权重学习也会终止(或者学习非常缓慢)。类似的结果对于输出神经元的偏差也是成立的。
(2)观察方程BP2,其中 这里写图片描述是权重矩阵 这里写图片描述的转置。这其实可以很直觉地看做是后在 这里写图片描述层的输出的误差的反向传播,给出了某种关于误差的度量方式。然后,我们进行Hadamard乘积运算 这里写图片描述。这会让误差通过 这里写图片描述层的激活函数反向传递回来并给出在 这里写图片描述的带权输入的误差 这里写图片描述
通过组合BP1和BP2,我们可以计算任何层的误差了。首先使用BP1计算 这里写图片描述,然后应用方程BP2来计算 这里写图片描述, 然后不断作用BP2,一步一步地反向传播完整个网络。特别地,当输出神经元已经接近饱和, 很有可能变小,导致权重学习缓慢。
(3)观察方程BP4,来自很低的激活值神经元的权重学习同样会非常缓慢。

4. 反向传播算法

4.1 算法流程

反向传播方程给出了一种计算代价函数梯度的方法。 让我们显式地用算法描述出来:
1. 输入x:为输入层设置对应的激活值这里写图片描述
2. 前向传播:对每个l = 2, 3, …, L计算相应的这里写图片描述这里写图片描述
3. 输出层误差:计算向量这里写图片描述
4. 反向误差传播:对每个l = L-1, L-2, …, 2,计算这里写图片描述
5. 输出:代价函数的梯度由这里写图片描述这里写图片描述

4.2 反向传播快速的原因

如果仅仅把代价看作权重的函数即C=C(w),则计算某个权值这里写图片描述关于C的导数:

这里写图片描述

其中 这里写图片描述是一个很小的正数,而 这里写图片描述是在第j个方向上的单位向量。换句话说,我们可以通过计算 这里写图片描述的两个接近相同的点的值来估计 这里写图片描述,然后应用上述公式。同样方法也可以用来计算 这里写图片描述
然后,遗憾的是,当你实现了之后,运行起来这样的方法非常缓慢。为了理解原因,假设我们有1,000,000个权重。对每个不同的权重 这里写图片描述,我们需要计算 这里写图片描述来计算 这里写图片描述。这意味着为了计算梯度,我们需要计算代价函数 1,000,000次,需要1,000,000次前向传播(对每个样本) 。我们同样需要计算C(w), 总共是1,000,001次。反向传播聪明的地方就是它确保我们可以同时计算所有的偏导数 这里写图片描述使用一次前向传播,加上一次后向传播。粗略地说, 后向传播的计算代价和前向的一样。

4.3 反向传播大视野

回顾反向传播算法,可以发现关于代价函数梯度的计算均是基于链式法则进行的。假设某个权重做一点小小的变动这里写图片描述

这里写图片描述

那么这个改变逐渐向后面网络层产生影响,最终到达输出层,影响代价函数:
这里写图片描述

所以代价函数 这里写图片描述改变与 按如下公式关联起来:
这里写图片描述

同时 这里写图片描述导致了 个神经元的激活值的变化 ,即
这里写图片描述

继而影响到下一层的激活值的变化,即
这里写图片描述

则综合前一层变化 ,有
这里写图片描述

最终,对于代价函数变化 ,有
这里写图片描述

对路径中所有可能的中间神经元选择进行求和。则有
这里写图片描述

而这个公式告诉我们的是:两个神经元之间的连接其实是关联于一个变化率因子,这仅仅是一个神经元的激活值相对于其他神经元的激活值的偏导数。从第一个权重到第一个神经元的变化率因子是 这里写图片描述。路径的变化率因子其实就是这条路径上的众多因子的乘积。而整个的变化率 这里写图片描述就是对于所有可能的从初始权重到最终输出的代价函数的路径的变化率因子的和。针对某一个路径,这个过程解释如下:
这里写图片描述
观察发现,可以将反向传播想象成一种计算所有可能的路径变化率的求和的方式。或者,换句话说,反向传播就是一种巧妙地追踪权重(和偏差)微小变化的传播,抵达输出层影响代价函数的技术。