PRML5-神经网络(1)

本节来自《pattern recognition and machine learning》第5章。

五、神经网络

        在本书的第3、4章分别是基于回归和分类的线性模型,都是通过将固定的基函数进行线性组合来处理。这些函数虽然分析和计算清晰,可是却受到维数灾难的困扰,当需要将模型用在大规模问题上时,有必要让基函数去适应数据。在后面的第7章介绍的SVM是首先在这些训练数据点中心部分定义基函数,然后在训练的时候选择这些基函数的一个子集来处理。SVM的一个优点就是虽然涉及到的是非线性优化问题,可是目标函数却是凸的。这些基函数生成的模型通常来说会比训练数据量小得多(虽然还是有些大,而且随着数据集的增大也会增大)。在本书后面第7.2节,介绍的相关向量机同样也是从一个固定的基函数集合中选择一个子集,然后生成更稀疏的模型。不同于SVM,它会生成概率化的输出,所以在训练的时候,其实是需要在非凸优化上花费功夫的。

       一种方法就是先固定基函数的个数,然后让他们自适应,换句话说,也就是使用这些基函数的参数化形式,让它们在训练的时候来得到参数值。在模式识别中最成功的就是前馈神经网络,也叫做多层感知机,事实上,“多层感知机”是一个错误的叫法,因为这个模型是通过多层逻辑回归模型(连续的、非线性的)构成的,而不是多层的感知机(不连续的、非线性的)构成的。和SVM有着相同泛化效果的情况下,NN能够更紧凑和快速;相同的和相关向量机一样,在紧凑上付出的代价就是似然函数(用来构成网络训练的基础)不再是模型参数的凸函数。本章的重点在于基于统计模式识别上介绍被证明最实用的NN,多层感知机。

      首先考虑NN的函数形式,包括具体的基函数的参数,然后讨论使用最大似然框架来定义网络参数遇到的问题,这当中会遇到非线性优化的解的问题,这需要计算log似然函数关于网络参数的导数,不过可以通过错误后向传播(error backpropagation)来有效的解决这个问题,同时这个案发可以用在其他求导上,比如Jacobian和Hessian矩阵。然后介绍各种在训练的时候的正则化方法和它们之间的关系。还会介绍一些NN的扩展模型,其中具体介绍了对条件概率分布建模的生成式模型,叫做混合密度网络(mixture density networks)。最后介绍下如何将贝叶斯用在NN上。

5.1前馈网络函数

      这里简略介绍,因为NN的基础已经算是常识了,(并不想把本博文写成完全翻译的形式,哪里比较有趣就写哪里)如图:


图5.1.1两层的NN

针对于文献中不同的NN层数的叫法,本书的习惯是从权重出发,也就是图5.1.1其实是个2层的NN(隐藏层的话,就是1层NN;神经元的话就是3层NN)。

 

从第一个式子可以看出,这其实就是多项式拟合的样子,可是它却也和NN的本质一样。通过对每一层的输入进行线性转换,然后输送到一个非线性函数中,然后将得到的值作为下一层的输入值,以此类推构成多层NN。这里假设:


        也就是输入之后,只进行了线性转换,没有进行非线性函数映射的时候。这里不难看出,这时候其实就是和之前的多项式拟合一样,对于标准的回归问题来说,这时候的,也就是这个函数就是等于本身,未进行非线性映射;对于多分类来说,每个输出单元的激活值是通过使用逻辑sigmoid函数转换的,也就是,这时候所表示的就是非线性映射了,通常有sigmoid函数,或者tanh函数,或者12年使用的relu函数等等。

所以其实可以看出,NN是个多层多项式拟合形式,其中的就是对应着多项式拟合中的不同位置上的系数:


(具体参数不介绍了,主要体现一个形式),这里有两个函数,也就是这是个2层的NN.

        上面这个函数的就是前馈神经网络的本质(forward propagation network)。值得注意的是这时候的NN图不是PGM,因为内部的点(除了输入层,输出层)都是表示确定的变量,而不是随机的变量(因为输入固定了,一层一层往上传就都固定了)。下面会介绍如何用概率来解释NN。多层感知机与NN不同的地方在于NN在隐藏单元中使用的是连续sigmoidal 非线性变换;而多层感知机用的是阶段函数的非线性变换(非连续的),也就是说NN的函数必须是关于网络参数可微分的,这才能够用在网络训练的过程中。

       如果所有的隐藏单元的激活函数都是线性的,那么这种类型的网络在深层也还是线性的,因为线性的线性变换还是线性,没意义。如果对于一个如图5.1.1的,当激活函数都是线性的,而且隐藏单元个数少于输入层,而且也少于输出层,那么这个网络的变换就不是简单的从输入到输出的变换了,因为中间层的维度约间使得信息丢失了不少。针对于最常用的网络图5.1.1来说,一种就是增加层数,其中使用线性变换和非线性函数映射的形式;另一种叫做跳层(skip-layer)连接,每个连接都对应着自适应参数(就是权重):


图5.1.2 跳层的前馈NN,(每个隐藏单元和输出单元都有偏置项的,为了概念理解,图中未详细画出)

对于这另一种的跳层前馈NN模型,例如,在一个两层网络中直接从输入连接到输出,如上图所示的x1到y1。原则上来说,一个带有sigmoidal隐藏单元的网络总是能够模仿跳层连接(对于有边界的输入值来说),在基于它的操作范围之内,通过在第一层权重上使用足够小的权值是的隐藏单元有效的线性化(个人:权重越小,得到的激活值越处在0附近,那部分接近线性),然后在第二层也就是隐藏层到输出层的权值使用个足够大的权值作为补偿。不过在实际中显式的包含跳层连接是更好的(上图就是显式的连接)。而且当层内的连接不是全连接的时候,该网络可以变得稀疏(后面的CNN)。如上图一样,因为在网络图和某个数学函数有着对应关系,所以可以让网络变得更加复杂,不过这里遵循前馈结构,也就是没有闭合的有向环。也就是确保输出是由输入的函数决定的,这种更一般化的前馈网络中每个单元(隐藏层或者输出层)的计算函数为:


         在历史上,前馈网络的函数逼近特性被研究的很多((Funahashi, 1989; Cybenko, 1989; Hornik et al., 1989; Stinchecombe and White,1989; Cotter, 1990; Ito, 1991; Hornik, 1991; Kreinovich, 1991; Ripley, 1996 )。所以NN又被称之为通用函数逼近器。例如,一个带有线性输出的两层网络可以逼近任意在紧凑的输入领域上的连续函数,其中的精度由隐藏单元数量控制。逼近体现在这些隐藏单元激活函数上,不过不包括多项式。虽然原理是不错,不过关键的问题还是如何在基于训练数据上找到合适的参数值(权值)。后面会介绍这里的最大似然和贝叶斯方法。下图5.1.3就是一个2层NN对不同函数的建模,并且显示了隐藏单元是如何协同合作来逼近最后的函数的。下下图的图5.1.4中就是简单的分类问题中隐藏单元扮演的角色,使用的分类数据集是附录A中提到的:


图5.1.3 MLP逼近四种不同函数的能力:(a);(b);(c);(d),这里H(x)是Heaviside分段函数。在每个例子中,N=50个数据点,通过在(-1,1)上平均采样得到的。这些数据点随后用来训练一个带有3个 隐藏单元的NN,期中隐藏层的激活函数是tanh,输出层是线性函数,NN拟合的结果图中红色曲线;三个隐藏单元的输出为三个虚线曲线。(个人:通过NN拟合之后,将每个输入点输入整个NN得到对应的输出,画出这时候的曲线为NN拟合的曲线,红色的,将每个隐藏单元独立分开,拟合的为三个不同的虚线,之所以输出层使用线性,就是为了说明不同的隐藏单元拟合的函数是如何线性组合来最终拟合给定函数的。就是为了说明每个隐藏单元扮演的角色)

图5.1.4简单二分类问题,通过使用一个(2个输入,2个tanh隐藏单元和一个逻辑sigmoid输出)NN来拟合。蓝色虚线为训练后两个隐藏单元分别z=0.5的时候的拟合函数,红色为y=0.5时候NN的决策面。作为对比,绿色为通过使用这些数据计算得到的最优决策边界(个人:该实验为了证明不同隐藏单元扮演的角色的同同时,说明了隐藏单元的非线性组合的拟合,以及与上面3个隐藏单元对比,说明隐藏单元数量的影响等问题)

5.1.1权重空间对称性

        当与贝叶斯模型相比的时候,前馈网络的一个特性就是对权重向量的一些不同选择得到的从输入到输出的映射却是相同的(chen et al ,1993)。拿图5.1.1来说,一个2层的NN,其中有着M个隐藏单元,层间是全连接形式。如果对于一个隐藏单元来说,改变所有输入到该单元权重的符号,那么得到的激活值是刚好相反的,因为tanh是个奇函数,所以可以通过改变该单元输出的所有权重的符号来逆转这个相反数从而使得输入到输出的映射不发生改变。所以其实可以通过两个不同的权值向量来得到相同的映射函数,对于M个隐藏单元来说,就会有M个这样的“符号-翻转”对称性。所以也就有着个选择(排列组合的原理)。

       同样的,假设在不同的隐藏单元之间交换所有的输入和输出的权重值(其实就是交换隐藏单元的位置),得到的网络输入端-输出端映射函数还是没变,不过这就是另一个权重向量的选择了,对于M个隐藏单元来说,就有着个选择(排列组合)。所以总的来说,该网络的权重空间对称就为(也就是在一个权重空间中,这么多方式的权重选择的结果导致的映射是相同的)(这是针对一层隐藏层的,如果有多层隐藏层,那么整个NN就需要用层数乘以这个因子)。事实证明这些因素差不多就是权重空间中的所有对称性的表现(除了某些对权重空间的选择会造成意外的对称情况),当然这些对成性不是tanh函数的专属(kurkova and kainen 1994),因为还有其他函数也能造成这种结果,很多情况下这些是不需要考虑的,除了5.7节可能会遇到(个人:因为这在初始化的时候注意下,然后差不多使用BP的时候一般不会造成这种结果,当然也有另外)。

5.2网络训练

      到目前为止,我们都是将NN看成是输入变量的向量映射到输出变量向量之间的参数化非线性函数。通过将NN与第一章的非线性拟合相类比,所以,这里也采用最小化平方误差函数的和的方法。给定输入样本,其中,目标变量值(标签)为,误差函数为:

                                                               (5.2.1)

为了以一种更通用的观点来解释网络训练,首先通过概率的方式来解释网络输出,即解决输出单元的非线性函数和误差函数的选择问题。首先来考虑一个回归问题,假设目标变量可以为任意实数。那么从本书的1.2.5和3.1章节中,这里我们假设是一个高斯分布,具体形式如下:

                                                                  (5.2.2)

这里是高斯噪音的精度(方差的逆)。当然这是一个有些限制性的假设,在5.6部分会将该方法扩展到更通用的条件分布上。对于条件分布(5.2.2)来说,已经足够区分输出单元的激活函数值了,因为该网络可以逼近任意从连续函数。假设数据集是N个i.i.d 的观测值,那么基于目标值,我们可以构建对应的似然函数:

                                                               (5.2.3)

通过使用负的log对数,得到的误差函数为:

                                          (5.2.4)

这可以用来学习参数,在5.7中,会介绍如何将贝叶斯引入NN,这里使用的是最大似然的方法。因为文献中都是最小化误差函数,而不是最大log似然,所以这里也遵循习惯。考虑的第一个决定项,最大化这个似然函数等于最小化平方误差函数的和:

                                                   (5.2.5)

这里舍弃了加法和乘法常量。最小化得到的的值为。实际中,网络函数的非线性会导致误差为非凸的,所以会找到对应的局部最小值,如5.2.1介绍的那样。在得到了之后,就可以通过最小化负log似然来得到的值:

                                                       (5.2.6)

       如果我们有多个目标变量,假设基于上条件独立,而且都是共享噪音精度,那么目标变量的条件分布为:

                                                    (5.2.7)

和之前的单个目标值的同样参数,最大似然的权重是通过最小化平方误差函数的和得到的。噪音精确度为:

                                                 (5.2.8)

这里K是目标变量的个数。在更复杂的优化问题上可以不需要独立的假设。回顾4.3.6部分,的一对误差函数(由负log似然给出)和输出单元激活函数。在回归问题上,可以将网络视为输出激活函数等于本身,即。对应的平方误差函数的和关于其求导为:

                                                                              (5.2.9)

这会在5.3部分用到。现在假设是二值分类问题,而且是一个目标变量,当其等于1时,表示为类,而当等于0时,表示为类。(4.3.6有相关知识)。使用一个输出和逻辑sigmoid为:

                                                                   (5.2.10)

所以。我们可以将解释为条件概率,而。给定输入得到的目标的条件分布是个伯努利分布:

                                                           (5.2.11)

如果我们假设得到互相独立的观察值集合,那么通过负的log对数得到的误差函数可以写成交叉熵误差函数:

                                              (5.2.12)

这里表示。这里没有是因为目标值都假设是 正确的标签。不过该模型也很容易扩展成有标签误差的情况。simard et al(2003)发现使用交叉熵误差函数代替平方误差和函数可以让分类问题的训练更快并提高泛化能力。如果有K个独立的二值分类,那么可以使用一个有着K个输出的网络,其中每个都是独立的一个逻辑sigmoid激活函数,每个输出都是一个二值分类标签,这里。如果假设类别标签在给定输入向量的基础上都是独立的,那么目标的条件分布为:


使用似然函数对应的负log函数,得到的下面误差函数:


这里。同样的,该函数关于具体输出单元激活值的求导如回归情况中(5.2.9)的形式。

        通过将相同问题下NN方法与第4章的线性分类模型相对比,对于如图5.1的那个标准的2层NN,在每个输出之间,第一层的权重都是共享的,而在线性模型中都是独立的。NN的第一层可以被认为是一个非线性特征提取的过程,然后介于不同的输出之间共享这些特征。最后考虑下标准的多分类问题,也就是每个输入都是K个互斥类别中的一个。这里的二值目标变量,是一个1 of K 的编码方案,网络的输出可以解释成,这时候使用的是下面的这种误差函数:

(作者:改成

(个人:就是将5.2.12中的逻辑sigmoid的输出每个单元都相加,然后再把每个样本都相加作为整个的误差)

正如4.3.4介绍的,可以看到输出单元的激活函数可以由softmax函数给出:


(个人:这里用的是softmax函数,而不是之前的那个逻辑形式。虽然可以从逻辑推广到softmax,这个过程可以看ng的ufldl有详细介绍)

这里满足,而且。注意到当对所有的都增加一个常量的时候,并不会变化,这是因为在权重空间中误差函数在某些方向上是恒定不变的。当在误差函数上增加适合的正则化项(5.5部分),那么这个简化就可以不要。同样的,这个函数关于每个输出单元值的求导形式如(5.2.9)。

     总结,对于输出单元激活函数和误差函数的选择还是有些需要总结的,比如对于回归来说,使用线性输出或者平方误差和函数;对于多个互相独立的二值分类(一个输入对应多个标签)来说,使用逻辑sigmoid输出和交叉损失函数;对于多类分类(一个输入对应多类中一个标签)问题,使用softmax输出和对应的多类交叉误差函数;对于只涉及到两类的分类问题,可以使用一个逻辑sigmoid输出或者使用两个输出(这时候使用softmax输出激活函数)。

5.2.1 参数优化

        这里介绍下误差函数的几何解释,我们可以将其视作权重空间中的一个曲面形状,如图:


图5.2.1.1误差函数的几何形式,作为权重空间的一个曲面,点是一个局部最小值,点是一个全局最小。在任意点的位置上,误差表面的局部梯度是由向量得到的。

        注意到在模型建立起来之后,对网络的参数也就是权重有:随机初始化;其他模型给的预训练初始化这两种方式。一般来说几何解释位置就是上面的为初始位置,然后通过寻找误差表面上的梯度方向,然后逐渐的往下找到那个最小值,因为误差函数是关于的平滑的连续函数,极小值也就是(或者很小很小)的时候,当然也是梯度消失的时候,而且该方向为函数最速上升的梯度方向,所以需要减小误差函数,就对其进行逆方向,也就是在上图的表面上往下走,在梯度消失的这个点被称之为驻点,也许是最小值,也许是最大值,也许是鞍点。不过因为误差函数是一个关于权重和偏置的高度非线性函数,所以在权重空间中有着许多的极小值,所以那个最小的极小值叫做全局最小,其他的叫做局部最小。而且不同的权重和偏置还会得到相同的值(上面的5.1.1分析的种就是个例子)。对于NN的应用来说,没必要找到全局最小(因为你不知道这个是不是全局最小),所以一般都是对比几个不同的局部最小来找到一个足够好的解就行了。因为也没期望能够找到解析解。当前来说连续非线性函数的优化还是一个广泛研究的问题,许多文献都有在这方面做工作。许多是对初始值的选择,许多是如何来进行连续的迭代:

                                                                       (5.2.1.1)

这里表示迭代的步次,不同的算法使用不同的权重向量来更新。许多算法是通过使用梯度信息来更新的。为了理解梯度信息的重要性,需要考虑下基于泰勒展开式的误差函数的局部逼近。

5.2.2局部二次逼近

        在优化问题上,以及各种用来解决优化的方法上,都可以通过基于考虑误差函数的局部二次逼近来理解。假设在权重空间上将函数泰勒关于点进行展开:

                               (5.2.2.1)

这里三次和更高次的项都被省略了。这里在点上的梯度:

                                                                                        (5.2.2.2)

而hessian矩阵中的元素为:

                                                                              (5.2.2.3)

从(5.2.2.1)中,对应的关于梯度的局部逼近为:

                                                                            (5.2.2.4)

(个人:就是泰勒展开式关于点的一次求导结果)

这时候假设点足够接近,那么这些表达式就会有合理的关于误差和梯度的逼近。假设在点上局部二次逼近的这种特殊情况,也就是这时候误差函数达到最小值,这时候没有线性项,因为在点上时。所以(5.2.2.1)变成了:

 (作者:改成)                                                (5.2.2.5)

这时候的Hessian矩阵是在点上计算得到的。为了解释这种几何性质,考虑Hessian矩阵的特征值等式:

                                                                                            (5.2.2.6)

这里特征向量形成了一个完备的正交集合(附录C),所以:

                                                                                            (5.2.2.7)

现在将扩展成一个关于特征向量的线性组合形式:

                                                                              (5.2.2.8)

这可以看作是坐标系统的一个转换,其中远点被转移到点上来了(个人:可以看看矩阵论的householder变换等等的矩阵变换部分),而且轴旋转到与特征向量对齐的方向上(通过正交矩阵来实现,该正交矩阵的列为),更详细的本书附录C有介绍。将(5.2.2.8)代入(5.2.2.5),然后结合(5.2.2.7)和(5.2.2.8),误差函数可以写成如下形式:


矩阵有且仅当符合下面的条件的时候才是正定的:

(作者:对于所有v !=0)

因为特征向量可以形成一个完备集合,一个任意的向量可以写成如下形式:


结合(5.2.2.6)和(5.2.2.7),得到下面形式:


所以 当且仅当它所有的特征值都是正的时候,才是严格正定的。在新的坐标系统中,它的基向量是通过特征向量给定的,常量(constant)的轮廓是一个椭圆,中心在原点上,如下图所示:


图5.2.2.1 最小值的周围,误差函数可以被二次形式逼近,常量误差的轮廓就是一个椭圆,它的轴与hessian矩阵的特征向量相对齐,它的长度(lengths)是与对应的特征值的平方根成反比的。

对于一维权重空间,驻点就是最小值,而且如果:


生成对应的hessian矩阵就是正定的。

5.2.3 梯度信息的使用

         正如在后面5.3看到的,可以通过BP的方法来计算误差函数的梯度,也就是通过梯度信息可以加快得到误差函数的最小值的速度。在上面的关于误差函数的二次逼近中(5.2.2.1),误差表面是由参数指定的,这包括了+3)/2个(个人:暂时不知道怎么算出来的)独立的元素(因为矩阵是对称的),这里的维度(即在网络中可调节的参数的总数)。所以用二次逼近最小值的方法是由个参数决定的,在我们完整的确定这个相互独立的信息碎片之前,不要妄想去得到最小值。如果没有使用梯度信息的话,那么就需要执行个函数,每个都需要步。所以这时候使用这种方法来寻找最小值的复杂度就是

        现在假设我们要使用一个算法来利用这些梯度信息了。因为每个都包含着项信息。我们就希望能够在步内找到最小值,正如后面看到的使用BP的方法,每个最小值的确认都只需要不,而且最小值现在可以在步内确定。因此,在实际算法中,是使用梯度信息用来训练NN的。

5.2.4梯度下降优化

         使用梯度信息的最简单的方法就是和(5.2.1.1)一样在负梯度方向上往前一小步来更新权重,所以:


这里参数被称之为学习率。在每次更新之后,梯度都需要重新计算一次。注意误差函数是基于训练集建立的,所以每一步都需要处理整个训练集来得到,使用整个训练集的方法叫做全批量方法(full batch)。每一步上权重会朝着误差函数梯度的方向移动一步,所以该方法也叫做梯度下降或者最速下降法。虽然这个方法理论上看上去很好,其实在实际上是个差算法,具体的可以看(bishop and nabney 20008)。对于批量优化方法来说,有更多更有效的方法,比如共轭梯度,拟牛顿方法等,这些更加的鲁棒而且比简单的梯度下降更快(gill et al 1981;fletcher ,1987;nocedal and wright 1999).不同于梯度下降法,这些算法可以让误差函数在每次迭代中都会下降,除非权重向量已经到局部或者全局最小了。为了找到足够小的最小值,需要将基于梯度的算法运行很多次,每次都是使用不同的随机初始值,然后在一个独立开的验证集上对比训练之后的结果。

       然而,梯度下降的在线版本却在大数据集上NN的训练有很好的表现(le cun et al 1989)。通过基于最大似然的方法,在互相独立的观察值集合上误差函数由这些样本上误差结果的和组成,误差函数如下面式子:


在线梯度下降,也被称之为序列梯度下降或者随机梯度下降,一次在一个数据样本上更新一次权重:


这个更新是通过在顺序或者随机排列的数据上循环更新的,当然中间还有基于批次数据样本来更新的(mini-batch)。相比较于全批量方法来说,在线的一个优势就是它能充分利用数据的冗余性,比如,考虑一个极端的情况,我们得到一个数据集,将它进行双倍的复制,也就是说这个误差函数会被乘以2,所以其实还是等效于使用原始的误差函数。而批量方法却需要两倍的计算来得到批量误差函数的梯度,可是在线方法却不受到这种影响。在线梯度下降法的另一个属性就是它有逃离局部最小的可能。因为对于整个数据集来说,一个关于误差函数的驻点通常不是每个不同数据样本的驻点。

      非线性优化算法,和它们在NN训练上的实际应用,更详细的可以看看(bishop and nabney 2008)。

5.3 误差BP

          这部分的目的在于介绍一种方法来高效的计算前馈NN的误差函数的梯度。也就是大家耳熟能详的BP算法。不过要注意,BP这个术语在NN计算文献中表示着许多不同的意思。例如MLP文献解释是一个BP网络,同时也表示使用梯度下降来训练MLP。本书中,指的是第二个。在大部分涉及到最小化误差函数的训练方法中,通常都包含着两步:求得误差函数关于权重的梯度;对梯度进行更新,这两个部分是完全不同的部分。正如我们看到的BP的最大贡献就是提供了一种用来计算梯度的方法,也就是将误差后向传播过整个网络,当然这个BP不止用在MLP上,可以用在其他的网络上,而且不止是用在简单的平方和的误差函数,还有通过例如jacobian和hessian矩阵得到的导数计算上;而第二个阶段,也就是使用梯度来更新权重的部分,最简单的也就是rumelhard 1986年提出的梯度下降方法,当然也还有其他的优化方法的,而且比最简单的梯度下降要好很多。

5.3.1 误差函数导数的计算

       这部分讨论一个有着任意前馈拓扑,任意可微分非线性激活函数,一类广泛的误差函数上适用的BP算法,不过以一个简单的单层隐藏层的sigmoidal的网络、平方误差和函数作为例子讲解。

      许多误差函数都是基于i.i.d 数据上的最大似然函数得到的,通过将训练集中每个样本的误差加起来作为整个数据集的误差函数:

                                                                                  (5.3.1.1)

这里需要考虑的问题是如何求得这个函数中的每一项,这可以直接用作后面的序列优化,或者累加起来用于批量方法中的情况。首先假设一个线性模型,其中的输出是输入变量的线性组合:

                                                                                      (5.3.1.2)

,对于一个具体的第n个样本输入 来说,它的误差函数就是:

                                                                       (5.3.1.3)

(个人:将输出层的k个神经元的误差加起来,这是在单个样本情况下)

这里。该误差函数关于权重的梯度为:

                                                                         (5.3.1.4)

在这其中就是我们称之为的“误差信号”,也叫做残差。为直接与这个权重(这里权重表示一个连接上的权值,以前馈方向来说,连接的输一端为输入端,一端为输出端)关联的输入端的激活值。在一个通用的前馈网络中,每个单元的权重化对应的输入的和为:

                                                                                       (5.3.1.5)

(个人:也就是网络中一个神经元输入的部分,将与其相连的输入权重路径上的输入与权重上的值相乘的结果,之后才会放入一个非线性转换函数)

然后将上面这个作为该神经元节点的输入,在其上面通过一个非线性激活函数来得到这个神经元的激活值:

                                                                                            (5.3.1.6)

        现在考虑如何来求关于某一层的的导数。因为每个不同单元的输出是依赖于具体的输入单元的 ,首先注意到是只作为单元 j 的线性组合值的输入权重的。可以通过使用链式规则来求偏导数:

                                                                              (5.3.1.7)

这里引入一个很有用的符号,也就是后面说的残差:

                                                                                           (5.3.1.8)

基于(5.3.1.5),可以得到下面这个(个人:就是这个单元的输入权重乘以对应的权重输入端的激活值生成的形式,用这个形式来求关于权重的导数。所以前面需要计算从输出层传到这个单元的残差关于这个线性组合的导数):

                                                                                       (5.3.1.9)

通过将(5.3.1.8)和(5.3.1.9)带入到(5.3.1.7)中,得到:

                                                                            (5.3.1.10)

从上面这个式子可以看出,所要求的导数其实就是权重输出端的那个残差乘以权重输入端的那个激活值(当为偏置的时候z  = 1 )。所以,为了求的这个导数,只需要计算隐藏层和输出层的每个值和对应的输入值,然后使用(5.3.1.9)就行了,正如这里假设的模型(个人:这里的模型的输出层的激活函数使用的是线性函数5.3.1.2,不是平方误差和函数,对于输出层的第k个单元来说,残差就是下面的结果),输出层单元的残差为:

                                                                            (5.3.1.11)

为了计算隐藏单元的值,再次使用链式规则 来求偏导数:

                                                           (5.3.1.12)

需要求得输出层所有与隐藏层第 j 个单元相连的 k 个单元传递过来的残差加起来。误差传递如下图形式:


图5.3.1.1 通过Bp计算右层k个单元传递过来的,从而计算隐藏层第 j 个单元的值。蓝色箭头表示前馈传播中信息传播的方向,红色箭头表示误差信息反向传播的方向。

这里标记的k 指的是该层后面的隐藏层或者输出层上的单元个数。在式子(5.3.1.12)中,我们基于这样一个事实,误差函数的变化只通过变量传过来(个人:也就是误差是通过权重往回传递,所以有k个连接,才将这k个误差加起来)。如果我们现在将由(5.3.1.8)定义的带入(5.3.1.12)中,然后结合(5.3.1.5)和(5.3.1.6),那么Bp的式子为:

                                                                          (5.3.1.13)

这告诉我们对于一个具体的隐藏单元的值来说,可以通过网络中更高层单元的回向传播得到,如上图所示。注意到上面这个式子的求和是基于第一个索引的。

      BP的总结:

     1、通过前馈计算整个网络的输出层每个单元的激活值;

     2、计算所有输出层单元的每个

     3、通过BP使用(5.3.1.13)来计算每个隐藏单元的

     4、使用(5.3.1.10)来计算所需的导数

     对于全批量方法来说, 总的误差的导数可以通过重复上面训练集中每个模式的步骤,然后将他们加起来:


上面的计算中我们都假设网络中每个单元的激活函数都是相同的,所以导数是一个通用的格式,如果不同单元使用的是不同的激活函数的话,那就需要在求导的时候追踪每个单元的函数。

5.3.2一个简单的例子

      针对上面的原理,这里举一个实例,假设模型是如图5.1.1的两层网络,使用的是误差平方和函数,在每个输出层的单元都是线性激活函数,也就是,隐藏单元的激活函数都是sigmoid函数:


也就是:


该函数一个很有用的特点就是他的导数为:


在使用误差平方和函数的基础上,对于第n个样本来说,得到的误差为:


这里是输出层的第k 个激活值,为对应的目标值,也就是 标签。

       首先,我们进行前馈传播:


      然后,计算输出层每个单元的残差


然后后向传播得到隐藏单元的残差:


最后,求得关于第一层和第二层的权重的导数:


5.3.3 BP的效率

       对于BP来说,一个最重要的问题就是它的计算效率。首先我们来了解下在基于网络中权重和偏置的总数为的情况下,计算误差函数的导数时所需要的计算操作次数。对于足够大的来说,一个单一的误差函数(一个输入样本)的复杂度为。这是基于这样一个事实:除了网络十分稀疏的情况下,权重的数量通常都会大于单元的数量。所以在前馈传播中计算的工作量受到(5.3.1.5)中求和的影响,而激活函数的计算需要较小的开销代价。在(5.3.1.5)中的每一项需要一个乘法、一个加法,总的计算代价就是

       一个用来代替BP计算误差函数的导数的方法就是有限差分。这通过扰动每个权重,然后通过下面的式子来逼近得到导数:

                                                           (5.3.3.1)

这里。在软件仿真中,逼近导数的精确度可以通过让变得更小(直到出现了数值舍入的问题为止)来改善。有限微分的精确度通常来说可以通过使用对称中心差分来提高:

                                              (5.3.3.2)

在这种情况下,的修正可以不要了,这可以通过在上面式子右边的泰勒展开式来验证,所以这时候的修正项变成了。然而这时候计算步骤的数量就变成了差不多(5.3.3.1)的两倍。

       数值差分的主要问题就是原来缩放因子(个人:在计算训练复杂度时乘以该因子)没有了。每个前向传播需要步。而在网络中的个权重都必须被独立的扰动,所以总的缩放因子成了

      不过在实际中数值差分还是很有作用的,它可以用来作为检查BP算法得到的梯度的正确与否。

5.3.4 Jacobian 矩阵

       同样的BP可以用来计算其他导数,这里就是介绍如何用来计算jacobian矩阵,它的元素都是网络的输出关于输入的导数:


其中每个导数都是基于所有的输入来确定的。jacobian矩阵在由很多不同的模型构成的系统中占据着重要地位,如下图所示:


图5.3.4.1 一个模块化的模式识别系统,其中jacobian矩阵用来将输出层的误差信号反向传播到系统前面的模块

该系统中每个模块都由一个固定的或者自适应函数构成,可以是线性、非线性,反正一定要能够微分。假设我们想要最小化上图中关于参数的误差函数。该误差函数的导数为:


这里的jacobian矩阵就是上图的红色模块。因为jacobian提供了一个测量输出关于每个输入变量变化局部敏感度的方法,而且,任何输入端的改变可以通过训练好的网络传播到输出端,并计算该误差对输出的影响:


很小的时候,上面的式子是成立的。由训练好的NN表示的网络映射是非线性的,所以jacobian矩阵中的元素都不是常量,不过也依赖于使用的具体的输入向量。所以上面这个式子只当输入有着很小的扰动的时候才是有效的,而且jacobian矩阵自己对于每个新的输入向量就必须要重新计算了。使用BP计算jacobian矩阵犹如之前对误差函数关于权重的导数计算一样,这里以元素来进行讲解:


这里使用了式子(5.3.1.5)。上面这个式子的求和是基于所有与输入单元i 相连的单元 j 上得到的(例如,与输入层单元i 相连的第一层隐藏层的所有单元)。现在可以通过递归BP形式来求出导数


再一次,这里的求和是基于所有与单元j 相连的后一层单元l 上得到的(对应着的第一个索引)。再一次使用(5.3.1.5)和(5.3.1.6),这里的BP是从输出层单元开始,所求的导数从输出单元的激活函数的函数形式求导开始,如果我们在每个输出层单元上使用的是独立的sigmoidal激活函数,那么:

(j 换成 l )

对于softmax输出来说:

(j 换成 l ,L的小写)

       总结jacobian的计算过程:首先通过输入向量进行前馈计算得到整个网络各层的激活值;然后,对于jacobian矩阵的第k 行,对应着输出层单元k,使用上面的BP递归计算隐藏单元和输出层单元的导数。再一次,这里可以通过使用上面的数值微分(5.3.3.2)来检查得到的导数是否正确。

5.4 Hessian矩阵

       前面介绍的都是BP如何来计算网络中误差函数关于权重的一阶导数;这里介绍如何来计算关于权重的二阶导数:


为了描述方便,这里将所有的权重和偏置参数都拉成一个向量的形式,其中元素为对应的权重和偏置。而对于二阶导数来说,就是hessian矩阵的元素,并且,这里就是权重和偏置的总数。Hessian矩阵在许多的神经计算中扮演着重要角色,包括:

     1、一些用于训练NN的非线性优化算法是基于误差表面的二阶导数基础上考虑的,而这就是由Hessian矩阵控制的(bishop and nabney 2008).

      2、当训练数据有微小变化的时候,hessian可以作为快速重训练前馈网络的基础(bishop,1991)

     3、hessian的逆矩阵可以用来识别网络中最不重要的权重,然后将其作为网络“修剪(pruning)”算法的一部分(le cun et al 1990)

     4、在用拉普拉斯逼近一个贝叶斯NN的时候,hessian占据着中心地位(5.7节)。它的逆用来计算一个训练好的网络的预测分布,它的特征值可以用来决定超参数的值,它的行列式可以用来评估模型的evidence(个人:不知道怎么说)。

     对于NN来说,各种逼近算法都可以用到Hessian矩阵,而Hessian还是可以通过BP来准确的计算得到。在许多hessian的应用中的一个重要依据就是它的计算的效率,如果有个参数(权重和偏置),那么hessian的矩阵就是×的,所以对于每个样本来说,需要的计算复杂度的缩放因子是

5.4.1对角逼近

        上面讨论的一些hessian的应用通常需要的都是hessian的逆矩阵,而不是hessian矩阵本身,所以我们对求得hessian的对角化逼近矩阵(简单的将非对角线元素置零)很有兴趣,因为该对角逼近矩阵的逆矩阵很容易求出。同样的,这里我们使用的误差函数是包括一个求和项的,每一项表示数据集中的一个样本,即,hessian矩阵可以一次一个样本的计算得到,然后将每个结果相加就行,对于(5.3.1.5)来说,在第n 个样本下,hessian的对角元素的可以写成:


通过使用(5.3.1.5)和(5.3.1.6),上面式子右边的二阶导数可以通过递归使用微分计算的链式规则的方法得到一个BP等式:

(作者:最右边改成

如果我们忽略二阶导数中非对角元素,那么可以简化成下面形式(becker and lecun 1989;lecun 1990):


需要计算这个逼近的计算步骤是,而对于完整的Hessian计算来说是,Ricotti et al 1988年使用hessian的对角逼近,不过他们是重新训练了中的所有项的,所以它们得到的是对角项的准确值。不过注意这里没有作为缩放因子的好处了,因为对角逼近的主要问题在于在实际操作中hessian通常是不能对角化的,所以这些逼近(主要为了计算方便)在计算的时候需要十分小心。

5.4.2 外积逼近

        当用NN来做回归问题时,通常都是使用平方误差函数求和的形式:


为了推理容易,这里值考虑输出层只有一个单元的情况(多个输出的情况可以较为容易的推广),可以将hessian矩阵写成如下形式:

(第一项是,少了转置)

可以看出如果输出的十分接近目标值,那么上面式子的第二项就可以省略了。不过大家认为严谨的观点是如1.5.5节说的,最小化平方损失和函数的最优函数是基于目标数据的条件平均,所以是一个有着0均值的随机变量,如果我们假设该值与上面式子右边第二项的二阶导数项之间不相关,那么整个第二项就是基于n 的和上均化为0。通过忽略这一项,就得到了一个levenberg-marquardt  逼近或者叫做外积逼近(因为这时候hessian矩阵可以通过向量的外积的和计算得到),所以:


这里,因为这里输出单元的激活函数是自身(即线性函数)。计算hessian的外积逼近是很简单的,因为这只涉及到了误差函数的一阶导数,也就是使用标准的BP只需要计算步就能得到。该矩阵的元素可以通过简单的乘法在步内完成。不过这里也有个问题值得注意的就是这个逼近只有当网络适当的训练之后才有用,对于那些通用的网络映射来说,第二项的二阶导数没法忽略的。

       在以交叉熵函数作为网络的误差函数,而且输出单元的激活函数是逻辑sigmoid函数的情况下,对应的逼近结果为:


使用softmax激活函数的多分类网络可以得到类似的结果。

5.4.3 逆hessian

       前面使用的外积逼近可以用在计算hessian的逆矩阵逼近过程中(hassibi and stork ,1993)。首先将外积逼近写成矩阵符号的形式:


这里是从第n个样本中得到的激活的输出单元的梯度,并且一次计算一个样本,建立一个hessian矩阵。现在假设我们已经通过前面L 个样本计算得到了逆hessian矩阵。那么在计算第L+1个样本的时候,得到如下关系:


为了计算hessian的逆,我们现在考虑这样一个矩阵关系:


上面的式子是woodbury 的一个特殊情况(C.7)。如果将上面的换成,而换成,那么:


以这种方式,可以处理完整个数据集。所以其实也是从头到尾处理完整个数据集,就刚好计算得到整个数据集上的hessian矩阵的逆,初始化矩阵,这里是一个很小的数,所以这个 算是实际上是为了找到的逆。不过结果不是特别的对的精确值敏感。对于多输出单元,只要将该算法简单的扩展就行了。这里我们可以发现hessian可以间接的作为网络训练算法的一部分。不过具体来说,拟牛顿非线性优化算法可以在训练阶段逐步的建立一个关于hessian的逆矩阵的逼近。这些算法在bishop and nabney 2008中有详细的介绍。

5.4.4 有限差分

        和一阶导数一样,这里的二阶导数也可以找到有限的差分方法,准确度受到数值精度的影响。如果我们每次都扰动一对权重,我们得到下面的形式:


通过使用对称中心差分的方式,可以确保剩余误差为而不是。因为在hessian矩阵中有个元素,每个元素的计算都需要步操作,所以要想计算完整的hessian矩阵,需要的计算复杂度为。所以这个缩放因子太大了,尽管在实际中它可以用来作为检测BP方法实现的正确与否。一个更好的数值微分的方法是通过使用误差函数的一阶导数的中心差分:


因为只需要扰动个权重,而且梯度可以在步内计算,所以用这种方法得到的hessian只需要步。

5.4.5 hessian的准确计算

        到目前为止都是计算的逼近,其实可以计算准确的hesssian的。通过在一阶导数上使用的BP的扩展方式。求得hessian需要的步骤是以作为缩放因子计算的。这里我们考虑一个有着两层权重的网络,并且使用索引表示输入,索引表示隐藏单元,索引表示输出,首先定义:


这里表示第n 个样本造成的误差。该网络的hessian可以以下面三个步骤计算完成:

      1、第二层中的两个权重:


     2、第一层中的两个权重:


      3、每一层中的一个权重:

(H应该是M,作者写错了,而且等号右边索引交换下位置)

这里是单元矩阵的第()个元素。如果这一个或者两个权重是偏置,那么对应的表达式可以简单的将对应的激活值设置为1就行。包含跳层连接的计算也不难。

5.4.6 利用hessian的快速计算

       在许多涉及到hessian矩阵的应用中,人们感兴趣的不是hessian矩阵本身,而是hessian这个矩阵与某个向量相乘的积。从之前的分析可以得出计算一个hessian需要步操作,而且它同时需要的存储也是。而计算得到的向量只有个元素,所以如果能够不算出中间的hessian矩阵,而是直接计算的结果,那么就只需要 步了。

       首先,注意到:


这里表示权重空间中的梯度操作符。我们先分析为了求的前向传播和后向传播的式子,然后通过上面这个式子分析为了求的前向传播和后向传播的式子集合(moller 1993;pearlmutter 1994)。这相当于用一个微分操作符作用在原始的前向传播和后向传播式子上。1994年pearlmutter使用符号来表示操作符,这里也这么用,通过将这个符号与之前的微分计算规则放在一起,得到下面这个结果:


(个人:应该是,不过觉得应该是转置才对的上后面的关于aj的求梯度,)。这里通过一个简单的例子来说明这里的原理,我们这里假定选择如图5.1.1的结构,一个2层的NN,输出端为线性激活函数,使用的是平方误差和函数。并且考虑一个样本的情况下,所需要计算的向量就是将每个独立样本处理完之后进行点加就行了。对于这一个2层的网络来说,前馈传播的式子为:


现在引入操作符,得到前馈传播的集合形式:


这里是对应着权重的向量中的元素。而被认为是按照上面的式子计算得到的新变量(个人:对上面关于zj的梯度暂时推不出来,因为算出来是v h‘(aj )*求aj的梯度,和上面的对不上,即vT 和h’(aj)满足交换律??,这里是针对单个神经元考虑,所以是标量,符合交换律)。

        因为我们使用的是平方误差和函数,所以得到的标准BP表达式为:


再一次使用操作符,得到关于BP式子的集合:


最后,加入之前求得的误差的一阶导数:


然后加上操作符,得到了向量中元素的表达式:


该算法的实现涉及到了额外作为隐藏单元的变量;和用在输出单元上的。对于每个输入样本来说,这些变量的值可以通过使用上面的结果计算出来,而且的元素通过上面这两个式子计算得到。不过该技术的一个优势在于这里使用的都是现有的前馈和反向传播技术,所以可以通过现有的软件包来稍微改动计算就能得到了。

     如果理想的话,该技术可以用来计算完整的hessian矩阵,通过一连续的向量,只要其中的一次选择计算hessian的一列。这会有着如5.4.5一样的良好的原理分析,不过就是会有些冗余计算。




(页面太长:见PRML5-神经网络(2))

ps:对于兴起的DL,推荐看看《Deep Learning in Neural Networks: An Overview 》,发表在arxiv上的,一共88页,可是却引用了888个参考文献,作为深度的阅读还是很有帮助的,收录了很多一路走来dl在NN中的发展的很多好文章,当成一个dl在nn中的论文收集综述看吧。

posted @ 2015-07-13 20:58  仙守  阅读(638)  评论(0编辑  收藏  举报