深层神经网络参数调优(二)
——dropout、题都消失与梯度检验
(原创内容,转载请注明来源,谢谢)
一、dropout正则化
中文是随机失活正则化,这个是一种正则化的方式,之前学过L1、L2正则化,这个则是另一种思想的正则化。dropout,主要是通过随机减少一些神经元,来实现减少w和b,实现防止过拟合的。
1、主要做法
假设一个概率阈值p,对于神经网络中的所有神经元,在每一次FP、BP的时候,都有p的概率会被保留下来。没有被保留下来的神经元,则不参与本次的运算,即不接收输入,也不输出结果。
2、具体做法
假设在神经网络的第三层,最终输出的矩阵是a,概率阈值p=0.8,则这一层的所有神经元都有0.8的概率会被留下。下面的代码是基于python的numpy。
2)将a和d相乘(这里python会自动将true转成1,false转成),以把被去掉的神经元的输出去除:a = np.multiply(a, d),这个multiply即矩阵对应元素相乘。
3)由于a的一部分神经元的输出被删除,考虑到保留下来的是80%,即可以理解成输出的值是原来计算值的80%。而这一层的输出的a,是作为下一层的输入,考虑到下一层的z=wa+b,为了不减少下一层的值,故需要把a除以概率阈值,保证整个输出的数值上,还是大小不变的:a = a / p
3、随机失活有效的原因
由于每次计算都随机去除了一些神经元,故整个神经网络的计算过程中,不会特别依赖于哪个特征值,这就保证了每个神经元的权重都不会太大,即可以产生收缩权重平方范数的效果。
4、其他事项
1)随机失活不能用在测试阶段,否则结果不稳定,不好确认模型是否正确。
2)概率阈值p的设置,每一层可以设的不一样,p越小保留的越少。当某一层的输入和输出的神经元太多,则过拟合的可能性大,此时可以把p设置的小一些。即随机失活完全是为了防止过拟合服务的,不能滥用。
3)随机失活由于可以设置每一层的阈值,故具有灵活性,可以控制每一层的过拟合情况。
4)应用
最常用在计算机视觉,由于输入的图片可能是模糊的,信息量不足,故经常用此方法,保证不依赖于某个像素。
5)缺点
代价函数没法明确的定义,因为每次的计算都不一样,也就无法画出迭代次数—代价函数的图。解决方案是,可以先设定p=1,即保留所有神经元,关闭随机失活,此时画出代价函数和迭代次数的图,确保是下降趋势的,再进一步考虑加上随机失活。
二、其他正则化方式
1、数据扩增(dataaugmentation)
这个主要是增加训练数据的方式,可以理解为人造数据,如将图片反转、缩放、扭曲等,这样可以得到更多的类似的图片参与训练,也可以有效的防止过拟合,起到正则化的效果。
2、early stopping
梯度下降都是为了获取到训练集代价函数最小值情况下的w和b,而early stopping则是不优化到最小,中途就把结果输出。
这么做的原理,是考虑到训练集和验证集的代价函数,随着迭代次数的走向不一样。一开始二者都会随着迭代而降低,当超过某次迭代,会逐渐出现过拟合,此时验证集的代价函数反而会升高。early stopping的做法,就是在验证集代价函数重新升高之前,停止迭代,返回此时的w和b。
这么做的缺点在于,没法将优化过拟合和优化欠拟合的情况分开,因为要监控着什么时候出现这个临界值。
这么做相对应L2正则化,好处在于,只需要一轮的这样的调试,就可以确定不同w情况下的代价函数,进而取得最好的w和b。而L2正则化的参数λ,并不好确定,需要经过多轮的调试,比较耗时。
三、归一化参数
1、概念
归一化参数,即当不同特征值的数值,在数量级上差距很大时可以进行归一化,这样数据更加均衡,梯度下降做起来更快。
2、做法
1)计算均值μ=所有样本该特征值和/m,再令所有样本该特征值x=x-μ(称为均值归零化)
2)计算所有样本的方差,由于均值已经归零,故方差即每个特征值自生值的平方。接着把x=x/方差,得到一个轴对称的分布图。
需要注意的是,对训练集归一化后,对测试集也要归一化。
3、归一化的理由
归一化可以加快梯度下降。考虑到参数如果分布很不均匀,画出的图像会是一个窄而长的图像,这样梯度下降比较慢;当归一化后,会类似圆形,此时归一化较快。下图左边是未归一化,右边是归一化的图。
四、梯度消失与梯度爆炸
1、概念
梯度消失,即计算梯度下降过程中,出现导数的值太小,接近;梯度爆炸则是出现导数特别大的情况。
2、产生原因
由于深度学习,神经网络的层次有可能非常多,假设总层次是150层,即L=150。不考虑b,并假设g(z)=z,即线性激活函数。
此时输出的y=w1*w2…*wn*x。可以看到,此时如果初始化的w如果大于1,假设是1.5,则此时y的值是1.5150*x,这个数会非常大,出现梯度爆炸;反之如果w是0.5,则150次幂后悔非常小,接近,出现梯度消失。
3、解决方案
并没有很好的解决方案,只有相对比较好的缓和方案。
由于梯度爆炸和梯度消失都是由于初始化的值不太好引起的,故这里要对初始化的值下功夫,即令初始化后的w,方差是某个值δ。
经过专门的人的研究,如果激活函数是ReLU,则δ=根号(2/n),这里的n是本层的输入的数量;而如果激活函数是tanh,则δ=根号(1/n),或根号(2/(本层n+上层n))。
五、梯度检验
1、概述
神经网络太过于复杂,故需要一种方式来验证,神经网络是否正确,梯度检验就是为了做这个。
2、梯度数值逼近
为了梯度检验,首先讨论梯度数值逼近,这个实际上就是求导的方式。可以看到计算一个函数的导数,可以用下面的方式来计算。即,计算某个值的导数,可以计算这个值加减一个非常小的数,带入函数得到两个函数的值,相减后除以两倍这个很小的数,即得到导数。
其中用这个数加减得到的,称为双边误差;而仅作加法(则不除以2),得到的是单边误差。经过验证,双边误差的误差值的数量级,要小于单边误差,故后面计算梯度检验,也是用双边误差进行计算的。
3、梯度检验
梯度检验的做法,其实就是使用上面的方法计算每一层的代价函数的导数,与用反向传播算法计算出来的值,进行比较,比较的方式如下图的check。
判断比较结果是否正常,是拿结果与梯度数值逼近法计算导数时用到的微小变量进行比较,如果是一个数量级,则正常;如果差距好几个数量级,则说明存在问题。
4、注意事项
1)梯度检验只用于调试,因为其计算速度很慢,不能真正用于训练。
2)梯度检验失败,则需要查看是哪些层出问题,进行调试。
3)如果有正则化项,则在使用梯度数值逼近法计算导数时,也要把正则化项考虑进去。
4)梯度检验与dropout不能一起用。
5)梯度检验对于比较小的w和b比较敏感,因此可以随机初始化后先计算一次,后面最终计算得到结果后再计算一次。
六、总结
本文讲到的是一些实用的内容,有些我没用过也不太清楚,这里相当于是埋下个种子,在后面实际用到的时候,会有更深刻的体会。
——written by linhxx 2018.02.05
领取专属 10元无门槛券
私享最新 技术干货