DeepLearning.ai学习笔记(二)改善深层神经网络:超参数调试、
一、训练/验证/测试集(Train/dev/test sets)一般来说为了充分利用已有数据以及让模型预测的更加一般化,通常将数据划分成训练/验证/测试集,划分比例一般为60%-20%-20%。 1.数据划分比例需要注意的问题在大数据时代,我们很容易有上百万甚至上千万的数据,这时假设我们使用训练集模拟出了若干个模型,现在需要比较不同模型的拟合效果,如果仍然将原数据的20%作为验证集,那么这将是一非常大的数据量,其实是没必要,因为一般来说只要选取一万或者几万(即1%-3%)的数据就可以了。 2.训练/测试集分布不匹配举个栗子来解释一下这个问题。加入我们要实现一个识别汽车的应用。我的在训练的时候采用的都是高清无码,拍的很好看的车子。可以到了测试集我们可能用一些手机拍的照片,这些照片相比起来可能比较模糊,暗淡,像素低。很显然,这两类数据分布不同。这种情况该怎么解决呢?Andrew大大的建议是让验证集数据与测试集数据同分布,既属于同一类数据。,用他的原话就是:
3.没有测试集肿么办?
二、偏差 & 方差
三、机器学习基础这一节主要介绍在训练模型时,遇到问题该如何解决的过程。如下图所示
四、正则化这一节内容讲的比较简单,主要介绍的是 (L2)正则化 。具体的可参考这篇博文来理解正则化。 下一节将会介绍为什么要使用正则化,以及直观理解正则化是如何预防过拟合的。 五、为什么要正则化1.直观理解(1)
我们首先做一个极端的假设,假设正则项系数 (λ) 非常大,那么为了满足(minJ(w,b))这个运算,则必须使得(w^{[l]}≈0) 但是这样会极大的简化神经网络的结构,简单地说可能就是从非常复杂的非线性结构转变成了线性结构,这时得到了最左边的模型,但显然也不行,这是欠拟合 所以需要取中间的值,让模型恰到好处,就如中间的模型一样。 2.直观理解(2)下面从另一个角度,即结合损失函数公式和激活函数曲线来理解。
又由正则化损失函数可以知道,当我们把(λ)的值设为很大的值时,权重(w)就会相应的减小 六、Dropout正则化1) Dropout("随机失活") 操作过程
2) 最常用实现方法--反向随机失活(Inverted Dropout)为方便说明我们假设需要计算的是3层神经网络,其中令
keepProb = 0.8 # d3元素值为True或False d3 = np.random.rand(a3.shape[0],a3.shape[1]) < keepProb # 在相乘运算时,python会自动将True转化为1,False转化为0 # 所以可以选出概率大于keepProb的节点继续留下来进行计算 a3 = np.multiply(a3,d3) a3 /= keepProb 四行代码,前面三行已经在注释中解释,下面着重解释一下第四行代码的作用(该行代码便是Inverted Dropout的关键步骤)。 我们假设网络的隐藏层,即(a^{[2]})有50个units,那么按照(keepProb=0.8)可以知道需要删除10个units,也就是说(a^{[2]})会减少20%,那么我们在计算下一层,即(z^{[3]}=w^{[3]}a^{[2]}+b^{[3]})时就会使得(z^{[3]})的期望值(均值)发生变化,为了不影响(z^{[3]})的期望值,我们需要用(w^{[3]}a^{[2]}div 0.8)来修正或弥补我们所需的20%。 3) 补充说明1.另外需要注意的是在测试阶段,我们不需要再使用dropout,而是像之前一样直接将各层的权重,偏差带入计算出预测值即可。 2.上面所提到的keepProb也可以是跟着各层节点数变化的,以下面的神经网络为例。 (W^{[1]} in R^{7×3},W^{[2]} in R^{7×7},W^{[3]} in R^{3×7},……) 七、理解Dropout下面给出好几种直观理解,看你喜欢那种咯~~ 1. 简化网络结构和正则化一样,通过dropout,神经网络结构会被简化,从而达到预防过拟合的效果。 2. 权重扩散以紫色节点为例,它有很多输入节点,但是每个节点都有可能被删除,所以它不能完全依靠某一个节点,就像古话说的,不能将所有鸡蛋放在同一个篮子里(我的天。。。顿时升华了有木有!2333)。 既然不能完全依靠某一个节点,那么就需要将权重传播开来,即每个输入节点的权重都增加那么一丢丢,这样就会产生 收缩权重的平方范数(shrinking the squared norm of the weights) 的效果,这与(L2正则化)有一样的效果,都能压缩权重。 3. 1神带9坑
回归到最重要的问题:为什么dropout效果这么好。Hinton大神的解释是dropout减少了节点之间的共适应。共适应这个词说起来好专业,我举个例子来说一下我的理解: 假设一个网络中有10个节点,有一个perfect节点,它的取值刚刚好,另外9个节点的取值还需要调整,也就是所谓的一神带9坑!这个时候网络的输出层往回传递误差,这10个节点都不知道自己现在的取值是不是合适的啊,毕竟咱们开了上帝视角,而它们没有。所以它们就根据传回来的误差更新自己的取值,虽然其他9个节点可能有更合适的取值,但是这个perfect的值就破坏了啊。而且,在更新取值的时候,其他9个坑逼节点心想“这个误差是咱们10个共同造成的,嗯,我只要把我那份误差更新掉就行”,而实际上最终的误差是9个节点造成的,也就是说这些个坑逼节点对自己的错误认识还不够充分!不行,不能这么宠着它们!一个很简单的想法,就是让perfect不工作,得了,您歇着吧!这个时候9个节点就可以更好的更新自己权值,直到出现下一个perfect节点。 但是,问题是咱们也不知道哪个节点是perfect节点啊,咱们训练的时候别说上帝视角了,有时候就连哪些个节点是dead node都看不穿啊。那怎么办呢?就让部分节点先不工作吧,先富带后富。假设不工作的节点全是坑壁节点,那对于perfect节点就是好事啊,毕竟最后的误差就小了。如果不工作的节点恰好有perfect节点,那对于那些个正在工作的菜鸡节点就是好事,让他们能正确认识到自己的错误!这样网络就能训练得更好了。 4. 知乎
八、其他正则化方法1.Data augmentation数据扩增简单地说就是在无法增加额外训练数据的情况下,可以对已有数据进行翻转、放大,扭曲等处理得到新的数据来扩充原数据集,从而达到正则化的目的。如图示 2. early stopping首先假设我们训练集的训练误差随着迭代次数递减,曲线如图蓝色曲线所示。这看起来貌似不错,所以接下来我们看看验证集的效果。 验证集误差在刚开始是递减的,但是在箭头所指处发生转向(开始增加),所以我们发现错误就要及时纠正,那我们训练到这就及时停下来吧~~ 但是这样是有明显的缺点的,因为我们在实现神经网络的时候一般是按照如下两个方面步骤进行的:
虽然early stopping让我们及时的避免了过拟合(减少方差),但是我们也停止了误差的下降(减小偏差)。这种一个时间解决一个问题的思路称为正交化(Orthogonalization)。 前面提到的 (L2)正则化 正则化虽然可以同时优化方差和偏差,但是他需要花费较大精力去找到合适的参数λ,但是吴大大说他自己更加倾向于用 (L2)正则化 这个方法。 九、正则化输入
十、梯度消失与梯度爆炸假如有如下图示的深度神经网络:
假设(W_{linear})都等于这个:,那么则有(y_{hat}=1.5^{L-1}W_LX),很显然当(L)很大时则会出现梯度爆炸。 同理若将权重的值设置为小于1,那么则会出现梯度消失。 十一、神经网络的权重初始化这篇文章主要就是介绍了权重如何初始化,但是并没有给出推导过程,而是直接给了结论。所以想更加了解如何初始化权重可以看一下我翻译的这篇文章神经网络权重初始化问题,其中很详细的介绍了权重初始化问题。 十二、梯度的数值逼近梯度其实就是微分求导,但是由于求导结果可能比较复杂,所以使用微积分中的求导的定义来计算梯度。 即假设损失函数(J(θ)=θ^3),那么梯度(frac{partial J(θ)}{partial θ}_{|θ=1}=3),那如果用求到的定义是怎么计算的呢?如下: [frac{partial J(θ)}{partial θ}_{|θ=1} = frac{J(θ+ε)-J(θ+ε)}{2ε}] 很显然ε越小,就越会逼近真实的梯度值。
十三、梯度检验上面说到了如何实现梯度的数值逼近,之所以这样做是为了判断我们的反向传播算法是否错误,这可以为我们的代码调试提供依据。但是怎么判断梯度计算正确呢?
十四、关于梯度检验实现的建议
|