Course 2-Improving Deep Neural Networks--Week 1
本周涉及数据集划分、偏差-方差、正则化、dropout、归一化输入、梯度消失与爆炸、权重初始化、梯度检验等内容。
1.1 train / dev / test 训练集、验证集、测试集
训练集 training set:是用来训练模型的
验证集 development set \ dev set:是用来选出哪个模型在dev set上表现最好
测试集 test set:用来对验证选出的模型进行无偏估计
对于小数据量的机器学习(10k左右样本量),常用且有效的分法为:训练集、测试集70%-30%划分,训练集、验证集、测试集60%-20%-20%划分。
对于大数据量的机器学习(百万以上样本量),验证集和测试集的比例就会小很多,如训练集、验证集、测试集98%-2%-2%划分,当数据量更大时为99.5%-0.25%-0.25%、99.5%-0.4%-0.1%
由于深度学习需要的数据量很大,数据的来源也很广泛,因此,很多数据源自不同的分布,但有一条经验法则是:必须保证验证集数据和测试集数据的分布相同。
另外,当不需要无偏估计时,我们可以不要测试集,此时只有训练集和验证集。
1.2 bias / variance 偏差、方差
在深度学习误差中,有关bias-variance trade-off 的讨论越来越少,总是分别考虑bias和variance。具体如下:
high bias –> underfitting
high variance –> overfitting
当样本只有两维特征时,我们尚能通过画出决策面来判断偏差和方差,但当样本维数很高时,要判断模型的bias和variance就要借助其他指标了。理解bias和variance的两个关键数据是train set error与dev set error,通过查看这两个数据来判断算法的偏差和方差情况。以下表数据为例,假设最优误差(贝叶斯误差)很小(接近为0)并且训练集和验证集来自同一分布。表中给出了四种情况下的训练集误差和验证集误差,以及它们的偏差和方差情况。我们首先通过查看train set error与最优误差之间的差异来判断算法的bias,如果train set error与最优误差差异很小,则算法为low bias;如果train set error与最优误差差异差异较大,则算法为high bias。然后再通过比较train set error与dev set error的差异来判断算法的variance,如果dev set error与train set error差异很小,则算法为low variance;如果dev set error与train set error差异较大,则算法为high variance。
train set error | dev set error | 结论 |
---|---|---|
1% | 11% | high variance |
15% | 16% | high bias |
15% | 30% | high bias, high variance |
0.5% | 1% | low bias, low variance |
按照之前的理解,高偏差意味着模型的复杂度不够、数据拟合度低,高方差意味着模型的复杂度过高、数据过拟合。那么,针对上表中第三种情况,一个模型同时具有高偏差和高方差意味着什么呢?想象一下在样本空间中,模型对样本空间中的部分数据拟合程度过低,但又对空间中的其他部分数据拟合程度过高,这样,该模型就同时具有高偏差和高方差。
1.3 basic “recipe” for machine learning 机器学习基础
Andrew Ng 在训练神经网络时会用到的基本方法:初始模型训练完成后,首先通过查看train set error来判断算法的bias高不高,如果算法是high bias,那么尝试有更多hidden layers或hidden units 的更大的网络(通常有用)、花更多的时间来训练网络(不一定有用)、尝试新的神经网络架构(不一定有用),直至偏差降低至可接受的数值。然后,通过查看dev set error来判断算法的variance有没有问题,如果算法是high variance,最好的方法就是采用更多的数据,当无法获得更多数据的时候,可以使用regularization,或者可以尝试其他的神经网络架构。这样不断尝试,直到找到一个low bias、low variance的算法。
1.4 regularization 正则化
当你怀疑模型存在overfitting,那么最应该尝试的方法可能是正则化。另一个解决高方差的方法是准备更多的数据,这也是非常可靠的办法,不过因为种种原因,我们无法获得更多的数据。但是,regularization常有助于防止过拟合。正则化,即在代价函数中加入了正则化项,常见的有
如果使用
如何在神经网络中实现
其中,
展开可写为:
此时,
因此,
最后说明一下,在计算正则项时,一般都忽略偏置b的正则项,因为它只是众多参数中的一个,影响很小,当然也可以计算,只是对结果的影响可忽略。
1.5 why regularization reduce overfitting
解释一:
对于包括有正则化项的代价函数
我们的目的是让代价函数
解释二:
假设**函数
one implementational tip:
当给代价函数加上正则化项后,画出的代价函数曲线就是随着迭代次数的增加单调递减的。如果画出的代价函数没有正则项,只有第一项,那么画出的代价函数可能不是在所有范围内都单调递减。
1.6 Dropout regularization
除了
如何实现dropout呢?
目前最常用的时inverted dropout(反向随机失活)。以神经网络中的第3层来说明如何在某一层神经网络中实现dropout。首先,定义向量
若
在做上式计算时,python会把true和false翻译为1和0,过滤掉要消除的神经元。最后,还要对
上式被称为inverted dropout technique。为什么要进行上式的操作呢?假设第3层上有50个神经元,因此
而在测试阶段,我们不需要显式地使用dropout。即,我们只在训练阶段使用dropout。
1.7 understanding dropout
由于dropout会随机消除网络中的一些节点,这样每次迭代时,网络都看起来更小了,而这一效果就和使用了正则化的效果一样。
另外,从单一神经元来看,当使用dropout时,该单元的输入被随机消除,也就是说,该神经元不依赖于任何输入,因为任何输入都有可能被随机消除。这样,与每个输入相关联的权重都比较小,即达到了收缩权重平方范数的效果,与
从技术上讲,我们也可以对输入层使用dropout,这样可以移除一些特征,但通常并不这么做,将keep-prob设置为1是最常用的值,或者设为一个较大的值,如0.9,但是消除一半的特征时不太可能的。
本节课总结:如果担心某些层比较容易发生过拟合,那么就将这一层的keep-prob设置的比较低,这样做的缺点就是,在交叉验证时,超参数的搜索范围比较大,要搜索更多的超参数。另一种可选方法是,在有些层上使用dropout,在有些层上不使用,使用dropout的层只有一个超参数,那就是keep-prob。
dropout在计算机视觉中使用的很多,几乎成了默认的选择。dropout是一种正则化方法,它有助于防止过拟合,因此,除非算法过拟合,不然Ng是不会使用dropout的,所以dropout在其他领域应用很少,主要存在于计算机视觉领域,因为我们没有足够的数据。
dropout的一大缺点就是代价函数
1.8 Other regularization methods
- data augmentation 数据扩增
常见于计算机视觉,对图像进行截取、水平翻转、形变等变换操作。 - early stopping
在训练模型时,我们希望模型的训练集误差(train set error),即代价函数J 不断下降,同时,我们还可以得到模型的验证集误差(dev set error)。通常,验证集误差会先下降,然后上升。early stopping的作用就是找到验证集误差最小时所对应的参数W ,认为这时的W 是模型的最佳参数。
但early stopping还有一个缺点,就是无法独立地处理代价函数优化和过拟合问题。因为提前停止梯度下降,也就是停止了优化代价函数J (这一点理解的不是太透)。
1.9 normalizing input
归一化输入是能够加速训练网络的一种技巧,需要两步:
(1) 0-均值化
这样,将数据集移动到均值为0的地方。
(2) 归一化方差
这样,数据集就成了0均值、方差为1的分布。
tips:标准化验证集和测试集的
为什么要归一化输入数据呢?,如下图所示,如果输入X在不同的维度上取值范围不一样,比如
1.10 vanishing/exploding gradients
当深度神经网络很深的时候(即
1.11 weight initialization for deep networks
1.10说明了什么是梯度消失和梯度爆炸。有一个能部分解决梯度消失/爆炸的方法就是谨慎选择神经网络的随机初始化参数。
首先考虑对一个单一的神经元:
当
若是relu**函数:
若是tanh**函数(Xavier初始化):
或者:
如果想添加其他的方差,那么这个方差将作为需要调节的另一个超参数。这样就可训练出一个权重或梯度不会过快增长或消失的神经网络。这也是一个加快训练的技巧。
1.12 numerical approximation of gradients
在实施backprop时,有一个测试叫梯度检验,它可以确保backprop的实现是正确的。为了实现梯度检验,首先要了解梯度的数值检验。即,双边差分的精度比单边差分的精度高。所以,在梯度检验时,我们使用双边差分。
1.13 gradient checking
- 神经网络的梯度检验:
- 将参数
W1 ,b1 ,W2 ,b2 …WL ,bL reshape成一个大的向量θ ,这样,代价函数J(W,b) 就变成了J(θ) 。同样的将dW1 ,db1 ,dW2 ,db2 …dWL ,dbL 以相同的方式reshape成一个大的向量dθ 。 - 实施梯度检验:
- for each
i : -
dθapprox[i]=J(θ1,θ2,...,θi+ε,...)−J(θ1,θ2,...,θi−ε,...)2ϵ≈dθi - 最后判断
dθapprox 与dθ 是否相近。即,计算下式 -
||dθapprox−dθ||2||dθapprox||2+||dθ||2 - 如果
ε=10−7 : - 当上式比值约为
10−7 或更小,那么这个结果就很好 - 当上式比值在
10−5 以内,这时候就要仔细检查一下 - 当上式比值在
10−3 以内,就会担心有bug。
1.14 gradient checking implementation notes
- 不要再训练时使用梯度检验,它只用于调试
- 如果算法梯度检验失败,要检查所有的成分来确定bug,即,找出是哪一个
dθapprox[i] 与dθ[i] 相差太大 - 如果使用了正则化,不要忘记正则项
- 梯度检验不能与dropout同时使用。因为在每次迭代时,dropout会随机让隐藏层的神经元消失,这样就难以计算dropout在梯度下降时的代价函数。所以,通常在梯度检验时不进行dropout,即设置keep-prob=1。在确保算法没问题的时候再打开dropout。
- 在随机初始化的过程中,运行梯度检验,然后训练一会儿后,再运行梯度检验。