1、得分函数

这里的线性函数就可以理解为得分函数。f(x,W)就是得分函数,其中f代表的是函数关系,x是指像素点,W是指像素点权重。这里输入的图片为32*32*3,表明像素点有3072个,每个像素点都对应着权重。

f(x,W)=Wx(+b)。其中x是指像素点,将其列为3720x1的矩阵。W是指每个像素点在每个分类类别的权重值,又称为权重参数,将其列为10x3720的矩阵,其中3720是因为每个像素点都对应这一个权重值,10是根据分类任务来分的,分类类别有10个这里就是10,像素点在每个类别都有对应的权重值,W是决定分类任务的关键。Wx相乘之后得到一个10x1的矩阵,也就是这张图片在每个类别的一个得分值。b是微调参数,是一个10x1的矩阵,对于计算出来该图像在每个类别的得分值进行微调,且每个类别的微调值可以不同。

这里简单的阐述了一下得分函数工作流程。首先是将这张图片分为4个像素点,也就是x是4

x1的矩阵,然后有三个类别,也就是W是3x4的矩阵,最后b是一个微调参数是3x1的矩阵。注意W矩阵里面有些权重值大,有些小,有些是正的,有些是负的,分别代表着些什么:权重值大是指该类别中对应像素点对于该类别输出结果的影响比较大,小就是影响小;权重值是正的表示在该类别中对应像素点对于输出结果有促进作用,负的就是有抑制作用。那么W这个权重矩阵哪里来的呢?是不断迭代更新优化而来的,最初W矩阵里面的值都是随机的,可见上图明明是一只猫,却在猫类别里面得分值最低,这就是权重值还没更新优化的结果,在深度学习中会通过训练集训练不断的更新权重值,直到达到临界条件(一般是损失函数的损失值很小接近于0才行)。

决策边界是由多组权重参数构成的,也就是不同类别的权重参数构成的,决策边界顾名思义就是边界线,每个边界线将属于自己类别的图像框进来,其中权重参数对决策边界的位置起到决定作用,微调参数起到微调作用。

2、损失函数

2.1 损失函数初步介绍

在了解得分函数之后,我们知道在深度学习过程中每经历一次训练就会得出每个类别的得分,有时候结果一点都不好,那么这个结果有多不好我们需要一个量的定义,这时候就引入了损失函数。有时候我们要完成不同的分类任务,在这个过程中,整个神经网络的框架是没有变化的,只是损失函数不同。

这里是一个比较常见的损失函数,其中Sj表示其他分类的得分值,Syi代表正确分类的得分值,利用Sj-Syi得到一个值,通过max函数(选择较大的一个数)在0和这个值之间选择最终的损失值,列如Sj-Syi为负说明正确分类的值要高一点,则损失值为0,至于为什么要加1,其实可以将这个1看作是一个容忍度,它可以自由调节的,也就是说Sj-Syi为负虽然正确分类的值要高一点但也存在着一定的误差,如果需要非常准确的结果,就可以将容忍度的值调高一点。然后是求和符号,这是因为有多个类别,要将不同类别的得分值与正确类别进行相减加上容忍度然后与0作比较取最大值后得出的损失值相加才是最终的损失值。

2.2 正则化

对于同一张图像损失值相同的两个神经网络模型一样吗?答案是不一样。这里f(x,W)是得分函数,L是损失函数。像素点值矩阵为x,类别为1个,W1是指第一个模型对于这张图象的权重值,W2是指第二个模型对于这张图象的权重值,两者的计算出来的类别得分一样,那么使用同一个损失函数会使损失值也一样,但是两个模型可以说是完全不同,第一个模型在于图像的局部(会出现过拟合),第二个模型则比较均匀,所以在两个模型损失值是一样的时候如何判断两个模型结构一样不?这时引入正则化。

为了区分损失值相同的两个模型,引入了正则化惩罚项。也就是说真正的损失函数等于数据损失加上正则化惩罚项。其中正则化惩罚项是指λR(W),可以看出只与权重参数有关,λ是一个数,其值越大就可以越大程度的防止过拟合。

上图是得出损失值的一整个流程图。首先x是像素点,W是权重参数,经过得分函数后得到一个得分再通过损失值计算函数计算数据损失值在通过加上正则化惩罚项得到最后的损失值。

3、softmax损失函数

softmax函数与sigmoid函数一样属于归一化函数,是sigmoid函数在多分类上面的推广。

之前我们通过得分函数可以得出图像在每个类别上的得分,但是在图像分类的任务当中我们通常不用得分来描述分类,而是利用概率来描述分类。 softmax函数就可以将图像最终的得分转换为图像在该类别上面的概率,softmax函数与sigmoid函数一样可以将任意的输入(-∞,+∞)进行归一化处理,输出值在0-1之间,而0-1之间正好是概率值。可以看到上面的公式

,根据该公式的图像就可以看出其归一化原理。

上图展示了softmax函数的一个工作流程。首先输入的图像是猫,然后经过得分函数后,可以看到猫类别、车类别、青蛙类别分别的得分是3.2、5.1、-1.7,可以看到正确类别得分3.2和错误类别得分5.1差距并不大,这里就需要对其进行放大操作,也就是exp操作(ex,x表示得分值),然后进行归一化处理,也就是将每个经过exp操作的值相加,然后将每个经过exp操作的值除以这个相加值就得到了一个概率值,再通过这个概率值来算损失值。这里的损失值是通过log函数(无论什么深度学习框架,pytorch或者是tensoflow都会要求写一个损失函数,一般都是利用这个log函数),由于在log函数中0-1都为负值,而概率值恰好是0-1,所以利用log函数求损失值的时候要加上一个负号,且概率值越接近1损失值越小,相反损失值越大。这些操作都对应这上面的公式,

是求得分的,

是根据得分求概率值的,

是求损失值的。

4、前向传播流程与反向传播计算方法

4.1反向传播的目的

上述的一系列操作,如得分函数,求概率,求损失值都是前向传播的一个过程,那么前面也讲过W权重值是需要不断更新的,W的更新就是通过反向传播来实现的,目的就是通过更新W来降低损失值。

4.2 梯度下降算法
4.2.1 简单的梯度下降例子

需要创建一条直线来回归拟合这三个点。

假设这条直线的公式为y=wx+b,其中w为定值,求最好的截距b的值。判断一条直线好不好,就是看这三个点到这条线的距离,再把这个距离误差写成最小二乘法的形式。

上图的公式是损失函数,将回归直线方程带入,可以得到一个以截距b和损失值L为未知量的二次方程。

因为是二次方程,且b一定为正值(根据三个点的位置可以看出),就可以画出二次方程的一个大概图像,根据初中的知识就可以算出最小损失值L对应的截距b的值,这就是b的最优值。

这里换一个思想,随便取一个b的值,然后通过迭代优化的方式,算出最小损失值L对应的最优截距值b。首先算出随机选取b点对应图像的斜率值,在定义一个值\varepsilon,更新b的值为

,可见更新完的b的值对应的损失值变小了。

再根据更新的b的值调节拟合函数的位置。

根据上述的步骤一直更新迭代b的值,直到达到L的最小值,该点的斜率为0,因此b不在更新达到了最优值。这就是梯度下降算法。

4.2.2 随机梯度下降算法

点不再是三个,而是很多个。函数不再是线性函数,而是非线性函数。这里需要求得y=f(xi,θ)里面θ的最优值。其损失函数是

,首先对θ求偏导

,相当于梯度值。在对其求均值

,该均值用来更新参数θ。利用公式

来更新θ(使θ沿着梯度的负向变化),其中Σ是指学习率,它可以控制梯度的步长。

根据这两个公式可以看出每迭代一次就需要计算所有样本的梯度值再求均值,这样会造成以下两个问题。首先是内存开销问题,因为每次都要计算所有样本的梯度值并保存计算结果。其次是迭代速度的问题,因为每次计算所有样本的梯度值才更新一次。

为解决这两个问题,每次只随机选取少量的样本。每次选取必须是随机的且不重复,这样的算法叫做随机梯度下降算法。

4.2.3 使用动量的随机梯度下降算法

随机梯度下降算法不是对于所有的情况都适用,如上图参数空间中存在着大量这样的山脊和山谷。

假设初始参数θ的值在黄点处,依照随机梯度算法,θ的值会沿着坡面向下移动。

如果梯度计算过大,就会导致参数运动轨迹幅度很大,造成震荡,而不能较好的收敛到一个比较合适的值。

为了解决震荡的问题引入了动量V,也就是参数在运动的过程中不仅要计算新的梯度方向,还要保持原始的运动方向,最终的移动方向是这两个方向的和。这里将原始的运动方向定义为动量v。

为了解决这一问题,在计算公式中也引入变量v,αv是原始方向,\varepsilon g是梯度下降方向。θ的更新变为θ+v。

4.2.4 学习率

在梯度下降算法过程中参数\varepsilon也很重要。在一个神经网络中,我们希望一开始就找到正确的收敛方向,因此会为\varepsilon设置一个比较大的值(因为θ的更新是与\varepsilon有关的,​​​​​​​​​​​​​​\varepsilon越大θ参数移动轨迹越大,越容易找到收敛方向),但是这也很容易因为移动轨迹大造成震荡而不能很好的收敛合适的位置。传统的方法是先设置一个​​​​​​​\varepsilon值,然后根据收敛情况手动调节​​​​​​​\varepsilon的值,但这样的人工方法是比较困难的。那么​​​​​​​\varepsilon的值是否可以根据梯度值自动调节呢?

为达到这一目标,引入参数r,r是梯度值计算随着时间增加的累积量。在学习率的分母加上r的根号值,这样可以使梯度值比较大的时候学习率可以快速下降下来,梯度较小的时候,学习率下降较缓,就不会出现震荡的情况。这里的\delta是一个很小的量,目的是为了使分母不为0,稳定计算的。

上述的r只与g有关,会使优化过程不好控制,这里加入参数ρ,ρ是一个可以手动调节的数,可以通过调节它控制优化过程。

4.2.5 使用动量的随机梯度算法与自适应学习率结合

s是自适应动量,r是自适应学习率参数。首先需要调整s和r的值,使其较大可以使算法较快的收敛。该算法的参数更新公式如图。

4.3 反向传播

需要对之前的知识进行两个强调,一是之前我们无论是计算得分、概率还是损失值时都只有一个权重矩阵,但是在真正的神经网络中有多个权重矩阵:W1、W2、……,每个权重矩阵侧重点都不一样,可能最开始是f(x,W1)=W1x,这个权重矩阵侧重的是图像中的主体,然后f(x,W1,W2)=W2W1x,而W2侧重的可能就是图像中的细微部分。这一点对于反向传播过程是有影响的,因为梯度下降算法中看得出来只对一个参数求了偏导(参数就是权重),但是如果出现了多个权重就要多次进行求偏导。如上图,f受到x、y、z的影响,因此f对于x、y、z求偏导可以看出每个参数对于f输出结果的影响程度,如果参数与f有直接关系就可直接求偏导,如z。但是如果没有直接有关系就需要多次求偏导,如x、y。

上图列举了反向传播的门单元,门单元可以看作是一种操作。首先加法门单元就是(x+y),那么进行梯度反向传播的时候,(x+y)求偏导都是1,也就是将梯度值均匀的分配给前面的神经元。其次是乘法门单元(x*y),进行梯度反向传播的时候,(x**y)求偏导都是对方,则相当于交换梯度值的感觉。最后是max门单元,也就是max(x,y)取x、y中比较大的一个数,进行梯度反向传播的时候是将梯度值传递给神经元得分值比较高1神经元。

4.4 链式法则

链式法则其实讲的就是反向传播过程中需要进行逐层求偏导,也就是前面将的f与x没有直接联系的话不可以对x直接求偏导,而是先对q求偏导,在对x求导。也可以理解为

,前向传播过程中,像素点x在经过W1、W2……一系列变化后得到损失值,在逐步的向前求偏导得梯度值来更新权重值。

5、 神经网络整体框架

神经网络的整体框架如上图。首先是层级结构,分为输入层、隐藏层和输出层,输入层相当于输入图像的像素点x,隐藏层相当于对像素点进行一列的变换(权重相乘,非线性变化),输出层相当于计算最后的损失值。神经元也就是这些圆圈,输入层的神经元就是提取的一系列特征(3个),第一个隐藏层的神经元相当于将输入的特征进行一系列的变换变为计算机可以识别的特征值(4个),例如输入层输入的特征是年龄、身高、体重,那么隐藏层就可以是对这三个特征进行加减乘除一系列的变换变为计算机可以识别的特征值,至于变为几个由神经网络模型决定。全连接指的就是每个相邻层之间的神经元都相互连接,首先看到输入层与第一个隐藏层之间的连线,这些连线就相当于是W1(第一个权重矩阵对像素点进行处理),输入层是1x3的矩阵,第一个隐藏层是1x4的矩阵,那么W1就是3x4的矩阵。其次看到第一个隐藏层和第二个隐藏层之间的连线,相当于W2(第二个权重矩阵,基于W1的处理结果上在进行处理),第一个隐藏层是1x4的矩阵,第二个隐藏层是1x4的矩阵,那么W2就是4x4的矩阵。最后看到第二个隐藏层与输出层之间的连线,相当于W3(第二三个权重矩阵,基于W2的处理结果上在进行处理得到输出结果),第二个隐藏层是1x4的矩阵,输出层是1x1的矩阵,因此W3是4x1的矩阵。非线性是指对于每个进行权重变化的结果都进行非线性处理,也就是x与W1相乘之后不会立即与W2相乘,而是先做一个非线性变化,也就是激活函数,例如sigmoid和softmax等等,将其结果做归一化处理,得到概率值。

上图就对非线性变化做出了解释,这里选择的激活函数是max函数,在得到W1x结果后不立即与W2相乘,而是进行非线性max处理之后在于W2相乘。

6、神经元个数对于结果的影响

神经元的个数对于结果是什么影响,是多一点好,还是少一点好?神经元的个数过多会产生过拟合现象,但是对于该数据集的训练结果会更好,另外神经元个数过多的话会增加迭代时间。上述网址(ConvNetJS demo: Classify toy 2D data)是复旦大学做的一个可视化神经网络的网站。

进入网站后首先可以看到神经网络的设置,里面包括输入层、隐藏层、输出层、神经元个数、激活函数等一系列设置,其中num_neurons就是隐藏层神经元的个数,可以通过调整神经元的个数看一看对结果有什么影响。

如上图,左边是分类结果图,右边是权重图,根据不断调节神经元个数,对于简单的数据来说少量的神经元就可以较好的分类,但是数据越复杂神经元的个数需要越多才能有较好的结果。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐