2.3 拟合、梯度下降与传播
2.3.1 过拟合和欠拟合
深度学习的训练和测试过程,与我们在学校里的学习非常类似:我们通常在学校学习知识,而深度学习是为了更新模型的权重(Weight)和偏移(Bias);我们有时候通过练习小测验来学习知识,深度学习通过训练集(Training Dataset)来学习这些权重和偏移;检验我们最终学习成果的方法就是期末考试,对于深度学习就是使用这些学习到的参数对测试集(Testing Dataset)检测;我们在学校学习的期末成绩越高,就代表我们的学习效果越好,对于深度学习,其学习效果的好坏叫作泛化(Generalization)能力,其泛化能力越好,表示其在测试集上的测试效果越好,而这里评价训练集上效果的好坏叫作训练误差(Training Error),评价测试集上效果的好坏叫作测试误差(Testing Error)。
学生在日常学习生活中,可能会遇到在做小测验的时候成绩不佳,可想而知,在期末考试的时候成绩也不理想。深度学习也有类似情况,深度学习在通过训练集学习参数时效果不佳(训练误差大),也就造成了模型在测试集上也不会取得较好的结果(测试误差大),我们把这种情况叫作欠拟合(Underfit)。
当然,在日常学习生活中,还会遇到另一种情况,在小测验之后我们已经学会了测验中的题目,但是在最终期末考试中还是没能取得好成绩。最简单的例子就是,小明同学背会了小测验的每道题的答案,但是期末考试时,题目中的数字改变了,小明还是不会做。类似地,对于深度学习,在训练集上误差较小,而在测试集上误差较大,我们把这种情况叫作过拟合(Overfit)。
也许有同学会发现,评价测试误差和训练误差只用大小来判断,难道没有客观量化的衡量标准?这里我们需要引入一个新的概念,即损失函数:
我们以预测房价为例,这里i表示房号,i=10表示第10套房子,yi表示第i套房子的实际价格,xi表示第i套房子的面积,f(xi)就是我们的预测价格。所以我们可以理解损失函数就是
这里的二次方项有些地方写为绝对值,其本质都是一样,只不过绝对值不方便计算机做求导运算,所以这也就说明了为什么有些损失函数前要加1/2,其原理也是为了二次方项求导后消除系数。
有了可以评价模型与真实值的客观标准——损失函数之后,我们再看看损失函数与过拟合和欠拟合的关系。如图2-7~图2-9所示,其中标有train的实线,表示训练时的损失函数,标有test的虚线表示测试时的损失函数,横坐标epochs表示迭代次数,纵坐标loss表示损失函数。图2-7中,训练误差略小于测试误差,基本拟合;图2-8中,训练误差和测试误差值都较大,表示模型学习效果较差;图2-9中,训练误差远小于测试误差值,表示模型只是“记住”训练所用的样本,并不具备泛化能力。
图2-7 正常拟合
图2-8 欠拟合
图2-9 过拟合
2.3.2 随机梯度下降
我们继续以拟合线性房价曲线为例,如图2-10所示,其中深灰色“×”表示样本,黑色实线表示真实房价的拟合曲线,浅灰色实线表示我们所拟合的房价模型曲线,损失函数的实际意义表示的是我们模型的曲线和实际房价曲线之间的相似程度,模型曲线越接近真实房价曲线,损失函数越低,反之,则损失函数越高。
图2-10 房屋面积与价格图
由于损失函数可以评价构建模型f(xi)与真实情况y的接近程度,假设真实房价的情况为yi,房屋面积为xi,与我们拟合的模型f(xi)的关系为
那么下一步就是让计算机如何调整参数w和b,以寻找最小的损失函数。这里就需要使用到著名的随机梯度下降法(Stochastic Gradient Descent):
式中,η为学习率;β为批量数;l为多批量的损失函数。需要说明的是w和b是不断更新的值,例如,使用初始化的w减去后,赋值给w,然后再使用更新后的w继续减去下一批量的,从而求得局部最优w。
我们应该如何理解随机梯度下降公式呢?
这里我们假设,损失函数为l=w2-3w+2,为了方便观察,我们把l替换为y,w替换为x,所以损失函数可写为y=x2-3x+2,我们就把求l的最小值,转换成了求y的最小值。回想一下中学时的知识,我们可知损失函数的图形如图2-11所示,导数为2x-3,令2x-3=0,求解x=1.5,所对应的y就是最小值。
可是计算机并不会求导数方程,那么计算机是如何求导数的呢?我们还是以y=f(x)=x2-3x+2为例,函数图如图2-11,当x=5时,y=12,f′(5)可由导数的定义求出:
图2-11 函数y=x2-3x+2的图
计算机可以给∇x赋值一个很小的值,例如∇x=0. 001,代入就可以求出y′=7. 001,其结果很接近求导公式的值,当∇x取一个更小值时,其误差可以忽略。
那么计算机又是如何求极小值的呢?
我们还是以y=x2-3x+2为例,由导数的特殊性可知,当x<1.5时,f′(x)<0,当x>1.5时,f′(x)>0,然后应用公式:x=x-ηf′(x),不断迭代x,即可求出x≈1.5。例如随机选取x=1,选取学习率η=0.01,f′(1)=-1,代入公式x=x-ηf′(x)=1-0.01×(-1)=1.01,x更新为x=1.01,发现x更接近于1.5了,然后继续代入更新后的x:x=x-ηf′(x)=1.01-0.01[2×(1.01)-3],再次更新为x=1.0198,更接近1.5了,不断重复,就会非常接近x=1.5。这里η的大小也就代表迭代一次更接近最小值的速率,所以也就明白了η为什么叫学习率(Learning Rate)了。我们把训练之前的自身设定的参数叫作超参数(Hyperparameter),这里的学习率就是超参数,需要说明的是并不是所有较小的η都可以“找到”局部最小值,我们只有调整参数η(简称调参)到合适值,才能求得局部最小值。
同理,,这里β表示一个小批量,例如β=10,所以这里也就表示,这10个批量的关于w求导的平均值,不断迭代更新,可以求得较小损失函数的w。
2.3.3 正向传播与反向传播
深度学习中经常会提到正向传播(Forward-propagation)和反向传播(Back-propagation),正向传播是数据从输入层到输出层正向地进行计算和存储等;反向传播刚好是从神经网络的输出层到输入层反向计算网络参数梯度。
为什么需要进行反向传播计算呢?
假设,我们现有方程q=zp,p=x+y合并得q=z(x+y),我们把能够表示数据输入输出的计算过程图叫作计算图(Computational Graph),所以方程q=z(x+y)的计算图如图2-12所示,这里我们把输入节点所在的层称为输入层(Input Layer),输出节点所在的层叫作输出层(Output Layer)。
图2-12 方程q=z(x+y)的计算图
假如我们要计算梯度,回想高等数学中的链式法则可知,,分析可知,在求梯度时,我们并不能直接求出,需要从输出层从后向前地先求出,再通过链式求导才能求出。例如,我们令x=1,y=2,z=3,正向传播可得p=3,q=9,反向传播可知,代入3×1=3。这里我们也就可以明白了,为什么有些书中所说的正向传播和反向传播是穿插交替进行的。同理,更复杂的模型也是如此进行的。
所以,反向传播就是由于链式求导法则,从而需要反向计算梯度。