北 京 大 数 据 研 究 院
BEIJING INSTITUTE OF BIG DATA RESEARCH

【科普系列】深度学习 Part 2

【导读】今天为大家带来深度学习系列干货第二期——人工神经网络

就目前而言,预测问题(包括分类与回归),是机器学习中最主要的一类。什么是预测呢?简单来说就是找到一个预测函数f,当输入X的时候,可以计算出y=f(X)。虽然从数学角度出发,最佳的函数f总是会存在的,也就是我们通常所说的“条件数学期望”,但是实际上,f往往是复杂且无法算出的。因此,我们需要首先假定这个函数具有某种确定形式。比如,假定f是线性函数,可以得到f(X)=w*X+b(其中w,X为向量);或者假定f是指数线性的,得到f(X)=exp(w*X+b),诸如此类。f的形式选择需要基于实际问题和我们的需求,有时我们希望f比较简单,能够迅速出结果;有时我们希望f能够尽可能地准确;有时我们可能希望f具有可解释性……


首先我们根据需要,主观选择了f的形式,将其视作f(X,w,b)(其中w和b是函数的参数,可以使高位响亮、矩阵甚至张量,由大量数字组成)。w和b取不同值对应该形式下不同的函数。举个例子,如果w取遍所有p维是响亮,k取所有实数,此时f(X,w,b)=w*X+b就可对应所有p元线性函数了。所以我们想要找到一个最佳的线性函数,就等同于找到一对最好的(w,b)。也就是说,在确定函数形式后,寻找最佳函数的问题就归结为寻找最佳系数的问题了,而后者往往是由计算机来完成的。

传统的统计学和经济学领域学者喜欢选择线性函数,是因为其简单易计算,且可解释。但是,线性函数有着巨大的欠缺——表示能力不足。想象一下在一个平面上有一条曲折回环的曲线,而我们打算通过线性回归找出一条直线,粗暴地把这条曲线解释为与这条直线近似。这个过程无疑会遗失掉大量的信息和特征。


而我们今天的主题,人工神经网络,与线性函数就存在着完全不同的思路。本质上讲,神经网络是一个极其复杂的多层嵌套函数,有着大量的参数(仍记为w,b,但此处二者代表高维张量)。简单来说,在这个模型下,我们可以想象当参数变化的时候,函数f的图像可以百转千回,模拟出各种形状。因此,与线性模型相比,神经网络的表示能力明显强大了很多个量级。然而,相应的,线性模型的优势在神经网络中不复存在,寻找最佳参数变得十分困难,整个模型变得难以解释。


我们将寻找最佳参数的过程称为“训练”,将训练时所拥有的n组对应的(X,y)数据称为“训练集”。整个流程可以概括为用训练集数据去寻找最佳参数。很多情况下,函数f的选择标准是预测值与真实值之间的平方误差(损失函数)尽可能小。由此,选择w,b的方式如下:

当然,我们也可以选用绝对值误差或者其他方法来选择损失函数,或者为了防止“过拟合”而在后面添加正则项等等,都是可以的。但是这些最终都能被化为求解一个极值的形式,因此在这篇文章中我们不妨采用一个最简单的形式。


当我们通过以上方法算出w和b之后,就得到了一个确定的函数f(X,w,b),此时,我们再输入一个新的X时就可以得到预测值y了。通常情况下,为了确定f是值得信赖的,我们会用已知的另一组(X,y)对f进行测试,我们称这组(X,y)为“测试集”。当确定f达到我们的要求时,我们就可以用它创造价值了。


综上,预测问题的处理流程是:根据需求选择模型→根据已有(X,y)求解极值得到最佳参数w,b→输入新的X,得到预测y。

我们接着来考虑神经网络的构造。构造神经网络的目的就是要发明一个f(X,w,b),使得当参数X变化时,能拟合出各种函数,描绘各种复杂的形状,越不线性越好;而另一方面,我们又希望这个函数能有比较简单的形式,也就是说越接近线性越好。乍看之下这是一个不可调和的矛盾,但是我们来看看神经网络是如何解决这个矛盾的。


首先,我们在线性函数的外层加套一个非线性的部分,使得其具有非线性特征。以Sigmoid函数为例:

这是一个S形曲面状函数,当w,b变化时,能够表示各种不同的S形曲面。听起来和线性函数类似,当线性函数参数变化时,对应不同的平面状函数。二者都不能拟合出复杂曲折的函数,因此,这一点上讲,该函数不见得比线性函数好。

但是,这个S函数与线性函数已经有了本质的区别:将线性函数进行线性组合或者再复合,仍然得到一个线性函数,但是这个S函数进行组合或者再复合后,得到的就不再是一个S函数了,而是一个复杂曲折的曲面形状。此处可参考以下式子:

由此可以想象这个函数的图像将是一个曲折回环的曲面,当参数w,b变化时,这个图像就可以千曲百折拟合出各种各样的形状了。

可以看出上面的例子只进行了两层嵌套,事实上我们可以根据需要进行多层嵌套。首先假定网络有n层,对于首层,输入自变量X,之后每一层的输入都是上一层的输出,而每一层的输出则是前一层输入的线性组合再加套一个S函数。基于此,当嵌套层数不断增多的时候,函数形状将变得极其复杂。我们通过下图来描绘这一过程:

做一下小结:神经网络是复杂多元函数的拟合器。其要解决的主要问题在于既要很好地拟合各种复杂的情况,又要相对简单可解释。解决方法主要是通过将自变量线性组合→复合非线性函数S→再进行线性组合→再复合非线性函数S……如此循环往复。这样一来,通过不断的复合能拟合出各种曲折复杂的形状,而对于线性组合和非线性函数S这两个函数组成部分都是比较简单且我们足够了解的。顺便一提,这种构建神经网络的思想,对于CNN,RNN等神经网络而言都是十分重要的。

3.1 优化——寻找极值

根据前文的介绍,训练神经网络的过程就是求解一个极值表达式。该式中,X是固定的参数,而w,b是变量。这一过程在数学中称为“优化”。


对于神经网络而言,为找寻最佳w,b,如果使得所有偏导数等于0,相当于求解一个形式极其复杂的大规模非线性方程组,这是根本没有办法解出来的。


而优化,采取了一种与求解方程完全相反的路径:首先假定f有关的w,b的偏导数表达式g(w,b),h(w,b)。如果是通过g=0,h=0与求解w,b总是很困难的,但是已知w,b去求解g,h总是相对简单的。因此,我们已知函数的一点,就可以知道其各个分量的偏导数,然后由于函数形式可微,就可以算出其所有的方向导数。由此,可以找出其下降最快的方向(方向导数最大的方向),称之为“最速下降方向”。


3.2 神经网络的BP算法

事实上,当每一个偏导数的表达式几乎和神经网络一样复杂的时候,同时存下这么多参数各自的偏导数表达式并不是很现实,因此我们需要找到一种方法,能够求出对确定参数w.b的方向导数。这里,我们需要用到复合函数求导的链式法则:

如果有多层嵌套,则可迭代使用链式法则:

将我们的神经网络f(X,w,b)利用链式法则进行求导。对于每个具体参数,都得到一个长长的链式求导表达式。由于我们的神经网络是由线性组合与S函数不断符合而成的,这两部分的求导都很简单,因此将它们用链式法则连起来得到结果也不难。

由于不同参数的编导表达式之间有着密切的联系,因此我们在对参数求偏导的过程中,实际上会先求出最后一层参数的偏导,再利用这些求导的值与求倒数第二层参数的偏导,以此类推,直到把第一层的所有参数的偏导求出来为止。


这个过程恰好与函数求值的过程相反,看起来是一个“后传”的过程,因此,训练神经网络的算法被称为“后传算法”,英文缩写为“BP算法”。理解BP算法的本质,对于后期理解CNN和RNN的训练过程是十分重要的。


3.3 神经网络的训练方法

通过BP算法,我们找出了下降最快的方向,但这并不是优化过程的全部,我们还需要确定向这个方向走的步长。


此处考虑一种最为简单的最速下降法:每一步都沿着最速下降方向下降一个固定的步长,直到达到一个指定的步数为止。公式如下(SD代表最速方向steepest descent,P为一个固定的步长)

接下来我们将这个算法做一些改动,使其具有更好的性能。


首先介绍一种叫做“Momentum”的算法(动量算法)。每一步除了沿着最速下降方向下降一个固定的步长之外,还要加一个“惯性项”,即上一步乘以一个衰减系数(0-1之间)。基于此,我们的优化算法就像具有了“动量”一样。这个算法总体来说比前一种最速下降法的效果要好。

其次,步长也不能是一成不变的,步长应该随着下降的步数逐渐下降,而这种方法被称作“Adagrad”:

而目前的实践中最流行的方式是“Adam”,大致是以上两种算法优势综合的结果:加入了“惯性项”以及“步长衰减”。其每一步的步长是都是前一步信息与这一步最速下降方向的滑动平均和。具体的公式比较复杂,就不在这里赘述了。



小编的话:今天深度学习的科普知识就到这里了,不知道有没有帮助大家了解深度学习更多一点呢?插播一句宣传,深度学习的相关课程和案例实践都可以在数据嗨客的平台上进行哦,以下附上课程链接:

http://hackdata.cn/learn/course/7/