AI | 神经网络和误差反向传播算法

01 | 神经网络的求解目标

神经网络模拟了人脑神经元借助突触传递电信号的生理机制,借由“输入层→隐藏层→输出层”实现对任意线性和非线性关系的拟合。

脱胎于人脑神经元,因此先天具有线性输入和偏置;不同层的神经元借由权重系数相互关联,因而不同层神经元之间的线性权重也是重要的参数。

当我们根据问题背景和先验知识预先设计好神经网络的层次及每层神经元个数后,接下来的工作就是通过数据拟合的方法,确定最优的线性权重与偏置组合。

对于生理神经元与模型神经元的差异可见图1,模型态对输入/输出数值以及激活函数进行了优化,使得其可以符合数学求导的连续性要求。

图1
图2展示了将不同神经元按照层次组合起来,就可以得到一个实际的神经网络模型;当其隐藏层具有多层/多个神经元时,即成为深度神经网络,相应的训练、预测分类过程也称之为深度学习(Deep Learning)。图2中将3×4的图像按照12个像素建立输入层,通过一个3神经元的隐藏层提取模式后,输出两个分类。

图2

02 | 神经网络求解本质

既然神经网络确定参数的过程类似于数据拟合,容易联想到数学领域中的“回归分析”,其一般过程也是指定某个模型方程,然后基于一组样本数据,选择最贴合样本数据的方程参数。
典型的回归分析即线性回归分析,如下题:

图3

基本的结题思路是计算7个样本的平均误差,然后求解平均误差的最小值。根据高等数学知识,容易知道最小值一定出现在偏导数为0的坐标点,于是问题转变为求解平方误差关于参数p和q的偏导数方程的唯一解;注意由于样本数据多于待求解参数个数,因而方程具有唯一解;确定p和q后,即可绘出相应的直线。

图4

图5

图6
其实神经网络的求解本质上也是由数据拟合参数的回归分析过程,因此具有共性:

1)需要确定刻画模型预测值和真实值(Groud Truth)的损失函数

2)由于本质上是损失函数关于参数的偏导数方程组求解,有且唯一解的条件是具有不小于待确定参数数量的独立样本数据,考虑到深度学习网络的层数与神经元个数极其庞大,导致其待确定的参数数量也是个天文数字,因而一般情况下,深度学习的训练求解都要求有海量样本数据支撑

除去上述两个相同点,神经网络自身的损失函数相对于参数的偏导数方程因为数量和多层嵌套问题,导致实际求解极其复杂,因而不能再使用线性回归分析中的方程组直接求解,必须寻找更可行地工程解决方案。

03 | 梯度下降算法

现实中人们下山的时候,往往不是一蹴而就,而是不断变换方向,寻找合适的下山路线。受此启发,人们提出了的“梯度下降算法”。

梯度下降算法的本质就是建立一种多步迭代机制,每一次迭代的时候都选择当前“最快”的下山方向,并迈出适当的一步;通过多轮不断迭代,就可以迅速逼近损失函数的最小值点(下山成功)。

那么如何确定“最快的下山方向”呢?

受到高等数学中关于多元函数极限的定义,以二元函数为例,当点(x,y)产生一个微小变化(x+△x, y+△y)时,其函数值的变化满足近似公式:

图7
上述式子等号右侧可以看作两个向量的内积:

图8

根据高中数学中关于两个向量内积方向夹角的认识(如柯西不等式),可以知道若想按照最快速度“下降”,变化量保持不变的情况下,应当使得内积最小;而两个大小确定的向量内积最小值出现在夹角180度时,此时显然有:

图9
其中的“-”表示位置变化应该是当前位置偏导数的负方向,即当前坐标减去相应的偏导数;η则作为“步长”刻画每次向负向偏导数方向移动的距离大小。需要注意的是,步长(或成为学习率)的设置不宜过大过小,因为过大时有可能直接“跳过”最小值点,而过小时则可能在局部极小值点附近来回徘徊,实际中需要多次尝试调参以取得最佳效果。

图10

04 | 误差反向传播算法

梯度下降算法的作用在于将求解回归分析方程组转变为了可迭代的梯度运算,从而给予了求解人工神经网络(ANN)工程解决方案(并非类似求解线性方程组那样的理论化方案)。

即便如此,人们在实际计算梯度迭代时,发现深度神经网络(DNN)中的权重参数与偏置参数实在是太多了,如果想求得对应的偏导数,就会陷入“导数灾难”,即根据复合函数求解的链式法则,所得到的损失函数针对某层神经元权重的偏导数会极其复杂;不仅如此,如此复杂的权重计算还很多!
ANN的求解再次制约了其发展,学术界亟需一种可行的梯度下降求解实现方案。

1986年美国斯坦福大学的Rumelhart等人提出了一种新颖的梯度计算方法,利用该方法,原本复杂的偏导数计算可以简化为神经元输入与输出间的简单函数。这就是今天闻名许久的误差反向传播算法。

误差反向传播算法的核心在于“神经单元误差”的提出。人们在分析神经网络权重偏导数求解过程中,发现经常出现的一个运算单元,即损失函数对于神经元线性输入的偏导数,如对于某神经网络,第L层第j个神经元的误差为:

δ j L = C z j L \delta_{j}^{L} = \frac{C}{z_{j}^{L}} δjL=zjLC

有了神经单元误差的概念,很快就可以将任一层线性权重和偏置均表示为该层神经单元误差和上一层输出的函数,其中{a}表示第l-1层第i个神经单元的输出:

图11
现在的问题转变为了如何有效求得损失函数C相对于每个神经单元的神经单元误差,即相对于每个神经单元线性输入部分的偏导数。

事实上,根据链式求导法则,可以计算出任一神经单元误差的表达式:

图12
进而通过推导,可以得出神经单元误差间的后向数列推导公式,其表明任一层的神经单元误差均可以由其关联的后一层所有的神经单元误差加权对应的系数后,链式激活函数对线性输入部分z的导数计算得到。

图13
庆幸地是,沿着既有的神经网络结构正向计算一次后,即可得到相应的线性输入和输出部分,进而由输出层可以逐步反向计算前一层的神经单元误差,并进一步计算相应的线性系数或偏置的偏导数,如此重复,即可不通过求导,而是数列递推的方式计算得到所有需要计算的参数的偏导数。
接下来就是利用梯度下降算法思想,减去梯度×步长得到更新后的参数坐标点,然后进行下一次数据迭代。

05 | 写在最后

本文并未进行详细的数学公式推导,因为涉及链式法则相对繁琐。对于大多数ANN使用者而言,仅需要建立一种认知:ANN的求解可以借助梯度下降算法逼近损失函数最小值,其中偏导数的计算可以借由基于神经单元误差的误差反向传播算法递推计算,所用数值均为相应神经单元的线性输入与激活函数、输出值等——而这些数值在进行正向计算时均已存储在网络数据结构中了。

另外值得一提的是,由上述的讲述,如果只有一个样本也可以进行一次误差反向传播以更新参数,但是考虑到实际样本数量庞大,每次都更新很可能会导致参数波动起伏剧烈,不利于把握样本整体模式,而且效率并不高;因而通常的做法是将所有的数据看作一个Epoch,然后分成多个Batch,每个Batch输入完成后进行一次损失函数计算与误差反向传播以更新参数,将所有Batch均输入处理完成后即结束一个Epoch;若效果依旧不满意,可以重复再进行下一个Epoch。

简而言之,ANN中误差反向传播求解的来龙去脉是:

图14

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值