人工神经网络背后的数学原理!
本文约8000字,建议阅读20分钟
本文介绍了人工神经网络背后的数学原理。
前言
搭建网络架构(含有待定参数) 通过比较输出与标签的差值定义损失函数(自变量为待定参数的函数) 随机给出一组初始参数 给出一个(sgd)/ 一批(Minibatch)训练样例(包括ANN的输入值和输出值) 前向传播得到预测标签和损失 利用梯度下降算法从后往前调整网络参数(误差反向传播,BP) 得到所有参数值 得到ANN并使用
其实这个问题非常简单,只是大家被梯度下降复杂的过程搞蒙了,忘记了它的本质。梯度下降算法自始至终都在干一件事——就是找到函数的极值点,当然确切的说是极小值点。但是,这种方法不同于以往我们在高等数学里学到的找极值点的方法。那么我们首先就要问,求极值的经典方法不香吗?
1.1 求极值:传统的方法不香吗?
例如要找到 f(x) = x^2 + 3x 的极值点
求导得 dy/dx = 2x + 3
令 dy/dx = 0
就得到 x = -1.5 时,导函数为0。
当 x < -1.5 时,2x + 3 < 0
当 x > -1.5 时,2x + 3 > 0
说明函数在x = -1.5 附近先下降、后上升
该点是一个极小值点
对于二元函数,情况更复杂一些。首先要找出该函数的驻点和偏导数不存在的点,这些点仍然只是可能的极值点。而二元函数的驻点需要同时满足两个偏导数为0的条件,即
该方法方法不具有普适性。所谓普适性,就是不能简单的向多元推广。从一元到二元的例子可以看出,函数的自变量个数每增加一元,就要研究新的求解方案。可以想象如果是三元函数,其二阶偏导数的个数更多,则判断极值的充分条件还要来的更加复杂。而ANN中可能会求解上亿元函数的极值点。 其次,这种方法需要解多元方程组,而且这些方程还不一定都是线性的。对于这种多元的非线性方程组,我们的直观感受就是很难解出。事实上,虽然存在一些可供编程的数值计算解法,但计算量大,且求出的是近似解,具有一定的局限性。
1.2 什么是梯度?
梯度的概念其实也不难,但为了让尽可能多的人明白这一概念,我们还是从一元函数开始吧。不过现在我们的目标是——用纯粹数值计算的方法,从函数上的某一点出发,找到函数的极值。这里我们只考察极小值。
1.2.1 一元函数找极值:从枚举试探法到梯度下降法
以函数为例,让我们看看如何找到极值。
向右走0.5,发现f(1.5) > f(1),说明这个方向是上升的方向,不应该选择这个方向;
向左走0.5,发现f(0.5) < f(1),说明这个方向是下降的方向,选择这个方向;
再向左走0.5,发现f(0) < f(0.5),说明这个方向是下降的方向,选择这个方向;
再向左走0.5,发现f(-0.5) > f(0),说明这个方向是上升的方向,不应该选择这个方向。
至此,我们可以将x = 0作为极小值点。
首先,选择一个方向 试着沿该方向走一小步,并据此判断该方向是否合理。如果合理,则走这一步;如果不合理,换一个方向 反复重复第二步,直到找到极小值点
第一,对于一元函数来说我们只有向左走或向右走两个选项。换句话说,每一步我们的选择是有限的,是可以枚举的。因此,这个方法我把它称之为枚举试探法。 第二,判断方向其实不必这样试错,直接求导就好。如果某点的导数值 > 0,说明在该点处函数是递增的,为了找到极小值,应该向左走;而如果导数值 < 0,则反之向右走即可。 第三,这种方法是不一定能找到极小值的,能不能找到极值点受选择的起始点以及 每次前进的步长这两个因素影响。
首先,求出某点的梯度 沿梯度的反方向移动一小步 反复进行第一、二步,直到找到极小值点
仍以函数,起始点x = 1为例,让我们看看如何用梯度找到极值。
初始x = 1, 步长step = 0.5
#在我们的例子里,梯度的计算式为2xi。i是指向x轴正向的单位向量
求x = 1处的梯度为2i,梯度反方向为-i #注意这里我们只关注梯度的方向,至于梯度的模长则不必在意
沿此方向走一步,x新 = x旧 + step * 负梯度方向上单位向量的坐标 = 1 + 0.5 * (-1) = 0.5
求x = 0.5处的梯度为1i,梯度反方向为-i
沿此方向再走一步,x新 = 0.5 - 0.5 * 1 = 0
求x = 0处的梯度为0,说明到达极值点
初始x = 1, 学习率step = 0.5
#在我们的例子里,梯度的计算式为2xi。i是指向x轴正向的单位向量
求x = 1处的梯度为2i,梯度反方向为-2i #注意这里我们既关注梯度的方向,也关注梯度的模长
沿此方向走一步,x新 = x旧 + step * 负梯度的坐标 = 1 + 0.5 * (-2) = 0
求x = 0处的梯度为0,说明到达极值点
还是函数,如果起始点选为0.4,而学习率仍为0.5,在采用单位化梯度向量的情形下,则无法找到事实上的极小值点
这次我们的函数变成了,起始点选择为(-5, -5),学习率仍设置为0.5。现在我们的目标是从这个点出发,找到该函数的极值点,我们知道这个极值点应该是(0, 0)。
首先,二元函数描述的是一个自变量和两个因变量之间的关系,也就是说函数的定义域是一个二维平面,我们要找的极值点就在这个二维平面上。 其次,由于是在二维平面上寻找极值点,我们每一步可以选择的方向不再局限于一维时的向左或向右,而是瞬间变成了无穷多个方向。因此,枚举试探法彻底宣告失效。还好我们有更智能的梯度下降法。 一元梯度定义式里的导数现在已经换成了多元函数的偏导数。
起始点坐标(-5,-5), 学习率step = 0.5
#在我们的例子里,梯度的计算式为2xi + 2yj。i和j分别是指向x轴正向和y轴正向的单位向量
求点(-5,-5)处的梯度为-10i-10j,负梯度为10i+10j,写成坐标形式就是(10,10)
在点(-5,-5)处沿此梯度走一步
根据公式 向量坐标 = 终点坐标 - 起点坐标,得终点坐标 = 起点坐标 + 向量坐标
这里,终点坐标是(x新, y新),起点坐标是(x旧, y旧) = (-5, -5)
向量坐标是负梯度坐标 = (10,10),再考虑学习率step,就可以得到
(x新, y新) = (-5,-5) + 0.5 * (10, 10) = (0, 0)
求(0, 0)处的梯度为零向量,说明到达极值点
梯度的计算公式为 梯度是一个向量,它总指向当前函数值增长最快的方向,而它的模长则是这个最快的增长率(导数)的值。 梯度下降法是一种通过数值计算求解函数极值点的方法 其过程概括来说就是顺着梯度的反方向一步步逼近可能的极值点 使用梯度下降法的理由在于求极值点的其他方法(如传统法、枚举试探法)不具有可计算性,无法编程实现 梯度下降法可以很方便的向多元函数推广,利于编写程序 记住在这个过程中,我们要找的是极值点(使函数取极值的那一组自变量),而不是具体的极值 梯度下降法的劣势在于不一定能找到全局最优解
二、人工神经网络(ANN)
2.1 神经元的数学模型
2.2 ANN是如何炼成的?
目标函数 | 损失函数 | |
---|---|---|
表现形式 | f | loss |
生成方式 | 事先搭好框架,再通过训练得出待定参数 | 将目标函数的输出与实际值作差得到框架,然后代入一个具体的训练样例(包括输入值与标签值) |
自变量 | ——神经网络的输入值(实际场合中可以是一张图片的所有像素值) | ——目标函数的待定参数 |
函数值(因变量)含义 | 属于不同分类的概率 | 预测值与实际值的差值(越小越好) |
特点 | 我们最终想要得到的函数,可以用来作图像分类。是线性函数与非线性函数的组合,规模很大,自变量与参数都很多 | 用来求出目标函数的过渡函数。非负,最小值为0,一般要使用梯度下降法找到极值点 |
举个例子看看函数变异的过程吧。设原函数为,这是一个关于的二元函数,其中a, b, c均是常数,也可以叫待定参数。现在我们给出一组具体的函数输入值比如,令把它们代入函数,并且将a, b, c视为变量,则函数变成了关于a, b, c的三元函数,记作。
这个ANN只有4个神经元,分别是。它输出两个目标函数,均是输入变量的函数,分别由神经元输出。可以记为
现在定义损失函数为
现在只要给出一个包含输入输出数据的训练样例,损失函数就成为不含未知参数的完全确定的函数。而我们要做的就是找到这个损失函数的极小值。
按照梯度下降算法的推导,此时我们只要按照下面的步骤就可以找出这个极小值:
随机指定一组初始参数 计算Loss函数关于各个参数的偏导数,注意这一步要代入参数的具体数值,也就是说这一步得到的是一个数 按照梯度下降的公式更新各个参数值直到满足一定条件为止
其中2、3里的内容是需要反复迭代的。
现在,我们以其中的几个参数为例,看看在调整过程中会遇到什么新问题。
这里,Loss函数依赖于变量,但与无关。回想多元函数求偏导数的规则,我们对求导时,应将视为常数。
而依赖于变量,因此这里应按照复合函数求导法则,即传说中的链式求导法则,先让Loss函数对变量求导,再令对求导,即:
其实从神经网络的图中可以很清楚的看出求导链。
这里有几个要点:
首先,式子的每一项均加下标w,表示要将具体的一组代入式子,得到一个数值 其次,当g(u)表示sigmoid函数时,对其求导的结果就是 函数对变量求偏导时,虽然也是函数,但它是关于自变量的函数,与无关,因此视为常数。这样,对求偏导的结果就是 等式右端最后得出的三项,在给出一个训练样例,并指定初始参数后,是可以独立计算出结果的
求出损失函数对的偏导数值,我们就可以按照梯度下降算法推导的公式,调整这个参数了!
现在,再来看看靠前的参数是怎么调整的,我们以和为例
还是老规矩,对照神经网络图,先写出它的依赖关系:
可以看出和,分别是函数和的变量,而函数均与和有关,所以Loss函数需要对均求偏导。
依然按照链式求导法则对求偏导,有:
对求偏导,有:
注意红框圈出来的部分是不是有些眼熟?