李飞飞计算机视觉笔记(4)--神经网络训练细节part1

这里说明一下,因为这个视频是2016年的,可能现在有些东西已经变化。
我们将用到以下和方差相关的定理:
假设有随机变量x和w,它们都服从均值为0,方差为σ的分布,且独立同分布,那么:
• w*x就会服从均值为0,方差为σ*σ的分布
• w*x+w*x就会服从均值为0,方差为2*σ*σ的分布

是否我们应该需要大量的数据集对模型进行训练?

这种认识是错误的,我们一般很少直接对卷积神经网络进行训练,通常会先在大数据集如ImageNet中进行预训练,然后将训练好的卷积神经网络提取出来,去除分类层即softmax层,然后加一层新的分类层,在我们自己的数据集上进行训练。如果我们的数据集很小,那么我们可以只训练softmax层;如果我们的数据集处于中等量,那么我们可以在老的权值基础上进行微调(finetune),我们的训练深度可以达到更深的位置,甚至可以反向传播整个网络,当然不管深度如何,都是从最后一层开始反向传播的。过程如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第1张图片
所以综上所述,没有大量的数据集也是可行的,我们可以找一个预训练好的卷积神经网络,然后在这个基础之上,用我们自己的数据集进行训练微调。

神经网络历史

在1960年左右,做出了一个类似于神经网络的机器,没错就是硬件,是神经网络在硬件上的实现,它计算的是 f = w x + b f=wx+b f=wx+b,就是一个感知机(就是一个二分类的线性分类器,因为处理的是二分类问题,所以最后一层只有一个神经元,数据必须是线性可分的,计算图如下图所示),使用的激活函数是阶梯函数,不能求微分,使用一种特殊的方法更新权值。
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第2张图片
这个时候反向传播算法还没有提出来,1960年提出了适应性神经元,他们将感知机整合成多层感知机网络,但同样是硬件实现,这时候有了程序设计的概念,这是第一次人们想到数据驱动的方法,某种意义上说这个机器具有了学习的能力,这是一个巨大的概念性的飞跃,但性能并不好。由于这些发明者对这个机器的乐观,70年代神经网络几乎没有进展。1986年一篇很有影响力的论文用清晰的公式很好地阐述了反向传播概念,这是第一次在论文中找到像是反向传播算法的描述,他们摒弃采用特定规则的更新法则,而是讨论了梯度,提出了损失函数公式,但是当他们试着加深这个层数时,这个神经网络的工作效果相比其他的机器学习工具包更加弱,那个时候没有得到一个好的结果,网络训练受阻,反向传播算法的效果也不是很好,那时候的计算机性能也比较差,难以承担如此大的计算量,数据也匮乏。后几年就没有过多的研究,到了2006年,第一次建立了神经网络模型,提出了逐层预训练,然后将所有层整合起来进行反向传播和微调的思想,事实上确实可以不需要预训练,直接使用反向传播,但一定要注意初始化的问题。这个时候人们已经可以对神经网络进行训练了。在2010年人们开始注意这个领域,研究出了很多重要的成果,例如在语音识别方面,将神经网络应用在了GMM-HMM语音识别模型中,其中一部分改成了神经网络中的一些东西,很好的改善了结果。在2012年机器视觉的图像识别领域,由Alex Krizhevsky等人实现的网络碾压了所有此类比赛的其他选手,这对于神经网络来说是一个很大的进步,从这个时候开始,很多人开始关注神经网络,并出现了很多的分支。

激活函数(Activation Functions)

sigmoid激活函数

它的公式如下图
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第3张图片
这里有一些关于sigmoid激活函数存在的问题:

1.梯度消失

如果使用sigmoid激活函数,某一些神经元的输出值趋近于0或者1时,这个时候求导从图中可见几乎等于0,所以在反向传播过程中会出现梯度趋0的情况,这中现象叫做梯度弥散(消失)。从以下图中可以看出这个问题,当输入值为-10时就会存在梯度消失。
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第4张图片
那么梯度消失会带来什么样的影响呢?如上图,当x输入值为-10时,当梯度传到这里时乘上局部梯度得到的梯度变小了,如果这个神经元是饱和的,即输出值为0或1,那么梯度的后向传播将在这里终止掉,因为梯度变为了0,没办法再往后面传播,而非饱和的神经元区域我们叫他sigmoid的激活区域。当一个大的神经网络都是处在饱和区域时,那么使用梯度将没办法进行后向传播,因为梯度的传播很快会被0所终止掉。

2.sigmoid函数的输出值不是关于原点中心对称的

助教的解释有点绕感觉,我的理解是从上面sigmoid函数的图像可以得知,他的取值范围为(0,1),也就是说下一层神经元的输入全是正数,又因为这一层链接下一层的参数的梯度等于这一层的输出乘上下一层神经元中sigmoid函数的x对于L的梯度,那么中间的所有层的参数(不包括神经网络输入层与第一层的参数)的梯度都要么是正数要么是负数,这样对权值的更新方向从一定程度上进行了限制,这样可能会引起收敛速度减慢。收敛速度是与激活函数的选取有关的,我们可以把整个神经网络写成一个数学表达式,再以这个表达式为基础写出损失函数表达式,损失函数表达式中就会有激活函数,我们把W看成是未知变量,根据训练数据求这个函数的最小值对应的W的值,W的最优值的求取速度肯定是和损失函数有关的,毕竟不同的函数它的斜率是不一样的,下降速度也不一样。
通过说明这个缺点,是想告诉我们,关于原点中心对称的输入和关于原点中心对称的输出能够使得模型收敛得更好。

3.关于x的计算非常耗时

相比于其他函数,关于x的计算在一定程度上耗费一点时间,这对于其他激活函数,这是它的缺点,但是对于大型的卷积神经网络,大部分时间是耗费在了卷积和点乘,这个激活函数的指数运算不是主要的耗时部位。

tanh激活函数

tanh函数的形式如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第5张图片
从图中可见tanh函数的输出在(-1,1)之间,这很好地解决了sigmoid函数输出值不关于原点中心对称的问题,但是它还是没有解决梯度消失的问题,依然存在饱和问题。从这里来说tanh比sigmoid的问题还少一个,可以说tanh比sigmoid更优。

ReLU损失函数

在2012年第一篇关于卷积神经网络的论文中指出使用非线性函数ReLU可以使得你的网络收敛得更快,这是ReLU第一次被提出,工作得非常好,达到了之前的6倍速度。函数图像如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第6张图片
函数形式: f ( x ) = m a x ( 0 , x ) f(x)=max(0,x) f(x)=max(0,x)
这个函数很明显是不会饱和的,至少在图的右半区域内梯度是不会变为0的;而且它的计算效率也是非常高效的比起上面两种激活函数,它的英文全称是Rectified linear unit(修正线性单元)。ReLU是基本默认使用的函数。但是他也有一定的问题,它的输出不是关于原点中心对称的,还有一点比较烦人的地方是如果输入全为负数,那么会出现梯度消失的情况,这种情况是梯度完全消失,不会有任何更新,比起上面两种要糟糕一些,如果为正,那么梯度为1,所以要么直接向前传递梯度,要么直接杀死梯度。对于是输入为0这一情况,其实不用太在意,因为这种情况很少见,你就当梯度不存在就行了。还有一个问题,我们知道了当输入值小于0时神经元的输出为0,且反向传播的局部梯度也为0,从而出现梯度消失,因为这个缺点,所以ReLU网络训练时会非常脆弱,一不小心ReLU神经元就会死掉,即发生梯度消失,举一个例子,当一个很大的梯度经过神经元更新过参数后,参数被大幅度更改,可能就变为了很小的负数,这个神经元前向传播的结果可能就为0,这个神经元就死掉了,这个神经元可能再也不会对任何数据有激活现象,如果这个情况发生,那么这个神经元的梯度将永远为0。这个问题会在两种情况下发生,第一就是初始化神经网络的时候对权值设置的不合理,刚开始训练时就死掉了;第二就是学习率过高,当学习率过高,我们知道参数的改变幅度就会很大,可能导致参数为很小的负数,最后可能40%的神经元都会死掉,我们可以设置适当的较小的学习率,使得传递过来的大梯度变成小梯度,参数不会改变太大,这个问题发生的情况也不会太频繁。有一些人会将bias设置为一个接近于0的正数而不是直接设置为0,如0.01,这样可以避免算出的结果为负数,从而避免前向传播的结果为0以及梯度为0,他们认为这样可以在初始时减少神经元死掉的可能性,但有一些人认为这个的效果没有多大。

Leaky ReLU激活函数

函数的形式如下
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第7张图片
其中的0.01其实是可以任意数的,不是规定的0.01。这个函数就不存在梯度消失、饱和的情况了,保留了ReLU的效率,相比ReLU,左半部分有了梯度,虽然很小,但不至于为0。一些人的研究表明这个激活函数的效果确实要好一点,不会再有神经元死亡的现象。右下角的函数被称为参数校正器或叫做PReLU,其中的 α \alpha α作为网络中的一个参数,我们可以通过后向传播学习它,每一个神经元有独立的 α \alpha α,就像这些神经元有他们自己的bias一样。我感觉这个参数给一个固定值也是可以的不用训练。

ELU(Exponential Linear Units 指数线性单元)

李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第8张图片
它继承了ReLU的所有优点,类似于Leaky ReLU,不存在神经元的死亡,因为左半部分不为0,输出是接近于0均值的即可以认为在某个角度上输出关于原点中心对称。这个函数到底好不好还没有定论(2016时)。其实按照上面ReLU部分说的,你只要小心地使用ReLU(控制学习率等),这是个很好的选择。

Maxout Neuron

李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第9张图片
上面的神经元是由Goodfellow提出来的,在有一些神经网络中可以看见它。它与一般的神经元的区别不仅在于损失函数,而且神经元的计算方式和计算的变量也有很大的差别,他有两组权重,两组权重与x相乘加上偏移量然后取最大值,它没有ReLU中是缺点,不会出现神经元的死亡,仍然高效率、分段线性,它的缺点也很明显是参数是原来的两倍,虽然有人在用它,但是不是很普遍,其实目前(2016年)ReLU是应用最广泛的。

激活函数总结和一些问题

不同的激活函数最终会使你得到不同的权值,这个与上面说的收敛效率是类似的。不要去使用sigmoid函数,tanh都比他好,使用它的情况很少,时间递归神经网络会用到它,后面会讲到这个特殊原因,而且应用方式也和我们之前的不一样。

数据预处理

李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第10张图片
先进行原点中心化,然后进行归一化,这类归一化的方法有很多,但在图像中我们一般不会进行归一化,而是经常进行零中心化。这里讲到了PCA算法,可以看看我的数学建模的文章,也可以不用看,因为这些在图像处理中并没有应用,尽管在机器学习中很常见。
在图像处理中最常见的是均值中心化处理,处理方法如下图PPT所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第11张图片
其中3表示通道,可以简单理解为红绿蓝。每张图像减去均值图像,这样的预处理能够获得更好的训练效果。下面的是另一种比较好的预处理,对通道进行,最后得到3个数,在VGGNet(一种卷积神经网络)是用这种方式进行处理的,这种方法更加简单,因为你只需要记住三个值就行了,第一种需要记住一张均值图片。

权值初始化

初始化权值很重要,在早些时候神经网络效果并不好就是因为权值的初始化没有得到重视。当我们对所有权值设为0后,神经网络会怎么样呢?我没听懂助教说的,找了网上有些说是权值会不管训练多少次都会一样,这很明显是错误的,就算是激活函数没有问题,如果输入层的输入之间不相等,输入层到第一个隐藏层的权值也会不一样,其实这个问题也很简单,了解了前向后向原理,自己画一个神经网络,思考一下就很明显了,比如我们使用的是单层的感知机,即只有输入层和输出层,这个时候激活函数选得对(如tanh,tanh在输入值为0时是有梯度的)那么也不会有任何问题,如果使用的激活函数为ReLU,这时就会出现全部的神经元都是死的,不管有多少的隐藏层,所有层的神经元全是死掉的,梯度全为0,下一次的输出同样是这样,陷入死循环,神经网络参数没有一点改变,依然为全0,就算使用sigmoid或者tanh在0处的梯度不为0,那么第一次BP时中间层神经网络的参数也是一致的,虽然如果输入之间不相等的话,后面可能参数会变为不相等,但这也不是我们所希望的,初始化为0,不是最好的方式。人们一般是选取小的随机的数值作为初始参数值,如下图实现
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第12张图片
上图是使用均值为0标准差为0.01的高斯分布随机值乘上0.01进行的初始化。对于层数较少的神经网络来说,这没什么问题,但是层数越高那么模型对初始化更为敏感,因为上面的初始化方法是非常简单的,可能就不适用。
我们使用上图所示的初始化方法,初始化一个10层的神经网络,每一层500个神经元,用tanh激活函数,我们将所有数据通过神经网络,观察每一层神经元的输出的均值和标准差,以及反向传播时的梯度,实验结果如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第13张图片
从上图可见,起始时数据的均值为0,标准差为1.0,因为激活函数是关于原点对称,权值的均值也是0,所以从第一层隐藏层开始,所有的隐藏层的输出均值均为0左右,但是标准差从开始的0.2到最后的0,每一层的标准差逐渐下降直到为0,从下面的柱状图可以看见,刚开始数据分布在-1到1之间,慢慢地数据分布开始收缩,最后收缩到只有0,所以使用这种初始化方法,最后面的层的输出将变为0,可以这样理解,我们的权值初始化为很小的正数,而且对输入数据进行了中性化处理,在传播过程中,因为权值很小,所以神经元的输出也很小,这样逐步累计,就变为近0的数。那么在反向传播时会发生什么呢?因为我们某一层给下一层的输入很小,所以这之间的梯度就会很小,梯度的大小等于输入乘上后面层传过来的梯度,从某一个损失函数开始,我们进行反向传播,不断乘上神经元的输入,在传递过程中,因输入很小,所以最终的梯度几乎为0,即发生梯度消失,在后向传播过程中,梯度量级逐步减小。如果我们将权值初始化时的系数0.01改为1.0,结果如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第14张图片
这种情况就是参数“走过头了”,因为权值很大,所以激活函数的输出要么为接近-1、要么为接近1,几乎所有的神经元都处于饱和状态,在反向传播中,梯度在任何地方几乎为0,权值不会有什么变化,这样就一直持续,当你训练了很多轮后,你会发现模型的损失值没有多大的改变,这个模型训练是失败的。
在2010年Glorot提出了Xavier初始化方法,Xavier从方差的角度来考虑初始化权值,并使用均匀分布来为权值进行初始化,它希望每一层的数据输出方差是相等的,它同时希望反向传播时每一层的梯度的方差是相等的,这样就不会出现参数设置过小出现梯度消失的情况(输出方差等于整个神经网络的输入时的方差,一般处理后为1),但它是“理论性”的东西,它只考虑了线性激活函数,即可以认为只有加权和,实际中我们使用的是非线性激活函数,效果和理论有点差别,但在tanh激活函数上表现还是很不错的,结果如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第15张图片
np.random.randn(fan_in,fan_out)表示从标准正态分布返回一个fan_in*fan_out大小的数组(PS:上面的初始化代码就是Xavier初始化实现,上图应该只是考虑了前向没有考虑后向,这个实现方法和我们从我下面给出的Xavier实现方法有点不一样,但是思路还是Xavier的思路,W的分子是一个标准正态分布,方差为1,均值为0,我们通过 ( ( W 1 − W ‾ ) 2 + . . . + ( W n − W ‾ ) 2 ) / n ((W_1-\overline{W})^2+...+(W_n-\overline{W})^2)/n ((W1W)2+...+(WnW)2)/n公式得到某一层W的方差为1/fan_in,满足Xavier初始化( W ‾ \overline{W} W为0)。下面我给出的链接使用了均匀分布对W初始化,所以助教使用的只是考虑了前向方差,没有考虑梯度方差,助教使用了标准正态分布,而没有使用均匀分布)。我们从图中可以看见最后一层的方差没有变为0,可见效果还是不错的,比如第一层出现下凹,这是因为论文并没有考虑tanh的非线性性,所以出现如上图的结果,这将影响数据的方差。虽然在tanh上表现很不错,但是当使用ReLU激活函数时,就没有那么好了,结果如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第16张图片
从图中可以看见方差随着层数的深入下降很快,到最后基本就为0了,后面的神经元好多都处于未激活状态,即死掉了,造成这个问题的原因是因为什么呢?论文中并没有讨论ReLU激活函数,它是当做线性激活函数进行处理的,如果我们使用高斯分布的数据输入时,方差为1,那么加权和的结果应该是方差为1,均值为0,也就是保持输入时的数据分布,这样将这个加权和结果通过ReLU激活函数得到的数值的方差会减半,因为有一半的输出变为了0,这样的方差将呈现指数型衰减。那么如何针对ReLU激活函数进行改进初始化方法呢?如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第17张图片
当我们使用了ReLU那么就不能保证每一层的输出的均值为0了,从上面两个图都能看出来。从上图中我们可以看见初始化实现改变了,相当于权值方差扩大了两倍,那么这样就可以避免使用ReLU出现方差减半的情况了。这样使用了这种方法,我们可以看见每一层的方差基本在0.8左右,对ReLU的效果不错。如果不使用2因数,那么可能神经网络不能收敛,或者很难收敛。所以,初始化是很重要的一个环节,需要仔细思考,特别是使用ReLU时,使用上面的方法是合理的。关于Xavier的推导和更多细节可以参看最下面我给出的链接。
有很多研究初始化方法的论文,使用何种初始化方法是数据驱动的,你可以让一组数据通过网络,然后观察是否每一层符合你的预期,如果不,那就不断调整初始权值,知道每一层的方差符合预期,初始化技术基本就是一项数据驱动的技术,并有一定的规则。一些有趣的初始化论文如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第18张图片

Batch Normalization

Batch Normalization是通过在非线性激活函数前,线性计算(wx+b)后在一个mini-batch上进行标准化处理激活值,使得激活值的输入满足均值为0,方差为1的分布,然后再用 γ \gamma γ β \beta β两个可学习的参数对上面处理后的激活值做进一步处理。过程和神经网络新结构如下
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第19张图片
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第20张图片
最后一步即scale and shift的作用我认为有两方面,第一就是当 γ \gamma γ β \beta β取某一个值时可以将激活值还原为wx+b,如下图(一般会对Var加上一个小的数,以防分母为0)
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第21张图片
这样模型可以根据学习到的参数决定是否还原,因为我们并不知道到底加入的BN处理是否很好,不清楚模型是否需要这个BN算法,也许模型就希望饱和一点;第二就是如果我们只进行标准化,得到均值为0,方差为1的数据,根据正态分布,那么95%的数值将位于[-2,2]之间,而这段区间对于激活函数sigmoid来说,相当于一个线性区域,我们知道多层的线性激活函数神经网络与单层的线性激活函数神经网络效果是一样的,这样我们进行BN处理后,模型的表达能力变弱了,所以需要一个scale和shift让激活值所在的区域向非线性区域走一点。因为有了 β \beta β参数,它可以将bias进行合并,所以我们就不需要bias了。对于全连接神经网络来说,每一个神经元有一个 β \beta β γ \gamma γ参数需要进行学习,卷积层因为有相同权值问题,可能会有相应处理,这个后面实现时再说吧,学习的方法依然是用链式求导法则,如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第22张图片
因为训练过程中有mini-batch,但是测试时并没有,只有单个实例,这种情况下,我们可以将所有训练数据通过神经网络记下所有数据的方差与均值(一般不这么用),或者我们也可以在训练时记下每一个mini-batch的均值和方差,然后对这些均值和方差进行如下处理来估计实例的均值和方差
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第23张图片
使用BN算法可以增强模型的鲁棒性,就像论文的标题一样
《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》可以减小分布不一致带来的问题。BN算法还使得模型收敛速度快、可以使用更高的学习率、不用太关注权值的初始化、有正则化和dropout的作用即提高模型的泛化程度。我们刚开始可以设置初始值为 γ = 1 \gamma=1 γ=1 β = 0 \beta=0 β=0,然后不断调整学习。因为有了标准化就不会存在刚开始训练时输入爆炸即很大很大导致梯度很大或出现输出饱和导致梯度消失的情况。
它的优点有如下
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第24张图片
它能够适应更多的初始化权值,当你未使用BN时有一些初始化导致模型训练失败,而可能使用BN后就不会存在这个问题。就如同上面提到的,它能够减少对dropout的需要,以独特的方式实现正则化,dropout就是随机让神经网络中的输出值为0,以此来使得模型泛化能力提升。可以这样理解提升正则化,助教给的解释是,正常情况下,批数据间独立并行通过神经网络,因为BN会将神经元的输入包含一个批数据的所有数据,所以输入的是关于这个批数据的一个方程,这样仿佛考虑了更多的数据,效果更好,比较直观的理解,可以自己写一个代码打印一下输出看一看。
使用BN可能会使得训练、运行时间延长30%左右。因为在全连接层、卷积层增加了操作层BN。

训练过程

首先我们预处理数据就是上面提到的预处理方法,对CIFAR10数据集减均值除标准差,构造一个包含50个隐藏层神经元的两层神经网络,结构如下
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第25张图片
我们需要尝试的第一件事是我们先取消正则化,我们使用softmax损失函数,得到的关于模型正确分类的损失值为如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第26张图片
上面的结果也是合理的,因为刚开始的初始化并不知道任何事情,第二步骤中我们加上正则化后损失值结果应该增大,结果也确实如此,如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第27张图片
这样我们就检查完了,接下来进行完整性检查,代码和过程描述如下
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第28张图片
我们尝试对训练集中很小的一部分进行训练,我们期望模型的正确率几乎为100%即产生过拟合,如果得到这样的结果那么我们就能确定我们的反向传播正常工作、更新正常工作、学习速率也设定得合理。然后开始考虑扩大训练集。取的小的数据集不用很大,但是我觉得也不能取一两个,这样可能存在偶然性,这个过程会很快的,是一种检查完整性很好的方法。如果得到的模型不是过拟合那么你在实现时可能存在一定的问题。所以我们应该在扩大训练集前进行检查。
然后我们开始在一个稍微大一点的数据集上求得好的学习率,如果使用全部数据集那么太慢了,所以我们需要折中选一个稍微大一点的数据集。学习率的大小不能通过肉眼看出来,我们需要通过模型训练去尝试,首先我们使用小的学习率1e-6,结果如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第29张图片
从图中我们可以看见损失值非常非常小的往下减少,所以这个学习率太小了,也有可能是其他的问题,因为损失函数出问题的原因有很多种,因为我们之前已经经历过了完整性检查,那么应该就是学习率太小了,我们需要加大它。这里有一个很有趣的事情就是,我们的正确率从10%变为了20%,但是我们的损失值基本没有变化这是为什么呢?我们可以考虑准确度的计算方法和损失值的计算方法的差别就应该知道了,也就是说他们的计算方法有差异,两个之间没有可比性。如果我们将学习率设置为1e6时,结果如下
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第30张图片
损失值直接爆炸了。我们接下来就把学习率限制在一个范围内,如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第31张图片
这样不断缩短区间,逐渐找到好的学习率。

超参数优化

这一部分我们目的是找最好的超参数,包括正则化参数和学习率,我们会用粗糙到精细化的思想,采用交叉验证法。首先我们只需要有一个大概的参数区间,然后第二步就是在原有的区间内选出表现比较好的一个小区间,然后我们重复这个步骤,不断缩短区间,最后选出一个表现最好的参数。在代码中,我们会先设置一个循环,在每次循环时先对正则化参数和学习率进行取样,然后进行训练,再用验证集对结果进行验证得到模型在验证集上的正确率,代码和结果如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第32张图片
通过上面的结果我们就可以知道在哪个范围可以得到好的超参数,我们只需要尝试很少一部分的参数就可以得到参数性能比较好的范围,只需要几分钟时间。还需要注意的是我们在优化学习率和正则化系数的时候,我们需要从对数空间中进行取样(即10的多少次方),因为0、1、100等这些数值,一般这些数值都是位于不好的区域内。
现在我们做第二步搜索,我们会基于第一次搜索得到的结果进行进一步搜索,第一步的结果是正确率较高的区间,第二步结果如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第33张图片
下面是我对上面的理解,有错欢迎大家来喷。在第二步骤中我们希望得到最终的结果了,我们从中可以看到最好的值为53.1%,但是这个正确率对应的学习率可能并不是全局最优的,因为还有一个正确率为53.0%的正确率对应的学习率,最优的学习率可能在其他区间,所以我们不能取它,我们可以在其他区间找一找看一下有没有更好的学习率,从而确定这个学习率是不是最优的,比如我们可以在-2~-3区间或者-2.5~-3再找一下。
下面我们讨论一下随机搜索和网格搜索的区别和优缺点。如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第34张图片
左边为网格搜索,右边为随机搜索。绿色的区域代表了不同的参数值的效果,“坡顶”对应的参数效果最好。我们在优化超参数的时候一般会有重要的超参数和不太重要的超参数,重要与否可以根据这些参数的不同取值对最终结果造成的影响程度而定,比如上图我们把垂直方向定为不太重要超参数,可以看见垂直方向的绿色区域非常的矮小。从上图中我们可以看见在某一范围内横向的超参数在某一个区域有最好的效果,但是在网格搜索中取不到,而我们在随机搜索中取到了那个最优值,所以说一般情况随机搜索效果更好,所以我们一般都是使用随机搜索。
我们可以在实际中使用多台机器并行运行不同的参数样本,得到比较好的参数后,我们给机器发送指令,告诉机器这些参数值比较好,然后改变区间再次运行,最后我们得到一组性能优异的参数样本,因为我们需要确定一些超参数的最优值,所以还是需要花费一点时间。
下面说了我们要学会看损失函数图,便于去发现训练过程中的问题,这里助教给了一个例子,损失函数最后画出来有点像线性的,而不是像指数形式那样,先减小的很快,然后慢慢放缓,这里可能的原因是学习率太小了,可以尝试增大学习率试试。
我们在训练时可能出现如下图所示的现象
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第35张图片
刚开始损失值没有什么变化而后某一时刻突然下降,造成这个问题的主要原因是初始化出了问题,刚开始的时候因为初始化问题导致了梯度几乎为0,损失值没有什么变化,当运动到某一个时刻的时候梯度有了明显变化,这个时候损失值开始有了明显变化。
强化学习解决的问题是不稳定的数据集,在强化学习中,我们的客户端是在不停的与环境进行数据交换的,如果我们的学习方针发生了变化,数据分布发生变化,损失函数会突然变高,因为客户端接收到了和以前完全不同的数据。
我们在训练时还要关注正确率,因为正确率可以给我们损失函数值所不具有的含义,比如如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第36张图片
如果我们发现我们的正确率在训练集上越来越高而在验证集上没什么变化的时候,可能就是过拟合了,接下来可能就会尝试提高正则化系数。
关于更新过程中权值的增量的衡量,如下图所示
李飞飞计算机视觉笔记(4)--神经网络训练细节part1_第37张图片
我们比较理想的情况是增量比上权值大小等于1e-3是比较好的,也就是千分之一,如果大了我们考虑减小学习率,如果小了我们考虑增大学习率。

总结

上面我们提到了图像的初始化就是减去均值,对于小的网络来说,我们可以不使用Xavier来进行初始化,我们可以选择一个很小的数作为初始权值,比如0.01,深层网络考虑Xavier。然后一般都要用到批标准化处理。

参考资料(这里包括延伸出来的一些知识点)

TF-IDF统计方法;
Xavier初始化方法链接1;
Xavier初始化方法链接2上;
Xavier初始化方法链接2下;
协方差;
从机器学习角度直观理解特征向量特征值的作用;
关于对称矩阵的特征向量和特征值的性质;
比较好、详细的PCA算法原理讲解,其中的一些细节地方,作者没有指出来,比如最后作者推出了数据的协方差矩阵的特征值是表达特征向量的重要性(特征值可以看做是对投影后数据的方差大小的度量,如果进行过中心化处理,特征值大小等于所有数据在这个投影上的方差乘上样本数),而特征向量表达的是拥有最大投影方差的方向(方差越大越好,便于区分),但是作者没有明显指出 X X T XX^T XXT其实就是数据的协方差矩阵。作者详细解释了为什么协方差矩阵最大特征值对应的特征向量就是最优投影方向,而特征值能够反应特征向量的重要程度。;
白化处理;
ZCA白化的处理(ZCA处理得到的结果比PCA白化处理的结果更加接近原始数据),作为拓展,以后有时间再看吧!既然这里用不到就暂时不看。;
Batch Normalization详解1;
Batch Normalization详解2;

你可能感兴趣的:(机器学习,计算机视觉,计算机视觉课程笔记,李飞飞,计算机视觉,神经网络训练细节)