深度学习秘籍
我们都知道深度学习分下图红框中的3步,然后我就就形成了自己的神经网络,我们就直接拿去测试集上实验吗,不,我们先要保证在训练集上有比较好的效果,否则训练集误差都比较大,那就说明之前的步骤有问题,导致整体有偏差,我们需要修改直到我们在训练集上有比较满意的结果,然后我们才可以在测试集测试,如果测试集上是比较好的效果,那我们的模型训练至此结束,如果不行,那就是训练集好测试集不好,就是过拟合了,我们就需要从头开始从新考虑模型的创建,创建完毕后还是需要先考虑训练集,直至训练集和测试集双优。
我们能把所有错误都归于过拟合吗,比如上图中我们没有看训练集准确率,直接看测试集结果,我们可能觉得测试集效果不好就是过拟合,这是不准确的,我们先看下图右,56层的神经网络比20层的神经网络在相同迭代次数,错误率高,但实际我们去观察训练集错误率,56层就已经比20层错误率高了,有人会把这叫做欠拟合,这是不准确的,一般的欠拟合是参数少导致拟合不准确,56层比20层多36层,参数多,完全可以后36层什么都不干,可能是因为学习率或者其他问题,导致停留在了局部最低点。
我们对应训练集和测试集的好坏都有具体的解决方法,先分析训练集的数据差可能的原因
我们首先考虑的就是激活函数我们一直在用的就是sigmoid函数,下图中我们使用神经元数量和准确率的关系,也许有人就会说,哇,你这是层数多过拟合了,但是请仔细看好,这是训练集上的数据,为什么这样呢,我们来分析
我们这种情况训练时,常常是训练着就发现靠近输入端的w梯度很小,学习很慢,相对的,靠近输出的w就梯度较大,学习较快,很容易就到了局部的最小点
因为我们使用了sigmoid函数(只分布在0,1之间),函数本身会使w得变化对后级影响小,随着层数增加越来越小,这就是原因。
我们发现sigmoid有不好用的地方,于是就有了relu激活函数,relu的特性是输入≥0,输出就是输入,输入<0,输出就是0。
我们选用relu有什么优点呢:
1便于计算
2有些生物上的仿生技术
3一个relu函数等同于无穷多个不同偏置的sigmoid函数叠加
4我们可以解决梯度消失的问题
我们知道relu的函数特性,当输入大于0,输出就是输入,当输入小于0,输出就是0,下图中有0的神经元的情况下,我们其实就可以将这个神经元拿掉
我们把0输出的神经元拿掉,剩下的其实就是线性的神经元,整个模型就变成了瘦的线性的网络,我们w的改变就不会因为层级的问题而对输出影响越来越小。
老师提了一个问题,如果我们模型是个线性的模型,而我们本来想用的是非线性的复杂模型,这不就无法达到我们的效果了吗,其实我们的神经网络还是个非线性模型,比如一个样本特征输入可能导致部分工作的模型实现线性模型,但是另一个样本经过神经网络可能开启(输出大于0)新的神经元,同时关闭一部分神经(输出为0)元来工作,他们的线性模型就不一样,总体来说就还是非线性的
我们也许还会提问,我们的反向传播会用到激活函数的导数,激活函数在0,0处并不可导,其实我们实际操作就是大于等于0导数都按1,小于0都是0,这样计算也快
relu的变种,我们知道relu函数当x小于0输出0,会导致有些w梯度变化无用,这时就有人想出来在relu负向做点手脚,就成了下面2个模型,定制一个,使负向不再是0
Maxout激活函数
什么是Maxout呢,我们将每层2个计算权重结果构成一个神经元(两两预先分好一组),将2组输出比较大小,取其大者,其实这跟后面我们知道的Maxpooling原理一样
我们看下图maxout的输出是根据神经元的权重输入我们取其max得到的结果,图中z1是wx+b,z2是x轴,取其最大者这里就是我们见过的relu(绿色折线)
如果我们w,b有其他值使z2不是x轴,如下图右下,就有了如图的绿色折线部分
所以说maxout是根据数据样本学习的激活函数,如果我们使用2个元素一组,可以学到类似relu或者绝对值的模型,如果3个元素一组,可以类似右下图的几种
下面我们就面临一个问题了,我们这个模型怎么训练,max不可导,还有反向传播怎么算?
我们假设图中红框内维度部分是较大值,那我们就成了一个线性模型,所以前向传播和反向传播的导数就可以求得了,当然不同的样本会导致每个神经元选择的元素不一样,构成不同的线性模型
Adaptive Learingrate自适应性学习率
我们训练集数据不好的时候,有时候也需要考虑采用自适应性学习率
我们之前学过adagrad调整学习率,比如图中w1横向使损失函数变化比较小,那我们就给与比较大维度学习率,w2就给与相对比较小的学习率
当然我们的损失函数模型复杂的可能是下图中的模型,不再是最开始学习率大就大,到一定位置又需要减小
于是我们就引入了RMSProp的梯度下降法,我们引入参数(这个参数可以调整),的初始值就是,然后将每次的和g带入权重,计算可得出新的用于更新参数,所以这还是梯度带有权重的均方根和,这个在0,1之间,我们调整它时,使我们的梯度是更偏向之前的梯度,还是新的梯度
解决局部最小点
我们看下图,我们都知道很难找到实际上的最小点,我们很容易停在了局部最小点,或者只是平滑点甚至是高点(只是微分足够小),老师课上说(据说可能有杜撰),我们的最小点就是山谷,他们往往就是比较多的参数同时达到一个相对较小值时候出现,如果我们采用复杂的神经网络,参数就不容易生成局部最小点。
我们都知道一个小球从高处落下,即使是到了最低点,根据惯性我们还是能往前走,就有可能跳出局部最低点,我们称之为动量Momentum
我们秒复习下之前学的梯度下降是怎么进行的,我们在初始点计算梯度,按照学习率步进一段距离,再计算新的梯度,继续步进,知道我们的损失函数趋近于0
我们怎么根据动量定义移动呢,假设我们初始在初始速度为0,当我们第一次计算梯度后,可以计算移动速度,他是跟上一个移动方向有关的,再开始移动,我们可以计算出梯度方向红色虚线,和原来的方向绿色虚线,将2个方向合成就得到新的方向
我们也可以另一种描述,速度v就是我们之前所有梯度的不同加权求和
我们看下图,如果我们的初始位置走,因为初始梯度是向右,所以向右走,中间点梯度和原速度都向右,继续向右,局部最小点梯度为0但原速度不为0,我们可以继续往前走,如果右侧山峰不高的话,我们甚至可能越过去继续寻找全局最小点
Adam其实就是RMSProp和Momentum的结合
我们当训练集已经训练得不错,但是测试集效果不太好的时候的第一种方法,early stoppIng
我们下图中随着训练集重复训练,训练集误差会减小,但是测试集的误差却可能增大,我们为了找到测试集上的最小点,把训练集又拆分成训练集和验证集
测试集效果差第二个方法是正则化,比如图中我们引入是w平方和的正则项,是L2正则。而且通常我们不会考虑偏置,我们使用正则通常是使损失函数更平滑,减少局部最低点,而偏置往往和平滑无关
我们分析L2正则,当我们引入后,对损失函数求导,可以比较出和原来的损失函数的区别是w的权重变向进行了减小,学习率和正则系数乘积一般比较小,可能回是0.01,0.001等等,结果相当于在原来的微分位置我们先将权重进行了缩小,权重的系数会越来越接近于0,但总体微分因为还有后一项,不会为0.因为权重在减小,我们称之为weight decay
我们也可以使用各权值的绝对值做L1正则,有人也许会说绝对值怎么求导呢,其实如果不考虑0处,我们可以采用符号函数sgn()作为导数结果,最终得到的式子比起无正则多了个固定的衰减项(当固定时确定),而且总是使w绝对值减小。
与L2相比,L2是按W成比例的衰减,当W比较大的时候衰减比较快,而L1是固定衰减,
L2正则是所有W权重都比较小,L1使局部权重减小(很接近于0),而其他权重往往比较大
类比正则,我们以人脑神经元为例,我们刚出生时候神经元比较小,6岁时神经元很多,到14岁神经元又开始减少,因为有些神经元不用,就会衰退,正则中W权重也是这样,不怎么更新就会变小
我们讲的测试集性能不好的第三个解决方法是Dropout,我们先讲是怎么做的,对于每个神经元,都有%p的概率给它拿掉,神经元被丢掉,与其相连的权重也失去了作用
我们丢掉部分神经元后,模型就变瘦了,我开门一般每次去一批次mini-batch训练得时候,我们更新一次随机dropout,我们使用dropout的时候,训练集的数据可能性能会变差点,但是往往测试集打的效果反而好些
我们dropout训练好模型了,测试集就不用dropout了,不过我们要对神经元的系数进行处理,比如我们的dropout rate是p%,那我们最后所有的权重都要乘以(100-p)%(图中小误),比如我们dropout率50%,我们的权重到最后都要乘以0.5
我们为什么将权重乘以系数呢,通俗理解就是,dropout的时候,我们的神经元会考虑我去掉的队友可能会不干活,我要好好干,但实际最终合在一起的时候,大家都会认真工作,所以要乘一点系数
我们举另一个例子来说明dropout,比如我们4个神经元,2个被dropout,但是我们测试时没有dropout我们的结果就接近之前的2倍,为了我们测试的性能一致,我们需要乘以系数
我们也把dropout叫做一种终极的ensemble,我们把训练集分成若干批次,每个批次训练一个模型,这些模型都有一定的复杂度,虽然可能都有些方差,但是经过他们的综合,往往就能得到一个比较好的模型
经过上一步训练得多个模型,将测试集数据输入,得到的输出取平均,我们就能得到一个比较好的结果。
类比下,决策树我们经常容易过拟合,但是很多棵决策树组成的随机森林就能有效的抑制过拟合。
我们为什么说dropout是终极的ensemble呢,我们假设有M个神经元,每个神经元选择不选择就有的模型组合,当然我们一般不会把所有组合都试一遍,但是我们在训练模型的时候,相同神经元的权重训练得是同一个东西,他们之间是共享的
我们看下图,当模型是线性的时候,dropout事实上就和直接不dropout每个权重乘以系数的模型一样,但这个前提是模型是线性的,通常我们的模型都不是线性的,所以二者最多是接近,但有时候我们有时候直接乘以系数的结果往往还是worked,比如我们的激活函数用relu,maxout他们相对sigmoid是比较接近线性的,所以比较worked